Library Reference

coalaip

High-level functions for interacting with COALA IP entities

class coalaip.coalaip.CoalaIp(plugin)[source]

High-level, plugin-bound COALA IP functions.

Instantiated with an subclass implementing the ledger plugin interface (AbstractPlugin) that will automatically be bound to all top-level functions:

plugin

Plugin – Bound persistence layer plugin.

__init__(plugin) → None

Initialize self. See help(type(self)) for accurate signature.

derive_right(right_data, *, current_holder, source_right=None, right_entity_cls=<class 'coalaip.entities.Right'>, **kwargs)[source]

Derive a new Right from an existing source_right (a Right or subclass) for the current_holder of the source_right. The newly registered Right can then be transferred to other Parties.

Parameters:
  • right_data (dict) – Model data for the right_entity_cls. See the given right_entity_cls for requirements. If source is provided in the dict, the source_right parameter is ignored.
  • current_holder (any, keyword) – The current holder of the source_right; must be specified in the format required by the persistence layer
  • source_right (Right, keyword, optional) – An already persisted Right that the new Right is allowed by. Must be using the same plugin that CoalaIp was instantiated with. Ignored if source is provided in right_data.
  • right_entity_cls (subclass of Right, keyword, optional) – The class that must be instantiated for the newly derived right. Defaults to Right.
  • **kwargs – Keyword arguments passed through to the right_entity_cls’s create method (e.g. create()’s data_format)
Returns:

A registered right_entity_cls Right (by default a Right)

Raises:
generate_user(*args, **kwargs)[source]

Generate a new user for the backing persistence layer.

Parameters:
  • *args – Argument list passed to the plugin’s generate_user()
  • **kwargs – Keyword arguments passed to the plugin’s generate_user()
Returns:

A representation of a user, based on the persistence layer plugin

Raises:

PersistenceError – If a user couldn’t be generated on the persistence layer

register_manifestation(manifestation_data, *, copyright_holder, existing_work=None, work_data=None, create_work=True, create_copyright=True, **kwargs)[source]

Register a Manifestation and automatically assign its corresponding Copyright to the given user.

Unless specified (see existing_work), also registers a new Work for the Manifestation.

Parameters:
  • manifestation_data (dict) – Model data for the Manifestation. See Manifestation for requirements. If manifestationOfWork is provided in the dict, the existing_work and work_data parameters are ignored and no Work is registered.
  • copyright_holder (any, keyword) – The user to hold the corresponding Copyright of the registered Manifestation; must be specified in the format required by the persistence layer
  • existing_work (Work, keyword, optional) – An already persisted Work that the Manifestation is derived from. Must be using the same plugin that CoalaIp was instantiated with. If specified, the work_data parameter is ignored and no Work is registered.
  • work_data (dict, keyword, optional) – Model data for the Work that will automatically generated for the Manifestation if no existing_work was specified. See Work for requirements. If not specified, the Work will be created using only the name of the Manifestation.
  • create_work (bool, keyword, optional) – To allow for the creation of a Manifestation without attaching a Work. Default is True.
  • create_copyright (bool, keyword, optional) – To allow for the creation of a Manifestation without attaching a Copyright. Default is True.
  • **kwargs – Keyword arguments passed through to each model’s create() (e.g. data_format).
Returns:

A namedtuple containing the Coypright of the registered Manifestation, the registered Manifestation, and the Work as named fields:

(
    'copyright': (:class:`~.Copyright`),
    'manifestation': (:class:`~.Manifestation`),
    'work': (:class:`~.Work`),
)

If manifestationOfWork was provided in manifestation_data, None will be returned for the Work; otherwise, the given existing_work or automatically created Work will be returned.

Return type:

RegistrationResult

