The lima API

Please note that the lima API uses a relatively uncommon feature of Python 3: Keyword-only arguments.

Keyword-only arguments

Keyword-only arguments can be recognized by their position in a method/function signature: Every argument coming after the varargs argument like *args (or after a single *) is a keyword-only argument.

A function that is defined as def foo(*, x, y): pass must be called like this: foo(x=1, y=2); calling foo(1, 2) will raise a TypeError.

It is the author’s opinion that enforcing keyword arguments in the right places makes the resulting code more readable.

For more information about keyword-only arguments, see PEP 3102

lima.abc

Abstract base classes for fields and schemas.

class lima.abc.FieldABC

Abstract base class for fields.

Being an instance of FieldABC marks a class as a field for internal type checks. You can use this class to implement your own type checks as well.

Note

To create new fields, it’s a better Idea to subclass lima.fields.Field directly instead of implementing FieldABC on your own.

class lima.abc.SchemaABC

Abstract base class for schemas.

Being an instance of SchemaABC marks a class as a schema for internal type checks. You can use this class to implement your own type checks as well.

Note

To create new schemas, it’s a way better Idea to subclass lima.schema.Schema directly instead of implementing SchemaABC on your own.

lima.exc

The lima exception hierarchy.

Note

Currently this module only holds Exceptions related to lima.registry, but this might change in the future.

exception lima.exc.AmbiguousClassNameError

Raised when asking for a class with an ambiguous name.

Usually this is the case if two or more classes of the same name were registered from within different modules, and afterwards a registry is asked for one of those classes without specifying the module in the class name.

exception lima.exc.ClassNotFoundError

Raised when a class was not found by a registry.

exception lima.exc.RegisterLocalClassError

Raised when trying to register a class defined in a local namespace.

exception lima.exc.RegistryError

The base class for all registry-related exceptions.

lima.fields

Field classes and related code.

lima.fields.TYPE_MAPPING =dict(...)

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object’s

(key, value) pairs
dict(iterable) -> new dictionary initialized as if via:

d = {} for k, v in iterable:

d[k] = v
dict(**kwargs) -> new dictionary initialized with the name=value pairs
in the keyword argument list. For example: dict(one=1, two=2)
class lima.fields.Boolean(*, attr=None, key=None, get=None, val=None)

A boolean field.

currently this class has no additional functionality compared to Field. Nevertheless it should be used over Field when referencing boolean values as an indicator for a field’s type and to keep code future-proof.

class lima.fields.Date(*, attr=None, key=None, get=None, val=None)

A date field.

static pack(val)

Return a string representation of val.

Parameters:val – The :class: datetime.date object to convert.
Returns:The ISO 8601-representation of val (YYYY-MM-DD).
class lima.fields.DateTime(*, attr=None, key=None, get=None, val=None)

A DateTime field.

static pack(val)

Return a string representation of val.

Parameters:val – The :class: datetime.datetime object to convert.
Returns:The ISO 8601-representation of val (YYYY-MM-DD%HH:MM:SS.mmmmmm+HH:MM for datetime.datetime objects with Timezone information and microsecond precision).
class lima.fields.Decimal(*, attr=None, key=None, get=None, val=None)

A decimal field.

Decimal values get serialized as strings, this way, no precision is lost.

class lima.fields.Embed(*, schema, attr=None, key=None, get=None, val=None, **kwargs)

A Field to embed linked objects.

