Using Alchemize¶
Alchemize relies on a explicit mapping structure that is defined on your model class. The mapping combined with the appropriate class mix-in will enable your object to serialize and deserialize to a supported format by Alchemize.
Simple Example¶
In the following example, we’ll be taking a portion of the sample response from the GitHub’s API to retrieve data on a single user.
Input JSON
{
"login": "octocat",
"id": 1,
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"type": "User",
"site_admin": false,
"name": "monalisa octocat",
"company": "GitHub",
"blog": "https://github.com/blog",
"location": "San Francisco",
"email": "octocat@github.com",
"hireable": false,
"bio": "There once was...",
"public_repos": 2,
"public_gists": 1,
"followers": 20,
"following": 0,
"created_at": "2008-01-14T04:33:35Z",
"updated_at": "2008-01-14T04:33:35Z"
}
Example Mapping
from alchemize import JsonMappedModel, Attr
class ExampleClass(JsonMappedModel):
__mapping__ = {
'id': Attr('user_id', int),
'login': Attr('login', str),
"email": Attr('email', str),
"name": Attr('name' , str)
}
...
Now that we have some sample JSON and a mapping on a class, we can put this information through the JsonTransmuter to get two-way conversion of our data.
Example Transmutation
from alchemize import JsonTransmuter
# From JSON to our Python Mapped Model
result_model = JsonTransmuter.transmute_from(json_str, ExampleClass)
# From our Python Mapped Model back to JSON
result_json = JsonTransmuter.transmute_to(result_model)
If you look at the resulting model and JSON string, you might notice that the only information that is carried over is what has been explicitly mapped.
Nested Mapped Models¶
Alchemize supports the ability to de/serialize child mapped models as well. This allows for you to explicitly map your data into nested Python objects and let Alchemize handle the serialization and deserialization of the entire data structure at once.
Example:
We want to convert the following JSON into appropriate Python objects.
{
"id": 12345,
"users": [
{
"name": "Foster Person",
"email": "foster.person@example.com"
},
{
"name": "Other Person",
"email": "other.person@example.com"
}
]
}
from alchemize import JsonMappedModel, Attr
class User(JsonMappedModel):
__mapping__ = {
'name': Attr('name', str),
'email': Attr('email', str)
}
class Project(JsonMappedModel):
__mapping__ = {
'id': Attr('project_id', int),
'users': Attr('users', [User])
}
We can now deserialize the data into our models using the JsonTransmuter
from alchemize import JsonTransmuter
result_model = JsonTransmuter.transmute_from(json_str, Project)
result_model.users[0].name # 'Foster Person'
result_model.users[1].name # 'Other Person'
We have successfully converted our JSON structure into a easily usable Python object structure.
For more information on how to define your mappings, take a look at the Alchemize API Documentation
Excluding Attributes for Serialization¶
For specific data models there are instances where you don’t want to serialize
certain attributes. For example, you’re pulling user information from a database
but you don’t want to serialize the password hash or some other internal value.
This is done by setting the serialize=False
argument on your Attr
.
from alchemize import JsonMappedModel, Attr
class User(JsonMappedModel):
__mapping__ = {
'name': Attr('name', str),
'email': Attr('email', str),
'password': Attr('password', str, serialize=False),
}
Note
The serialize
setting can be overridden by the transmuter if
explicited set during the transmute_to(...)
call.
Wrapped Objects¶
Some API responses can wrap the information you’re interested in inside a
container object. There are many reasons for this, but often from a model
interface perspective, you just want to represent the data itself and not
the container. To handle this use-case, Alchemize provides the
__wrapped_attr_name__
option.
This option allows for parsing this JSON into the following single model
{
"#item": {
"name": "John Doe",
"email": "rando@doe.com",
}
}
from alchemize import JsonMappedModel, Attr
class User(JsonMappedModel):
__wrapped_attr_name__ = '#item'
__mapping__ = {
'name': Attr('name', str),
'email': Attr('email', str),
}
Simple Helper Usage¶
If you don’t really care about a custom serialization implementation or hook-in you can use the basic helper models which handle will transmute to/from on their own.
from alchemize import JsonModel, Attr
class User(JsonModel):
__mapping__ = {
'name': Attr('name', str),
'email': Attr('email', str),
'password': Attr('password', str, serialize=False),
}
model = User.from_dict({
'name': 'thing',
'email': 'thing@thing.corp',
'password': 'my-password',
})
json_dict = model.as_dict()
# You can also set attributes on instance creation
model = User(name='thing', email='thing@thing.corp')