Skip to content

Automatic (de)serialization of arguments and return values for Python functions

License

Notifications You must be signed in to change notification settings

alexmojaki/datafunctions

Repository files navigation

datafunctions

Build Status Coverage Status Supports Python versions 3.7+

Automatic (de)serialization of arguments and return values for Python functions.

pip install datafunctions

@datafunction is a decorator which automatically deserializes incoming arguments of the decorated function and serializes the return value. For example:

from datetime import datetime
from datafunctions import datafunction

@datafunction
def next_year(dt: datetime) -> datetime:
    return dt.replace(year=dt.year + 1)

assert next_year("2019-01-02T00:00:00") == "2020-01-02T00:00:00"

@datafunction automatically converts the string argument to a datetime object, and then converts the returned datetime back to a string.

This is useful for calling functions over a remote connection or from a different language - see instant_api and instant_client for example.

More generally, the arguments and return value as seen from the outside the function are basic JSON serializable objects - strings, dicts, etc. They are converted to and from the correct types (as indicated by type annotations) by marshmallow. Common Python types as well as dataclasses (which may be nested) are supported. For example:

from dataclasses import dataclass
from datafunctions import datafunction

@dataclass
class Point:
    x: int
    y: int

@datafunction
def translate(p: Point, dx: int, dy: int) -> Point:
    return Point(p.x + dx, p.y + dy)

assert translate({"x": 1, "y": 2}, 3, 4) == {"x": 4, "y": 6}

To decorate a method, pass is_method=True, e.g:

class MyClass:
    @datafunction(is_method=True)
    def method(self, x: int) -> int:
        ...

All parameters and the return value must have a type annotation, except for the first argument when is_method=True. Variadic parameters (e.g. *args or **kwargs) and positional-only parameters (before /) are not allowed.

If there is an exception deserializing or binding the arguments an ArgumentError will be raised with the underlying exception attached to __cause__. Similarly a ReturnError may be raised when trying to serialize the return value.

For more manual control, use the methods:

  • load_arguments
  • dump_arguments
  • load_result
  • dump_result

Under the hood, the type annotations are gathered into a dataclass which is then converted into a marshmallow schema using marshmallow_dataclass. marshmallow handles the (de)serialization.

Instances of this class have attributes params_schemas and return_schemas, each of which have the following attributes:

  • dataclass
  • schema_class: the marshmallow schema class
  • schema_instance: a no-args instance of schema_class

About

Automatic (de)serialization of arguments and return values for Python functions

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published