Raises:
  • ModelDataError – If the manifestation_data or work_data contain invalid or are missing required properties.
  • IncompatiblePluginError – If the existing_work is not using a compatible plugin
  • EntityNotYetPersistedError – If the existing_work is not associated with an id on the persistence layer (persist_id) yet
  • EntityCreationError – If the manifestation, its copyright, or the automatically created work (if no existing work is given) fail to be created on the persistence layer
  • PersistenceError – If any other error occurred with the persistence layer
register_work(work_data, *, copyright_holder, **kwargs)[source]

Register a work

transfer_right(right, rights_assignment_data=None, *, current_holder, to, **kwargs)[source]

Transfer a Right to another user.

Parameters:
  • right (Right) – An already persisted Right to transfer
  • rights_assignment_data (dict, optional) – Model data for the generated RightsAssignment that will be associated with the transfer
  • current_holder (any, keyword) – The current holder of the right; must be specified in the format required by the persistence layer
  • to (any, keyword) – The new holder of the right; must be specified in the format required by the persistence layer. If the specified user format includes private information (e.g. a private key) but is not required by the persistence layer to identify a transfer recipient, then this information may be omitted in this argument.
  • **kwargs – keyword arguments passed through to the right’s transfer method (e.g. transfer()’s rights_assignment_format)
Returns:

the RightsAssignment entity associated with this transfer

Return type:

RightsAssignment

Raises:

entities

Entities mirroring COALA IP’s entity model.

Requires usage with a persistence layer plugin (see AbstractPlugin) for the creation and transfer of entities. JSON, JSON-LD, and IPLD data formats are supported.

Note

This module should not be used directly to generate entities, unless you are extending the built-ins for your own extensions. Instead, use the high-level functions (coalaip) that return instances of these entities.

Warning

The immutability guarantees given in this module are best-effort. There is no general way to achieve immutability in Python, but we try our hardest to make it so.

Core Entities

Note

Most of these core entity classes have their functionality implemented through Entity. See Entity for an overview of the base functionality of each of these core entities.

class coalaip.entities.Work(model, plugin)[source]

COALA IP’s Work entity.

A distinct, abstract Creation whose existence is revealed through one or more Manifestation entities.

Work entities are always of @type ‘AbstractWork’.

classmethod generate_model(*args, **kwargs)[source]

Generate a Work model.

See generate_model() for more details.

Ignores the given ld_type as Work entities always have @type ‘AbstractWork’.

class coalaip.entities.Manifestation(model, plugin)[source]

COALA IP’s Manifestation entity.

A perceivable manifestation of a Work.

Manifestation entities are by default of @type ‘CreativeWork’.

classmethod generate_model(*args, **kwargs)[source]

Generate a Manifestation model.

See generate_model() for more details.

class coalaip.entities.Right(model, plugin)[source]

COALA IP’s Right entity. Transferrable.

A statement of entitlement (i.e. “right”) to do something in relation to a Work or Manifestation.

More specific rights, such as PlaybackRights, StreamRights, etc should be implemented as subclasses of this class.

By default, Rights entities are of @type ‘Right’ and only include the COALA IP context, as Rights are not dependent on schema.org.

classmethod generate_model(*args, **kwargs)[source]

Generate a Work model.

See generate_model() for more details.

transfer(rights_assignment_data=None, *, from_user, to_user, rights_assignment_format='jsonld')[source]

Transfer this Right to another owner on the backing persistence layer.

Parameters:
  • rights_assignment_data (dict) – Model data for the resulting RightsAssignment
  • from_user (any, keyword) – A user based on the model specified by the persistence layer
  • to_user (any, keyword) – A user based on the model specified by the persistence layer
  • rights_assignment_format (str, keyword, optional) –

    Data format of the created entity; must be one of:

    • ’jsonld’ (default)
    • ’json’
    • ’ipld’
Returns:

The RightsAssignment entity created from this transfer

Return type:

RightsAssignment

Raises:

See transfer()

class coalaip.entities.Copyright(model, plugin)[source]

COALA IP’s Copyright entity. Transferrable.

