A HTTP wrapper for pycoalaip.
pycoalaip is Python-specific. Furthermore all underlying dependencies are written in Python, which means that parties interested in COALA IP would have to re-implement large parts of their logic in their programming language to make use of COALA IP. To solve this problem in the short-term, this library exposes a RESTful web interface (runnable in Docker) of the functionalities provided in pycoalaip.
Alpha. At the moment all you can do is hit against a few endpoints that are being exposed. Minimal error paths are provided. This package and pycoalaip will probably mature rather quickly as we're actively developing them currently.
No. Currently we're hitting against a BigchainDB instance running in quasi "regtest" mode. Its never been used in production either. In its current state, this package can and should be used to experiment with COALA IP.
- Read the installation section on how to install with Docker.
- Get familiar with the REST API provided at the end of this document.
- Hit against a running Docker container with a HTTP client of your choice.
NO! Think of this library more like a shell-command. The flask server should at least be run behind a reverse-proxy like nginx, so that its interface is NOT exposed to the world wide web.
Yes, curl.
-
You'll have to install, configure and run BigchainDB as well as MongoDB.
-
Install and run this library using the following commands:
$ git clone git@github.com:bigchaindb/coalaip-http-api.git
$ virtualenv --python=python3 venv
$ source venv/bin/activate
$ pip install -r requirements_dev.txt
$ python web/server.py
Use Docker 🐳.
You'll need to have at least the base Docker and Docker Compose installed, but on some platforms (i.e. OSX and Windows), Docker Machine. will also be necessary. As a quick primer, it may be interesting to go through the guide to run BigchainDB via Docker, but we've already set up everything for you in this repo.
If you already have Docker installed, just make sure you have a recent version:
$ docker --version
Docker version 1.12.1, build 23cf638
$ docker-compose --version
docker-compose version 1.15.0, build e12f3b9
Using the provided docker-compose.yml, you can install and start MongoDB, BigchainDB, and the COALA IP HTTP server with just a few commands.
First, copy the default environment settings and build the Docker containers:
$ cp .env_template .env
$ docker-compose build
And then start the services:
# In one terminal
# Note that BigchainDB must be started after RethinkDB has begun accepting connections (may take a few seconds)
$ docker-compose up -d mdb
$ docker-compose up bigchaindb
# In another terminal
$ docker-compose up api
By default, the COALA IP HTTP server will now be available through
http://localhost:3000/api/v1/
, along with the BigchainDB API
(http://localhost:32768/api/v1/
).
Note: If you are running Docker through Docker Machine, the services will
only be available through the hostname of your Docker Machine instance. Use
docker-machine ip <machine-name>
to get this hostname, and use it to replace
the localhost
part of the above URLs.
The API server can be configured with a number of environment variables see .env_template.
Let's assume you have an artwork you'd like to loan to someone else. These are the steps you'll need to follow in order to register the work and any transactions relating to the work via COALA IP.
- First, create some users for both yourself and those "someone elses"
- Register your artwork as a Manifestation
- Derive a special "usage" Right from the Copyright that resulted from registering your artwork
- Finally, transfer that special "usage" Right to someone else, optionally including a contract and other information as part of the transfer.
This call will not store any data on the running instance of BigchainDB. It simply generates a public/private key-pair that can be used in a POST-manifestation call.
POST /api/v1/users/
HEADERS {"Content-Type": "application/json"}
PAYLOAD: None
RETURNS:
{
"publicKey": "<base58 string>",
"privateKey": "<base58 string>",
}
In order to register the manifestation on BigchainDB as transactions on a
specific copyright holder's name, the copyright holder's publicKey
and
privateKey
must be provided here.
Note that the attributes shown for manifestation
and work
can be much more
diverse; for this, see their COALA IP models definition.
POST /api/v1/manifestations/
HEADERS {"Content-Type": "application/json"}
PAYLOAD:
{
"manifestation": {
"name": "The Fellowship of the Ring",
"datePublished": "29-07-1954",
"url": "<URI pointing to a media blob>"
},
"copyrightHolder": {
"publicKey": "<base58 string>",
"privateKey": "<base58 string>"
},
"work": {
"name": "The Lord of the Rings Triology",
"author": "J. R. R. Tolkien"
}
}
RETURNS:
{
"work": {
"@id": "<Relative URI with the ID of the entity on BigchainDB>",
"@type": "AbstractWork",
"name": "The Lord of the Rings Trilogy",
"author": "J. R. R. Tolkien"
},
"manifestation": {
"@id": "<Relative URI with the ID of the entity on BigchainDB>",
"@type": "CreativeWork"
"name": "The Fellowship of the Ring",
"manifestationOfWork": "<URI pointing to the Work's transaction ../<txid>",
"datePublished": "29-07-1954",
"url": "<URI pointing to a media blob>"
},
"copyright": {
"@id": "<Relative URI with the ID of the entity on BigchainDB>",
"@type": "Copyright"
"rightsOf": "<Relative URI pointing to the Manifestation ../<txid>"
}
}
The returned @id
s denote the persisted ID of the entities on BigchainDB as a
relative URI to the current document base (i.e. the route URL, or
/manifestations
in this case). For now, these point to the CREATE
transaction for the entity; in the future, they will be changing to be an asset
ID instead.
In the case of the returned Work and Copyright, their @id
s are slightly
inconvenient to process as they live under a different base URL (/works
and
/rights
, respectively). You should strip away the leading paths to use just
the persisted IDs of these entities.
Note that in the future, we also plan to replace the JSON-LD linking structure with IPLD.
To check if your POST was successful, try validating by doing the following:
- Check the response of your POST request: Is the return value similar to the example provided above?
or
or
-
Open your browser and go to
http://localhost:9984/api/v1
(your locally running BigchainDB instance - if using the default Docker settings, use port32768
instead). -
To check if your previously created entities were included in BigchainDB, take the string in any of the returned
@id
s and append it to the following link:http://localhost:9984/api/v1/transactions/<string goes here>
. BigchainDB should then answer with the transaction the entity was registered in (if using the default Docker settings, use port32768
instead).
Note: If running on Docker and/or Docker Machine, substitute the hostnames and ports of the above URLs with your Docker settings, as necessary (see the running with Docker section for more help).
Rather than registering new Rights directly to resulting rightsholders, new Rights are initially registered to the current holder of the existing Right or Copyright that allows for the new Right's creation. Doing so allows the initial link between the source rightsholder and resulting rightsholder to be kept as part of the new Right's chain of provenance.
Note that the attributes for the right
may be much more diverse; see its COALA
IP models definition.
Also see transferring a Right on how to transfer a registered Right to new holders.
POST /api/v1/rights/
HEADERS {"Content-Type": "application/json"}
PAYLOAD:
{
"right": {
"license": "<Legal license text or URI pointing to a license document>"
},
"currentHolder": {
"publicKey": "<base58 string>",
"privateKey": "<base58 string>"
},
"sourceRightId": "<ID of an existing Right that allows for the creation of this new Right; must be held by the user specified in `currentHolder`>"
}
RETURNS:
{
"right": {
"@id": "<Relative URI with the ID of the entity on BigchainDB>",
"@type": "Right",
"source": "<sourceRightId>",
"license": "<Legal license text or URI pointing to a license document>",
}
}
To check if your POST was successful, follow the steps in registering a manifestation and use the returned Right's data instead.
A contract between a rightsholder and a licensee can be recorded through the transferring of a Right, via an accompanying RightsAssignment entity. The transfer transaction recorded on BigchainDB links to that contract (via the RightsAssignment) and provides a record of the parties, the date of the transaction, and the contract that applies.
You may only transfer a Right (or Copyright) that you are currently holding.
RightsAssignment entities are automatically created for each transfer and may
include additional arbitrary attributes if a rightsAssignment
dict is given
in the payload.
POST /api/v1/rights/transfer
HEADERS {"Content-Type": "application/json"}
PAYLOAD:
{
"rightId": "<ID of an existing Right to transfer; must be held by the user specified in `currentHolder`>",
"rightsAssignment": {
...
},
"currentHolder": {
"publicKey": "<base58 string>",
"privateKey": "<base58 string>"
},
"to": {
"publicKey": "<base58 string>",
"privateKey": null
}
}
RETURNS:
{
"rightsAssignment": {
"@id": "<currently empty>",
"@type": "RightsTransferAction",
... (provided `rightsAssignment`)
}
}
Note that the to
field in the payload may avoid specifying the new holder's
private details (i.e. signingKey
), but should still provide the keys needed to
conform to the user model.
To check if your POST was successful, follow the steps in registering a manifestation and use the returned Right's data instead.
You can retrieve any submitted entities via a GET to one of the following
endpoints with the entity's ID (usually the @id
stripped of any relative URL
artifacts):
/manifestations/<manifestation_id>
: Manifestations/works/<work_id>
: Works/rights/<right_id>
: Copyrights and Rights
The ownership history of a Right is represented as an time-series array of ownership events (sorted from the initial creation of the entity), each in the form of:
{
"user": {
"publicKey": "<public key of the owner>",
"privateKey": null
},
"eventId": "<transaction id of the transaction detailing the ownership event>"
}
Note that, as in the recipient (to
) of a Rights transfer, the returned user
models only contain their public information.
GET /api/v1/rights/<ID of an existing right>
RETURNS:
[{
"user": {
"publicKey": "<public key of the owner>",
"privateKey": null
},
"eventId": "<transaction id of the transaction detailing the ownership event>"
}, ...]