Welcome to pycoalaip’s documentation!¶
Important
Development Status: Alpha
Contents:
pycoalaip¶
Python reference implementation for COALA IP.
- Development Status: Alpha
- Free software: Apache Software License 2.0
- Documentation: https://pycoalaip.readthedocs.io
Features¶
CoalaIp.generate_user()
: Create a user representation suitable for use withcoalaip
CoalaIp.register_manifestation()
: Registering aManifestation
(and along with it, an associated parentWork
and aCopyright
of theManifestation
)CoalaIp.derive_right()
: Derivation of aRight
from an allowing sourceRight
orCopyright
CoalaIp.transfer_right()
: Transfer of aRight
orCopyright
from the current owner to a new owner- Querying the ownership history of an COALA IP entity
To learn more about how to use these features, you may be interested in the usage section of the docs.
TODO¶
- Host COALA IP JSON-LD definitions and set
<coalaip placeholder>
to the purl for the definitions. - Support IPLD serialization
Packaging¶
Bumping versions:
$ bumpversion patch
Releasing to pypi:
$ make release
$ twine upload dist/*
Credits¶
This package was created with Cookiecutter and the audreyr/cookiecutter-pypackage project template.
Installation¶
Stable release¶
To install pycoalaip, run this command in your terminal:
$ pip install coalaip
This is the preferred method to install pycoalaip, as it will always install the most recent stable release.
If you don’t have pip installed, this Python installation guide can guide you through the process.
From sources¶
The sources for pycoalaip can be downloaded from the Github repo.
You can either clone the public repository:
$ git clone git://github.com/bigchaindb/pycoalaip
Once you have a copy of the source, you can install it with:
$ python setup.py install
Usage¶
To use pycoalaip in a project:
import coalaip
Quickstart¶
To get started with coalaip
, you should first pick a persistence layer (and
an accompanying plugin) to use. For a list of available persistence layer
plugins, see here.
Once you’ve configured your chosen plugin, the main workflow to follow is:
1. Create an instance of CoalaIp
;
1. Generate users for yourself and other parties;
1. Register a Manifestation
entity (and its accompanying Work
and
Copyright
entities) for your IP;
1. Derive a specific Right
from your IP’s Copyright
(or another
Right
that pertains to your IP); and
1. If desired, transfer the specific Right
to another party, to record a
legal transaction relating to the Right
(e.g. a transfer of ownership,
a loan, etc).
Note
Each of CoalaIp.register_manifestation()
, CoalaIp.derive_right()
,
and CoalaIp.transfer_right()
have optional arguments to cover alternate
use cases that are not explained here.
You may be interested in looking at the library reference for their complete documentation.
Warning
In the current implementation, operations that use the persistence layer are NOT ensured to succeed, and you may find that some operations need to be repeated.
A good example of this is if a storage requiring non-neglible consensus (e.g. BigchainDB) is used: the implementation assumes that everything has succeeded if it was able to write to the storage rather than confirming (later) that what it wrote was actually accepted.
Creating an instance of CoalaIp
¶
Let’s assume you have an instance of a persistence layer plugin ready.
from coalaip import CoalaIp
plugin = Plugin(...)
coalaip = CoalaIp(plugin)
Generating users¶
Representations of users are defined by the persistence layer plugin. You can generate a user compatible with your chosen persistence layer by:
# Note that the plugin may dictate that you need to provide extra arguments
# to this function
user = coalaip.generate_user()
Registering a Manifestation
¶
Upon initial registration of a Manifestation
, a Work
(if not provided)
and Copyright
are automatically generated.
manifestation_data = {...}
registration_result = coalaip.register_manifestation(manifestation_data,
copyright_holder=user)
manifestation = registration_result['manifestation']
work = registration_result['work']
copyright = registration_result['copyright']
Deriving a specific Right
¶
You can create more specific Rights
from source Rights
or
Copyrights
if you are the current holder of the source Right
.
copyright = ...
right_data = {...}
right = coalaip.derive_right(right_data, current_holder=user,
source_right=copyright)
Transferring a Right
¶
Transfers of a Right
will change ownership of the entity from the current
holder to a new holder. A RightsAssignment
entity can also be encoded in a
transfer, holding more specific information about the particular details
related to the transaction, such as a agreed-upon contract between the two
parties, the time of the transaction, and etc.
right = ...
current_holder = ... # user representation
new_holder = ... # user representation
rights_assignment_data = {...}
rights_assignment = coalaip.transfer_right(right, rights_assignment_data,
current_holder=current_holder,
to=new_holder)
Querying for an Entity
’s ownership history¶
Each entity returned has a .history()
method and .current_owner
property defined, in case you’re interested in finding out the ownership
history of the entity.
Obtaining an instance of an Entity
¶
If you know you have COALA IP entities persisted, but don’t have them in an
Entity
class (e.g. you saved the entities’ IDs in a database, and now want
to use them), you can load an instance of an Entity
by using the static
.from_persist_id()
method of that entity type.
from coalaip.entities import Manifestation
manifestation_id = '...'
manifestation = Manifestation.from_persist_id(manifestation_id,
plugin=plugin)
Doing so will generate a lazy-loaded entity for you to use. Accessing the
entity’s data for the first time will load the entity from the persistence
layer (which may error); if you’d like to load it immediately, you can either
call .load()
or use the force_load
flag in .from_persist_id()
:
manifestation = Manifestation.from_persist_id(manifestation_id,
plugin=plugin)
manifestation.load()
# Or
manifestation = Manifestation.from_persist_id(manifestation_id,
force_load=True,
plugin=plugin)
Reference¶
See the library reference for a complete reference of all available classes and functions.
Plugins¶
pycoalaip
requires a persistence layer plugin to be used in order to
persist COALA IP entities to a distributed ledger, database, or file storage
system.
Available Plugins¶
Writing a Plugin¶
Writing a plugin for pycoalaip
is relatively simple. We use the
pycoalaip-{plugin_name} naming scheme for plugin packages.
A plugin is expected to subclass from AbstractPlugin
and implement all the abstract methods and properties, following the API laid
out in the AbstractPlugin
’s documentation.
To make your plugin discoverable by name to pycoalaip
, you should also set
an entry point in your setup.py
for the coalaip_plugin
namespace.
Taking the BigchainDB plugin as an example, this may look something like:
setup(
...
entry_points={
'coalaip_plugin': 'bigchaindb = coalaip_bigchaindb.plugin:Plugin'
},
...
)
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
(aRight
or subclass) for thecurrent_holder
of thesource_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 givenright_entity_cls
for requirements. Ifsource
is provided in the dict, thesource_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 thatCoalaIp
was instantiated with. Ignored ifsource
is provided inright_data
. - right_entity_cls (subclass of
Right
, keyword, optional) – The class that must be instantiated for the newly derived right. Defaults toRight
. - **kwargs – Keyword arguments passed through to the
right_entity_cls
’screate
method (e.g.create()
’sdata_format
)
Returns: A registered
right_entity_cls
Right (by default aRight
)Raises: ModelDataError
– If theright_data
contains invalid or is missing required properties.EntityNotYetPersistedError
– If thesource_right
is not associated with an id on the persistence layer (persist_id
) yetEntityCreationError
– If the Right fails to be created on the persistence layerPersistenceError
– If any other error occurred with the persistence layer
- right_data (dict) – Model data for the
-
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- *args – Argument list passed to the plugin’s
-
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
. SeeManifestation
for requirements. IfmanifestationOfWork
is provided in the dict, theexisting_work
andwork_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 thatCoalaIp
was instantiated with. If specified, thework_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. SeeWork
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 inmanifestation_data
, None will be returned for the Work; otherwise, the givenexisting_work
or automatically created Work will be returned.Return type: RegistrationResult
Raises: ModelDataError
– If themanifestation_data
orwork_data
contain invalid or are missing required properties.IncompatiblePluginError
– If theexisting_work
is not using a compatible pluginEntityNotYetPersistedError
– If theexisting_work
is not associated with an id on the persistence layer (persist_id
) yetEntityCreationError
– If the manifestation, its copyright, or the automatically created work (if no existing work is given) fail to be created on the persistence layerPersistenceError
– If any other error occurred with the persistence layer
- manifestation_data (dict) – Model data for the
-
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
’stransfer
method (e.g.transfer()
’srights_assignment_format
)
Returns: the RightsAssignment entity associated with this transfer
Return type: Raises: EntityNotYetPersistedError
– If theright
has not been persisted yetEntityNotFoundError
– If theright
was not found on the persistence layerEntityTransferError
– If theright
fails to be transferred on the persistence layerPersistenceError
– If any other error occurred with the persistence layer
- right (
-
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
asWork
entities always have @type ‘AbstractWork’.
-
classmethod
-
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.
-
classmethod
-
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
orManifestation
.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: Raises: See
transfer()
- rights_assignment_data (dict) – Model data for the resulting
-
classmethod
-
class
coalaip.entities.
Copyright
(model, plugin)[source]¶ COALA IP’s Copyright entity. Transferrable.
The full entitlement of Copyright to a
Work
orManifestation
.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
asCopyright
are always ‘Copyright’s.
-
classmethod
-
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 throughcreate()
.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. RaisesPersistenceError
if called.
-
classmethod
generate_model
(*args, **kwargs)[source]¶ Generate a Work model.
See
generate_model()
for more details.Ignores the given
ld_type
asRightsAssignment
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 byplugin
.Subclasses must implement their own
generate_model()
;generate_model()
determines the semantics behindmodel
(its creation and validation).-
model
¶ Model
orLazyLoadableModel
– 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. aftercreate()
).
-
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 ofDataFormat
or a string equivalent. Defaults to jsonld.
Returns: Id of this entity on the persistence layer
Return type: 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: EntityNotFoundError
– If the entity is persisted, but could not be found on the persistence layerPersistenceError
– If any other unhandled error in the plugin occurred
-
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 (seeload()
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; seecreate()
on persisting an entity.Based on the
data_format
, the following are considered special keys indata
and will have different behaviour depending on thedata_type
requested in later methods (e.g.create()
):Parameters: - data (dict) – Model data for the entity
- data_format (
DataFormat
or str) – Data format ofdata
; must be a member ofDataFormat
or a string equivalent. Defaults to jsonld. - plugin (subclass of
AbstractPlugin
, keyword) – Persistence layer plugin used by generatedcls
Returns: A generated
cls
entity fromdata
Return type: cls
Raises: ModelDataError
– ifdata
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 ofEntity
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 usedata()
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 setforce_load
or useload()
on the returned entity before accessingdata()
.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 generatedcls
Returns: A generated entity based on
persist_id
Return type: cls
Raises: - If
force_load
isTrue
, seeload()
for the - list of possible exceptions.
- persist_id (str) – Id of the entity on the persistence
layer (see
-
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
– ifdata
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: EntityNotFoundError
– If the entity is persisted, but could not be found on the persistence layerPersistenceError
– If any other unhandled error in the plugin occurred
-
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: EntityNotYetPersistedError
– If the entity is not associated with an id on the persistence layer (persist_id
) yetEntityNotFoundError
– If the entity has apersist_id
but could not be found on the persistence layerPersistenceError
– If any other unhandled error in the plugin occurredModelDataError
– If the loaded entity’s data fails validation or its type or context differs from their expected values
-
status
¶ The current status of this entity in the backing persistence layer, as defined by
Entity.plugin
. InitiallyNone
.Raises: EntityNotFoundError
– If the entity is persisted, but could not be found on the persistence layerPersistenceError
– If any other unhandled error in the plugin occurred
-
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: Raises: EntityNotYetPersistedError
– If the entity being transferred is not associated with an id on the persistence layer (persist_id
) yetEntityNotFoundError
– If the entity could not be found on the persistence layerEntityTransferError
– If the entity fails to be transferred on the persistence layerPersistenceError
– If any other unhandled error in the plugin occurred
-
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.
-
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 validatedata
-
__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. InitiallyNone
. Not initable. Note that this attribute is only immutable after it’s been set once after initialization (e.g. afterload()
).
-
ld_context
¶ See
ld_context
-
__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, aModel
is generated as the instance’sloaded_model
using the given arguments.
-
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 fromvalidator
or its type or context differs from their expected valuesEntityNotFoundError
– If the entity could not be found on the persistence layerPersistenceError
– If any other unhandled error in the plugin occurred
-
data formats
¶
Utilities for data formats supported by pycoalaip.
exceptions
¶
Custom exceptions for COALA IP
-
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.
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
-
-
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.
-
plugin
¶
-
class
coalaip.plugin.
AbstractPlugin
[source]¶ Abstract interface for all persistence layer plugins.
- Expects the following to be defined by the subclass:
type
(as a read-only property)generate_user()
get_status()
save()
transfer()
-
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: EntityNotFoundError
– If the entity could not be found on the persistence layerPersistenceError
– If any other unhandled error in the plugin occurred
-
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: EntityNotFoundError
– If the entity could not be found on the persistence layerPersistenceError
– If any other unhandled error in the plugin occurred
-
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:
-
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: Raises: EntityNotFoundError
– If the entity could not be found on the persistence layerPersistenceError
– If any other unhandled error in the plugin occurred
-
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: Raises: EntityCreationError
– If the entity failed to be createdPersistenceError
– 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: Raises: EntityNotFoundError
– If the entity could not be found on the persistence layerEntityTransferError
– If the entity failed to be transferredPersistenceError
– If any other unhandled error in the plugin occurred
-
type
¶ A string denoting the type of plugin (e.g. BigchainDB).
About this Documentation¶
This section contains instructions to build and view the documentation locally.
If you do not have a clone of the repo, you need to get one.
Viewing the documentation¶
You can either start a little web server locally, or open the HTML files with your browser.
To start a web server at http://localhost:5555/
# In project root, after making the docs
$ cd docs/_build/html/ && python -m SimpleHTTPServer 5555
Alternatively, open the docs/_build/html/index.html file in your web browser.
Making changes¶
Rebuild the docs and refresh the page on your web browser.
Contributing¶
Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.
You can contribute in many ways:
Types of Contributions¶
Report Bugs¶
Report bugs at https://github.com/bigchaindb/pycoalaip/issues.
If you are reporting a bug, please include:
- Your operating system name and version.
- Any details about your local setup that might be helpful in troubleshooting.
- Detailed steps to reproduce the bug.
Fix Bugs¶
Look through the GitHub issues for bugs. Anything tagged with “bug” and “help wanted” is open to whoever wants to implement it.
Implement Features¶
Look through the GitHub issues for features. Anything tagged with “enhancement” and “help wanted” is open to whoever wants to implement it.
Write Documentation¶
pycoalaip could always use more documentation, whether as part of the official pycoalaip docs, in docstrings, or even on the web in blog posts, articles, and such.
Submit Feedback¶
The best way to send feedback is to file an issue at https://github.com/bigchaindb/pycoalaip/issues.
If you are proposing a feature:
- Explain in detail how it would work.
- Keep the scope as narrow as possible, to make it easier to implement.
- Remember that this is a volunteer-driven project, and that contributions are welcome :)
Get Started!¶
Ready to contribute? Here’s how to set up coalaip for local development.
Fork the coalaip repo on GitHub.
Clone your fork locally:
$ git clone git@github.com:your_name_here/coalaip.git
Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:
$ mkvirtualenv coalaip $ cd coalaip/ $ pip install -r requirements_dev.txt
Create a branch for local development:
$ git checkout -b name-of-your-bugfix-or-feature
Now you can make your changes locally.
When you’re done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox:
$ flake8 coalaip tests $ pytest $ tox
To get flake8 and tox, just pip install them into your virtualenv.
Commit your changes and push your branch to GitHub:
$ git add . $ git commit -m "Your detailed description of your changes." $ git push origin name-of-your-bugfix-or-feature
Submit a pull request through the GitHub website.
Pull Request Guidelines¶
Before you submit a pull request, check that it meets these guidelines:
- The pull request should include tests.
- If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.rst.
- The pull request should work for Python 3.4 and 3.5. Check https://travis-ci.org/bigchaindb/pycoalaip/pull_requests and make sure that the tests pass for all supported Python versions.
Tips¶
To run a subset of tests:
$ pytest tests.test_coalaip
To run tests with debugging:
$ pytest -s
To run tests and break on errors:
$ pytest --pdb
Credits¶
Development Lead¶
- BigchainDB <dev@bigchaindb.com>
Contributors¶
None yet. Why not be the first?
History¶
0.0.3 (2017-05-06)¶
Some changes during the OMI hackfest!
- Make creation of Work and Copyright optional when registering a Manifestation.
0.0.2 (2017-05-05)¶
Some changes during the OMI hackfest!
Some highlights:
- Add register_work method to enable registering a work without necessarily registering a manifestation.
0.0.1 (2017-02-17)¶
First alpha release on PyPI.
Additional features added with no backwards-incompatible interface changes. COALA IP models are backwards-incompatible to previous versions due to upgrades related to spec changes.
Some highlights:
- Queryability of an Entity’s ownership history and current owner
- Entities can be given a custom
@id
- Additional sanity checks employed when deriving Rights, to ensure that a correct source Right and current holder are given
- Update COALA IP models to latest spec
- Added usage documentation
0.0.1.dev3 (2016-12-06)¶
Lots of changes and revisions from 0.0.1.dev2. Totally incompatible from before.
Some highlights:
- Implemented Rights derivation (from existing Rights and Copyrights)
- Implemented Rights transfers
- Entities are now best-effort immutable
- Support for loading Entities from a connected persistence layer
0.0.1.dev2 (2016-08-31)¶
- Fix packaging on PyPI
0.0.1.dev1 (2016-08-31)¶
- Development (pre-alpha) release on PyPI.