The full entitlement of Copyright to a Work or Manifestation.

Copyright entities are always of @type ‘Copyright’ and by default only include the COALA IP context, they are not dependent on schema.org.

classmethod generate_model(*args, **kwargs)[source]

Generate a Work model.

See generate_model() for more details.

Ignores the given ld_type as Copyright are always ‘Copyright’s.

class coalaip.entities.RightsAssignment(model, plugin)[source]

COALA IP’s RightsAssignment entity.

The assignment (e.g. transfer) of a Right to someone.

RightsAssignment entities may only be persisted in the underlying persistence layer through transfer operations, and hence cannot be created normally through create().

RightsAssignment entities are always of @type ‘RightsAssignment’ and by default only include the COALA IP context, as Copyrights are not dependent on schema.org.

create(*args, **kwargs)[source]

Removes the ability to persist a RightsAssignment normally. Raises PersistenceError if called.

classmethod generate_model(*args, **kwargs)[source]

Generate a Work model.

See generate_model() for more details.

Ignores the given ld_type as RightsAssignment entities always have @type ‘RightsTransferAction’s.

Base Entities

Base functionality for the models above. These should never be instantiated; prefer one of the Core Entities instead.

class coalaip.entities.Entity(model, plugin)[source]

Abstract base class of all COALA IP entity models.

Immutable (see :class:`~.PostInitImmutable`).

Implements base functionality for all COALA IP entities, including entity creation (create()) and status queries (status) on the backing persistence layer provided by plugin.

Subclasses must implement their own generate_model(); generate_model() determines the semantics behind model (its creation and validation).

model

Model or LazyLoadableModel – Model of the entity. Holds the data and Linked Data (JSON-LD) specifics.

plugin

subclass of AbstractPlugin – Persistence layer plugin used by the Entity

persist_id

str – Id of this entity on the persistence layer, if saved to one. Initially None. Not initable. Note that this attribute is only immutable after it’s been set once after initialization (e.g. after create()).

create(user, data_format=<DataFormat.jsonld: 'jsonld'>)[source]

Create (i.e. persist) this entity to the backing persistence layer.

Parameters:
  • user (any) – A user based on the model specified by the persistence layer
  • data_format (DataFormat or str) – Data format used in persisting the entity; must be a member of DataFormat or a string equivalent. Defaults to jsonld.
Returns:

Id of this entity on the persistence layer

Return type:

str

Raises:
  • EntityCreationError – If an error occurred during the creation of this entity that caused it to NOT be persisted. Contains the original error from the persistence layer, if available.
  • EntityPreviouslyCreatedError – If the entity has already been persisted. Contains the existing id of the entity on the persistence layer.
  • PersistenceError – If any other unhandled error in the plugin occurred
current_owner

any – A user based on the model specified by the persistence layer if a current owner exists, otherwise None. In the case where the user model contains secret information, the returned user may omit this information.

Raises:
data

dict – A copy of the basic data held by this entity model. Does not include any JSON-LD or IPLD specific information.

If the entity was generated through from_persist_id(), the first access of this property may also load the entity’s data from the persistence layer (see load() for potentially raised exceptions)

classmethod from_data(data, *, data_format=<DataFormat.jsonld: 'jsonld'>, plugin)[source]

Generic factory for instantiating cls entities from their model data. Entities instantiated from this factory have yet to be created on the backing persistence layer; see create() on persisting an entity.

Based on the data_format, the following are considered special keys in data and will have different behaviour depending on the data_type requested in later methods (e.g. create()):

  • jsonld:
    • @type’ denotes the Linked Data type of the entity
    • @context’ denotes the JSON-LD context of the entity
    • @id’ denotes the JSON-LD identity of the entity
  • Otherwise:
    • ‘type’ denotes the Linked Data type of the entity
