Giter Club home page Giter Club logo

python-adapters's Introduction

Adapters

Build Status

Adapters allow converting data from one structure to another.

The adapters work very similar to Serializers in Django REST framework. They are not tied with Django nor DRF in any way, instead they provide a generic way of transforming an object to another.

The are intended to be used when working with 3rd party APIs and as View-Models.

Example

Suppose you're dealing with an API that returns a profile in the following format:

{
    "first_name": "Alexandra",
    "last_name": "Johnson",
    "dob": "2/27/1985",
    "address_street": ["71 Boat Lane"],
    "address_zip": "EH45 0ZQ",
    "address_city": "Alderton",
    "address_country": "GB"
}

But your local models are a little different:

class Address(object):
    def __init__(self, **kwargs):
        self.line1 = kwargs.get('line1', None)
        self.line2 = kwargs.get('line2', None)
        self.postal_code = kwargs.get('postal_code', None)
        self.city = kwargs.get('city', None)
        self.region = kwargs.get('region', None)
        self.country = kwargs.get('country', None)


class Profile(object):
    def __init__(self, **kwargs):
        self.first_name = kwargs.get('first_name', None)
        self.last_name = kwargs.get('last_name', None)
        self.birthday = kwargs.get('birthday', None)
        self.address = kwargs.get('address', None)

How do you create local instances from the result returned by the API? Enter adapters:

import adapters


class AddressAdapter(adapters.Adapter):
    class Meta(object):
        model = Address

    line1 = adapters.CharField(source='address_street.0')
    line2 = adapters.CharField(source='address_street.1', default='')
    postal_code = adapters.CharField(source='address_zip')
    city = adapters.CharField(source='address_city')
    region = adapters.CharField(source='address_region', default='')
    country = adapters.CharField(source='address_country')


class ProfileAdapter(adapters.Adapter):
    class Meta(object):
        model = Profile

    first_name = adapters.CharField()
    first_name = adapters.CharField()
    birthday = adapters.DateField(source='dob')
    address = AddressAdapter(source='*')


ProfileAdapter().adapt(remote_data)

Declaring adapters

Declaring an adapter is as simple as inheriting from adapters.Adapter.

The data argument can be omitted and passed to the .adapt() method. See Adapting data below.

The instance argument is optional and it allows converting to an existing instance i.e. instead of creating a new one.

Meta options

The Meta.model field specifies the type of the end result. Defaults to dict and as such the data is converted to a dictionary.

Adapting data

To convert data from one format to another, call the Adapter.adapt() method. It accepts an optional data argument which refers to the data to be converted.

Fields

Each field accepts the following arguments:

  • source refers to the attribute that will be used to populate the field; the default is to use the same name as the field;

The source argument can use dotted notation to traverse objects e.g. profile.birthday.

The value * can be used to indicate the adapter to pass the entire object to the field.

  • default specifies the default value of the resulting field; if not set and the field is required, it will raise an error
  • required indicates whether the field should be required or not; default is True

The following field types are available:

AdapterMethodField

The field gets it's value by calling a method defined on the adapter class. It can be used to manipulate the data.

The method_name argument refers to the name of the method. It defaults to get_<field_name>.

BooleanField

Converts the result to a boolean value.

CharField

A Unicode field.

DateField

Parses the value into a datetime.date object.

DateTimeField

Parses the value into a datetime.datetime object.

DecimalField

Parses the value into a Decimal object.

FloatField

A float field.

IntField

An integer field.

TimeField

Parses the value into a datetime.time object.

VerbatimField

Copy the value as is.

python-adapters's People

Contributors

alexei avatar illia-v avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-adapters's Issues

Add omitempty option

I.e. a field having omitempty=True would not be set on the destination object

Get_attribute method is misbehaving for every other Field except AdapterMethodField.

The BaseField's get_attribute method is reliant on the data provided to the field and so, in the case of all the fields except AdapterMethodField(where get_attribute is overridden), we can get into some nasty issues, for example:
if the data is etree type(from lxml), when we put a CharField() on our custom Adapter, the get_attribute method will think that isinstance(obj, collections.Iterable) is True and such, will try to int(attr) which in our case is a string, <field_name> and it will crash silently(the get_attribute will return undefined because the exception is caught and in the end it will prompt the error message down the line as " Required value not found for field <field_name>. Provide a default value. " which is confusing).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.