Converters
The converter
parameter of the uplink.Consumer
constructor accepts a custom adapter class that handles serialization of HTTP request properties and deserialization of HTTP response objects:
Starting with version v0.5, some out-of-the-box converters are included automatically and don't need to be explicitly provided through the converter
parameter. These implementations are detailed below.
Marshmallow
Uplink comes with optional support for marshmallow
.
uplink.converters.MarshmallowConverter
Bases: Factory
A converter that serializes and deserializes values using
marshmallow
schemas.
To deserialize JSON responses into Python objects with this
converter, define a marshmallow.Schema
subclass and set
it as the return annotation of a consumer method:
Note
This converter is an optional feature and requires the
marshmallow
package. For example, here's how to
install this feature using pip:
Source code in uplink/converters/marshmallow_.py
Note
Starting with version v0.5, this converter factory is automatically included if you have marshmallow
installed, so you don't need to provide it when constructing your consumer instances.
Pydantic
New in version v0.9.2
Uplink comes with optional support for pydantic
.
uplink.converters.PydanticConverter
Bases: Factory
A converter that serializes and deserializes values using
pydantic.v1
and pydantic
models.
To deserialize JSON responses into Python objects with this
converter, define a pydantic.v1.BaseModel
or pydantic.BaseModel
subclass and set
it as the return annotation of a consumer method:
@returns.json()
@get("/users")
def get_users(self, username) -> List[UserModel]:
'''Fetch multiple users'''
Note
This converter is an optional feature and requires the
pydantic
package. For example, here's how to
install this feature using pip:
Validates if :py:mod:pydantic
is installed
Source code in uplink/converters/pydantic_.py
Note
Starting with version v0.9.2, this converter factory is automatically included if you have pydantic
installed, so you don't need to provide it when constructing your consumer instances.
Converting Collections
New in version v0.5.0
Uplink can convert collections of a type, such as deserializing a response body into a list of users. If you have typing
installed (the module is part of the standard library starting Python 3.5), you can use type hints (see PEP 484) to specify such conversions. You can also leverage this feature without typing
by using one of the proxy types defined in uplink.types
.
The following converter factory implements this feature and is automatically included, so you don't need to provide it when constructing your consumer instance:
uplink.converters.TypingConverter
Bases: Factory
Added in v0.5.0
An adapter that serializes and deserializes collection types from
the typing
module, such as typing.List
.
Inner types of a collection are recursively resolved, using other
available converters if necessary. For instance, when resolving the
type hint typing.Sequence[UserSchema]
, where
UserSchema
is a custom marshmallow.Schema
subclass, the converter will resolve the inner type using
uplink.converters.MarshmallowConverter
.
Note:
The typing
module is available in the standard library
starting from Python 3.5. For earlier versions of Python, there
is a port of the module available on PyPI.
However, you can utilize this converter without the
typing
module by using one of the proxies defined by
uplink.returns
(e.g., uplink.types.List
).
Here are the collection types defined in uplink.types
. You can use these or the corresponding type hints from typing
to leverage this feature:
uplink.types.List
module-attribute
A proxy for typing.List
that is safe to use in type
hints with Python 3.4 and below.
uplink.types.Dict
module-attribute
A proxy for typing.Dict
that is safe to use in type
hints with Python 3.4 and below.
Writing Custom JSON Converters
As a shorthand, you can define custom JSON converters using the @loads.from_json
(deserialization) and @dumps.to_json
(serialization) decorators.
These classes can be used as decorators to create converters of a class and its subclasses:
# Creates a converter that can deserialize the given `json` in to an
# instance of a `Model` subtype.
@loads.from_json(Model)
def load_model_from_json(model_type, json):
...
Note
Unlike consumer methods, these functions should be defined outside of a class scope.
To use the converter, provide the generated converter object when instantiating a uplink.Consumer
subclass, through the converter
constructor parameter:
Alternatively, you can add the @install
decorator to register the converter function as a default converter, meaning the converter will be included automatically with any consumer instance and doesn't need to be explicitly provided through the converter
parameter:
from uplink import install, loads
# Register the function as a default loader for the given model class.
@install
@loads.from_json(Model)
def load_model_from_json(model_type, json):
...
uplink.loads
Bases: _ModelConverterBuilder
Builds a custom object deserializer.
This class takes a single argument, the base model class, and registers the decorated function as a deserializer for that base class and all subclasses.
Further, the decorated function should accept two positional arguments: (1) the encountered type (which can be the given base class or a subclass), and (2) the response data.
Added in version 0.5.0
PARAMETER | DESCRIPTION |
---|---|
base_class
|
The base model class.
TYPE:
|
Source code in uplink/models.py
from_json
classmethod
Builds a custom JSON deserialization strategy.
This decorator accepts the same arguments and behaves like
uplink.loads
, except that the second argument of the
decorated function is a JSON object:
Notably, only consumer methods that have the expected return
type (i.e., the given base class or any subclass) and are
decorated with uplink.returns.from_json
can leverage
the registered strategy to deserialize JSON responses.
For example, the following consumer method would leverage the
from_json
strategy defined above:
Added in version 0.5.0
Source code in uplink/models.py
uplink.dumps
Bases: _ModelConverterBuilder
Builds a custom object serializer.
This decorator takes a single argument, the base model class, and registers the decorated function as a serializer for that base class and all subclasses.
Further, the decorated function should accept two positional arguments: (1) the encountered type (which can be the given base class or a subclass), and (2) the encountered instance.
Added in version 0.5.0
PARAMETER | DESCRIPTION |
---|---|
base_class
|
The base model class.
TYPE:
|
Source code in uplink/models.py
using
to_json
classmethod
Builds a custom JSON serialization strategy.
This decorator accepts the same arguments and behaves like
uplink.dumps
. The only distinction is that the
decorated function should be JSON serializable.
Notably, only consumer methods that are decorated with
uplink.json
and have one or more argument annotations
with the expected type (i.e., the given base class or a subclass)
can leverage the registered strategy.
For example, the following consumer method would leverage the
to_json
strategy defined above, given
User
is a subclass of ModelBase
:
Added in version 0.5.0