Parameters:
  • data (dict) – Model data for the entity
  • data_format (DataFormat or str) – Data format of data; must be a member of DataFormat or a string equivalent. Defaults to jsonld.
  • plugin (subclass of AbstractPlugin, keyword) – Persistence layer plugin used by generated cls
Returns:

A generated cls entity from data

Return type:

cls

Raises:

ModelDataError – if data fails model validation

classmethod from_persist_id(persist_id, *, force_load=False, plugin)[source]

Generic factory for creating cls entity instances from their persisted ids.

Note: by default, instances generated from this factory lazily load their data upon first access (accessing data()), which may throw under various conditions. In general, most usages of Entity and its subclasses do not require access to their data (including internal methods), and thus the data does not usually need to be loaded unless you expect to explicitly use data() or one of the transformation methods, e.g. to_json(). If you know you will be using the data and want to avoid raising unexpected exceptions upon access, make sure to set force_load or use load() on the returned entity before accessing data().

Parameters:
  • persist_id (str) – Id of the entity on the persistence layer (see Entity.plugin)
  • force_load (bool, keyword, optional) – Whether to load the entity’s data immediately from the persistence layer after instantiation. Defaults to false.
  • plugin (subclass of AbstractPlugin, keyword) – Persistence layer plugin used by generated cls
Returns:

A generated entity based on persist_id

Return type:

cls

Raises:
  • If force_load is True, see load() for the
  • list of possible exceptions.
classmethod generate_model(*, data, ld_type, ld_context, model_cls)[source]

Generate a model instance for use with the current cls.

Must be implemented by subclasses of Entity.

Parameters:
  • data (dict, keyword) – Model data
  • ld_type (str, keyword) – @type of the entity.
  • ld_context (str or dict or [str|dict], keyword) – “@context” for the entity as either a string URL or array of string URLs or dictionaries. See the JSON-LD spec on contexts for more information.
  • model_cls (class, keyword) – Model class to use the generated model. See models.
Returns:

A model instance

Raises:

ModelDataError – if data fails model validation

history

list of dict – A list containing the ownership history of this entity. Each item in the list is a dict containing a user based on the model specified by the persistence layer and a reference id for the event (e.g. transfer). The ownership events are sorted starting from the beginning of the entity’s history (i.e. creation). In the case where the user model contains secret information, the returned user may omit this information.

Raises:
load()[source]

Load this entity from the backing persistence layer, if possible.

When used by itself, this method is most useful in ensuring that an entity generated from from_persist_id() is actually available on the persistence layer to avoid errors later.

Raises:
status

The current status of this entity in the backing persistence layer, as defined by Entity.plugin. Initially None.

Raises:
to_ipld()[source]

Output this entity’s data as an IPLD-serializable dict.

The entity’s @type is represented as ‘type’ and the @context is ignored.

to_json()[source]

Output this entity as a JSON-serializable dict.

The entity’s @type is represented as ‘type’ and the @context is ignored.

to_jsonld()[source]

Output this entity as a JSON-LD-serializable dict.

Adds the @type, @context, and @id as-is. If no @id was given, an empty @id is used by default to refer to the current persist_id document.

class coalaip.entities.TransferrableEntity(model, plugin)[source]

Base class for transferable COALA IP entity models.

Provides functionality for transferrable entities through transfer()

transfer(transfer_payload=None, *, from_user, to_user)[source]

Transfer this entity to another owner on the backing persistence layer

Parameters:
  • transfer_payload (dict) – Payload for the transfer
  • from_user (any) – A user based on the model specified by the persistence layer
  • to_user (any) – A user based on the model specified by the persistence layer
Returns:

Id of the resulting transfer action on the persistence layer

Return type:

str

Raises:

models

Low level data models for COALA IP entities.

Encapsulates the data modelling of COALA IP entities. Supports model validation and the loading of data from a backing persistence layer.

Note

This module should not be used directly to generate models, unless you are extending the built-ins for your own extensions. Instead, use the models that are contained in the entities (entities) returned from the high-level functions (coalaip).