Parameters:
  • schema – The schema of the linked object. This can be specified via a schema object, a schema class or the qualified name of a schema class (for when the named schema has not been defined at the time of instantiation. If two or more schema classes with the same name exist in different modules, the schema class name has to be fully module-qualified (see the entry on class names for clarification of these concepts). Schemas defined within a local namespace can not be referenced by name.
  • attr – See :class: Field.
  • key – See :class: Field.
  • get – See :class: Field.
  • val – See :class: Field.
  • kwargs – Optional keyword arguments to pass to the :class: Schema‘s constructor when the time has come to instance it. Must be empty if schema is a lima.schema.Schema object.

Examples:

# refer to PersonSchema class
author = Embed(schema=PersonSchema)

# refer to PersonSchema class with additional params
artists = Embed(schema=PersonSchema, exclude='email', many=True)

# refer to PersonSchema object
author = Embed(schema=PersonSchema())

# refer to PersonSchema object with additional params
# (note that Embed() itself gets no kwargs)
artists = Embed(schema=PersonSchema(exclude='email', many=true))

# refer to PersonSchema per name
author = Embed(schema='PersonSchema')

# refer to PersonSchema per name with additional params
author = Embed(schema='PersonSchema', exclude='email', many=True)

# refer to PersonSchema per module-qualified name
# (in case of ambiguity)
author = Embed(schema='project.persons.PersonSchema')

# specify attr name as well
user = Embed(attr='login_user', schema=PersonSchema)
pack(val)

Return the marshalled representation of val.

Parameters:val – The linked object to embed.
Returns:The marshalled representation of val (or None if val is None).

Note that the return value is determined using an (internal) dump fields function of the associated schema object. This means that overriding the associated schema’s dump() method has no effect on the result of this method.

class lima.fields.Field(*, attr=None, key=None, get=None, val=None)

Base class for fields.

Parameters:
  • attr – The optional name of the corresponding attribute.
  • key – The optional name of the corresponding key.
  • get – An optional getter function accepting an object as its only parameter and returning the field value.
  • val – An optional constant value for the field.

New in version 0.3: The val parameter.

attr, key, get and val are mutually exclusive.

When a Field object ends up with two or more of the attributes attr, key, get and val regardless (because one or more of them are implemented at the class level for example), lima.schema.Schema.dump() tries to get the field’s value in the following order: val get key and finally attr.

If a Field object ends up with none of these attributes (not at the instance and not at the class level), lima.schema.Schema.dump() tries to get the field’s value by looking for an attribute of the same name as the field has within the corresponding lima.schema.Schema instance.

class lima.fields.Float(*, attr=None, key=None, get=None, val=None)

A float field.

currently this class has no additional functionality compared to Field. Nevertheless it should be used over Field when referencing float values as an indicator for a field’s type and to keep code future-proof.

class lima.fields.Integer(*, attr=None, key=None, get=None, val=None)

An integer field.

currently this class has no additional functionality compared to Field. Nevertheless it should be used over Field when referencing integer values as an indicator for a field’s type and to keep code future-proof.

class lima.fields.Reference(*, schema, field, attr=None, key=None, get=None, val=None, **kwargs)

A Field to reference linked objects.

Parameters:
  • schema – A schema for the linked object (see :class: Embed for details on how to specify this schema). One field of this schema will act as reference to the linked object.
  • field – The name of the field to act as reference to the linked object.
  • attr – see :class: Field.
  • key – see :class: Field.
  • get – see :class: Field.
  • val – see :class: Field.
  • kwargs – see :class: Embed.
pack(val)

Return value of reference field of marshalled representation of val.

Parameters:val – The nested object to get the reference to.
Returns:The value of the reference-field of the marshalled representation of val (see field argument of constructor) or None if val is None.

Note that the return value is determined using an (internal) dump field function of the associated schema object. This means that overriding the associated schema’s dump() method has no effect on the result of this method.

class lima.fields.String(*, attr=None, key=None, get=None, val=None)

A string field.

currently this class has no additional functionality compared to Field. Nevertheless it should be used over Field when referencing string values as an indicator for a field’s type and to keep code future-proof.

lima.schema

Schema class and related code.

class lima.schema.Schema(*, exclude=None, only=None, include=None, ordered=False, many=False)

Base class for Schemas.

Parameters:
  • exclude – An optional sequence of field names to be removed from the fields of the new Schema instance. If only one field is to be removed, it’s ok to supply a simple string instead of a list containing only one string for exclude. exclude may not be specified together with only.
  • only – An optional sequence of the names of the only fields that shall remain for the new Schema instance. If just one field is to remain, it’s ok to supply a simple string instead of a list containing only one string for only. only may not be specified together with exclude.
  • include – An optional mapping of field names to fields to additionally include in the new Schema instance. Think twice before using this option - most of the time it’s better to include fields at class level rather than at instance level.
  • ordered – An optional boolean indicating if the :meth: Schema.dump method should output collections.OrderedDict objects instead of simple dict objects. Defaults to False. This does not influence how nested fields are serialized.
  • many – An optional boolean indicating if the new Schema will be serializing single objects (many=False) or collections of objects (many=True) per default. This can later be overridden in the dump() Method.

New in version 0.3: The include parameter.

New in version 0.3: The ordered parameter.

Upon creation, each Schema object gets an internal mapping of field names to fields. This mapping starts out as a copy of the class’s __fields__ attribute. (For an explanation on how this __fields__ attribute is determined, see SchemaMeta.)

Note that the fields themselves are not copied - changing the field of an instance would change this field for the other instances and classes referencing this field as well. In general it is strongly suggested to treat fields as immutable.

The internal field mapping is then modified as follows:

  • If include was provided, fields specified therein are added (overriding any fields of the same name already present)

    If the order of your fields is important, make sure that include is of type collections.OrderedDict or similar.

  • If exclude was provided, fields specified therein are removed.

  • If only was provided, all but the fields specified therein are removed (unless exclude was provided as well, in which case a ValueError is raised.)

Also upon creation, each Schema object gets an individually created dump function that aims to unroll most of the loops and to minimize the number of attribute lookups, resulting in a little speed gain on serialization.

Schema classes defined outside of local namespaces can be referenced by name (used by lima.fields.Nested).

dump(obj)

Return a marshalled representation of obj.

Parameters:obj – The object (or collection of objects, depending on the schema’s many property) to marshall.
Returns:A representation of obj in the form of a JSON-serializable dict (or collections.OrderedDict, depending on the schema’s ordered property), with each entry corresponding to one of the schema’s fields. (Or a list of such dicts in case a collection of objects was marshalled)

Changed in version 0.4: Removed the many parameter of this method.

many

Read-only property: does the dump method expect collections?

ordered

Read-only property: does the dump method return ordered dicts?

class lima.schema.SchemaMeta

Metaclass of Schema.

Note

The metaclass SchemaMeta is used internally to simplify the configuration of new Schema classes. For users of the library there should be no need to use SchemaMeta directly.

When defining a new Schema (sub)class, SchemaMeta makes sure that the new class has a class attribute __fields__ of type collections.OrderedDict containing the fields for the new Schema.

__fields__ is determined like this:

  • The __fields__ of all base classes are copied (with base classes specified first having precedence).

    Note that the fields themselves are not copied - changing an inherited field would change this field for all base classes referencing this field as well. In general it is strongly suggested to treat fields as immutable.

  • Fields (Class variables of type lima.abc.FieldABC) are moved out of the class namespace and into __fields__, overriding any fields of the same name therein.

  • If present, the class attribute __lima_args__ is removed from the class namespace and evaluated as follows:

    • Fields specified via __lima_args__['include'] (an optional mapping of field names to fields) are inserted into __fields__. overriding any fields of the same name therein.

      If the order of your fields is important, make sure that __lima_args__['include'] is of type collections.OrderedDict or similar.

      New fields in __lima_args__['include']__ are inserted at the position where __lima_args__ is specified in the class.

    • Fields named in an optional sequence __lima_args__['exclude'] are removed from __fields__. If only one field is to be removed, it’s ok to supply a simple string instead of a list containing only one string. __lima_args__['exclude'] may not be specified together with __lima_args__['only'].

    • If in an optional sequence __lima_args__['only'] is provided, all but the fields mentioned therein are removed from __fields__. If only one field is to remain, it’s ok to supply a simple string instead of a list containing only one string. __lima_args__['only'] may not be specified together with __lima_args__['exclude'].

      Think twice before using __lima_args__['only'] - most of the time it’s better to rethink your Schema than to remove a lot of fields that maybe shouldn’t be there in the first place.

New in version 0.3: Support for __lima_args__['only'].

SchemaMeta also makes sure the new Schema class is registered with the lima class registry lima.registry (at least if the Schema isn’t defined inside a local namespace, where we wouldn’t find it later on).

classmethod __prepare__(metacls, name, bases)

Return an OrderedDict as the class namespace.

This allows us to keep track of the order in which fields were defined for a schema.