Warning

The immutability guarantees given in this module are best-effort. There is no general way to achieve immutability in Python, but we try our hardest to make it so.

class coalaip.models.Model(data, ld_type, ld_id='', ld_context=NOTHING, validator=<instance_of validator for type <class 'mappingproxy'>>)[source]

Basic data model class for COALA IP entities. Includes Linked Data (JSON-LD) specifics.

Immutable (see :class:`~.PostInitImmutable` and attributes).

Initialization may throw if attribute validation fails.

data

dict – Model data. Uses validator for validation.

ld_type

str – @type of the entity

ld_id

str – @id of the entity

ld_context

str or dict or [str|dict], keyword – “@context” for the entity as either a string URL or array of string URLs or dictionaries. See the JSON-LD spec on contexts for more information.

validator

callable – A validator complying to attr’s validator API that will validate data

__init__(data, ld_type, ld_id='', ld_context=NOTHING, validator=<instance_of validator for type <class 'mappingproxy'>>) → None

Initialize self. See help(type(self)) for accurate signature.

class coalaip.models.LazyLoadableModel(ld_type, ld_id=None, ld_context=None, validator=<instance_of validator for type <class 'mappingproxy'>>, data=None)[source]

Lazy loadable data model class for COALA IP entities.

Immutable (see :class:`.PostInitImmutable` and attributes).

Similar to Model, except it allows the model data to be lazily loaded afterwards from a backing persistence layer through a plugin.

loaded_model

Model – Loaded model from a backing persistence layer. Initially None. Not initable. Note that this attribute is only immutable after it’s been set once after initialization (e.g. after load()).

ld_type

See ld_type

ld_context

See ld_context

validator

See validator

__init__(ld_type, ld_id=None, ld_context=None, validator=<instance_of validator for type <class 'mappingproxy'>>, data=None)[source]

Initialize a LazyLoadableModel instance.

If a data is provided, a Model is generated as the instance’s loaded_model using the given arguments.

Ignores ld_id, see the ld_id() property instead.

data

dict – Model data.

Raises ModelNotYetLoadedError if the data has not been loaded yet.

ld_id

str – @id of the entity.

Raises ModelNotYetLoadedError if the data has not been loaded yet.

load(persist_id, *, plugin)[source]

Load the loaded_model of this instance. Noop if model was already loaded.

Parameters:
  • persist_id (str) – Id of this model on the persistence layer
  • plugin (subclass of AbstractPlugin) – Persistence layer plugin to load from
Raises:
  • ModelDataError – If the loaded entity’s data fails validation from validator or its type or context differs from their expected values
  • EntityNotFoundError – If the entity could not be found on the persistence layer
  • PersistenceError – If any other unhandled error in the plugin occurred

data formats

Utilities for data formats supported by pycoalaip.

class coalaip.data_formats.DataFormat[source]

Enum of supported data formats.

exceptions

Custom exceptions for COALA IP

class coalaip.exceptions.CoalaIpError[source]

Base class for all Coala IP errors.

class coalaip.exceptions.IncompatiblePluginError[source]

Raised when entities with incompatible plugins are used together. Should contain a list of the incompatible plugins as the first argument.

class coalaip.exceptions.ModelError[source]

Base class for all model errors.

class coalaip.exceptions.ModelDataError[source]

Raised if there is an error with the model’s data.

class coalaip.exceptions.ModelNotYetLoadedError[source]

Raised if the lazily loaded model has not been loaded from the backing persistence layer yet.

class coalaip.exceptions.PersistenceError(message='', error=None)[source]

Base class for all persistence-related errors.

message

str – Message of the error

error

Exception – Original exception, if available

class coalaip.exceptions.EntityCreationError(message='', error=None)[source]

Raised if an error occured during the creation of an entity on the backing persistence layer. Should contain the original error that caused the failure, if available.

class coalaip.exceptions.EntityNotFoundError(message='', error=None)[source]

Raised if the entity could not be found on the backing persistence layer

class coalaip.exceptions.EntityNotYetPersistedError(message='', error=None)[source]

Raised when an action requiring an entity to be available on the persistence layer is attempted on an entity that has not been persisted yet.

class coalaip.exceptions.EntityPreviouslyCreatedError(existing_id, *args, **kwargs)[source]

Raised when attempting to persist an already persisted entity. Should contain the existing id of the entity.

existing_id

str – Currently existing id of the entity on the persistence layer

See :exc:`.PersistenceError` for other attributes.
class coalaip.exceptions.EntityTransferError(message='', error=None)[source]

Raised if an error occured during the transfer of an entity on the backing persistence layer. Should contain the original error that caused the failure, if available.

plugin

class coalaip.plugin.AbstractPlugin[source]

Abstract interface for all persistence layer plugins.

Expects the following to be defined by the subclass:
generate_user(*args, **kwargs)[source]

Generate a new user on the persistence layer.

Parameters:
  • *args – argument list, as necessary
  • **kwargs – keyword arguments, as necessary
Returns:

A representation of a user (e.g. a tuple with the user’s public and private keypair) on the persistence layer

Raises:

PersistenceError – If any other unhandled error in the plugin occurred

get_history(persist_id)[source]

Get the ownership history of an entity on the persistence layer.

Parameters:

persist_id (str) – Id of the entity on the persistence layer

Returns:

The ownership history of the entity, sorted starting from the beginning of the entity’s history (i.e. creation). Each dict is of the form:

{
    'user': A representation of a user as specified by the
            persistence layer (may omit secret details, e.g. private keys),
    'event_id': A reference id for the ownership event (e.g. transfer id)
}

Return type:

list of dict

Raises:
get_status(persist_id)[source]

Get the status of an entity on the persistence layer.

Parameters:

persist_id (str) – Id of the entity on the persistence layer

Returns:

Status of the entity, in any format.

Raises:
is_same_user(user_a, user_b)[source]

Compare the given user representations to see if they mean the same user on the persistence layer.

Parameters:
  • user_a (any) – User representation
  • user_b (any) – User representation
Returns:

Whether the given user representations are the same user.

Return type:

bool

load(persist_id)[source]

Load the entity from the persistence layer.

Parameters:

persist_id (str) – Id of the entity on the persistence layer

Returns:

The persisted data of the entity

Return type:

dict

Raises:
save(entity_data, *, user)[source]

Create the entity on the persistence layer.

Parameters:
  • entity_data (dict) – The entity’s data
  • user (any, keyword) – The user the entity should be assigned to after creation. The user must be represented in the same format as generate_user()’s output.
Returns:

Id of the created entity on the persistence layer

Return type:

str

Raises:
  • EntityCreationError – If the entity failed to be created
  • PersistenceError – If any other unhandled error in the plugin occurred
transfer(persist_id, transfer_payload, *, from_user, to_user)[source]

Transfer the entity whose id matches persist_id on the persistence layer from the current user to a new owner.

Parameters:
  • persist_id (str) – Id of the entity on the persistence layer
  • transfer_payload (dict) – The transfer’s payload
  • from_user (any, keyword) – The current owner, represented in the same format as generate_user()’s output
  • to_user (any, keyword) – The new owner, represented in the same format as generate_user()’s output. If the specified user format includes private information (e.g. a private key) but is not required by the persistence layer to identify a transfer recipient, then this information may be omitted in this argument.
Returns:

Id of the transfer action on the persistence layer

Return type:

str

Raises:
  • EntityNotFoundError – If the entity could not be found on the persistence layer
  • EntityTransferError – If the entity failed to be transferred
  • PersistenceError – If any other unhandled error in the plugin occurred
type

A string denoting the type of plugin (e.g. BigchainDB).