Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for GETing entities #28

Merged
merged 2 commits into from
Feb 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,10 @@ To check if your POST was successful, try validating by doing the following:

or

1. Try to [request for the entity with a GET request](#requesting-submitted-entities)

or

1. Open your browser and go to `http://localhost:9984/api/v1` (your locally
running BigchainDB instance - if using the default Docker settings, use port
`32768` instead).
Expand Down Expand Up @@ -366,6 +370,17 @@ manifestation](#was-my-post-to-manifestations-successful) and use the returned
Right's data instead.


### Requesting Submitted Entities

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


### Querying the ownership history of a Right

The ownership history of a Right is represented as an time-series array of
Expand Down
4 changes: 2 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def created_manifestation_resp(client, alice):
},
}

resp = client.post(url_for('manifestation_views.manifestationapi'),
resp = client.post(url_for('manifestation_views.manifestationlistapi'),
data=json.dumps(payload),
headers={'Content-Type': 'application/json'})

Expand All @@ -66,7 +66,7 @@ def created_derived_right(client, alice, created_manifestation_resp):
'sourceRightId': copyright_id,
}

resp = client.post(url_for('right_views.rightapi'),
resp = client.post(url_for('right_views.rightlistapi'),
data=json.dumps(payload),
headers={'Content-Type': 'application/json'})

Expand Down
76 changes: 70 additions & 6 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def test_create_manifestation(client, alice):
'@type': 'Copyright',
},
}
resp = client.post(url_for('manifestation_views.manifestationapi'),
resp = client.post(url_for('manifestation_views.manifestationlistapi'),
data=json.dumps(payload),
headers={'Content-Type': 'application/json'})
resp_dict = resp.json
Expand Down Expand Up @@ -82,7 +82,7 @@ def test_create_manifestation_missing_single_attribute(client, alice):
'author': 'J. R. R. Tolkien',
},
}
resp = client.post(url_for('manifestation_views.manifestationapi'),
resp = client.post(url_for('manifestation_views.manifestationlistapi'),
data=json.dumps(payload),
headers={'Content-Type': 'application/json'})
# TODO: I really don't know why flask_restful includes the extra '' in the
Expand All @@ -100,14 +100,47 @@ def test_create_manifestation_missing_argument_in_body(client):
'datePublished': '29-07-1954',
},
}
resp = client.post(url_for('manifestation_views.manifestationapi'),
resp = client.post(url_for('manifestation_views.manifestationlistapi'),
data=json.dumps(payload),
headers={'Content-Type': 'application/json'})
assert resp.status_code == 400
assert resp.json['message']['work'] == \
'Missing required parameter in the JSON body'


def test_get_manifestation(client, alice, created_manifestation_resp):
manifestation = created_manifestation_resp['manifestation']
resp = client.get(
url_for('manifestation_views.manifestationapi',
entity_id=manifestation['@id']))

assert resp.status_code == 200

resp_manifestation = resp.json
# The Manifestation we get back has its @id set to "" as it could be found
# at that location
resp_manifestation.pop('@id')
manifestation.pop('@id')

assert resp_manifestation == manifestation


def test_get_work(client, alice, created_manifestation_resp):
work = created_manifestation_resp['work']
work_id = work['@id'].split('../works/')[1]
resp = client.get(url_for('work_views.workapi', entity_id=work_id))

assert resp.status_code == 200

resp_work = resp.json
# The Work we get back has its @id set to "" as it could be found
# at that location
resp_work.pop('@id')
work.pop('@id')

assert resp_work == work


def test_create_right(client, alice, created_manifestation_resp):
copyright_id = created_manifestation_resp['copyright']['@id']
copyright_id = copyright_id.split('../rights/')[1]
Expand All @@ -129,7 +162,7 @@ def test_create_right(client, alice, created_manifestation_resp):
},
}

resp = client.post(url_for('right_views.rightapi'),
resp = client.post(url_for('right_views.rightlistapi'),
data=json.dumps(payload),
headers={'Content-Type': 'application/json'})
resp_dict = resp.json
Expand All @@ -148,7 +181,7 @@ def test_create_right_missing_single_attribute(client, alice):
},
'sourceRightId': 'mockId',
}
resp = client.post(url_for('right_views.rightapi'),
resp = client.post(url_for('right_views.rightlistapi'),
data=json.dumps(payload),
headers={'Content-Type': 'application/json'})
assert resp.status_code == 400
Expand All @@ -163,14 +196,45 @@ def test_create_right_missing_argument_in_body(client, alice):
'license': 'http://www.ascribe.io/terms',
},
}
resp = client.post(url_for('right_views.rightapi'),
resp = client.post(url_for('right_views.rightlistapi'),
data=json.dumps(payload),
headers={'Content-Type': 'application/json'})
assert resp.status_code == 400
assert resp.json['message']['sourceRightId'] == \
'Missing required parameter in the JSON body'


def test_get_right_from_copyright(client, alice, created_manifestation_resp):
copyright = created_manifestation_resp['copyright']
copyright_id = copyright['@id'].split('../rights/')[1]
resp = client.get(url_for('right_views.rightapi', entity_id=copyright_id))

assert resp.status_code == 200

resp_copyright = resp.json
# The Copyright we get back has its @id set to "" as it could be found
# at that location
resp_copyright.pop('@id')
copyright.pop('@id')

assert resp_copyright == copyright


def test_get_right_from_right(client, alice, created_derived_right):
resp = client.get(url_for('right_views.rightapi',
entity_id=created_derived_right['@id']))

assert resp.status_code == 200

resp_right = resp.json
# The Right we get back has its @id set to "" as it could be found
# at that location
resp_right.pop('@id')
created_derived_right.pop('@id')

assert resp_right == created_derived_right


def test_transfer_right(client, alice, bob, carly, created_derived_right):
payload = {
'rightId': created_derived_right['@id'],
Expand Down
2 changes: 2 additions & 0 deletions web/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from web.views.users import user_views
from web.views.manifestations import manifestation_views
from web.views.rights import right_views
from web.views.works import work_views


class StandaloneApplication(gunicorn.app.base.BaseApplication):
Expand Down Expand Up @@ -67,6 +68,7 @@ def create_app(settings):
app.register_blueprint(user_views, url_prefix='/api/v1')
app.register_blueprint(manifestation_views, url_prefix='/api/v1')
app.register_blueprint(right_views, url_prefix='/api/v1')
app.register_blueprint(work_views, url_prefix='/api/v1')
return app


Expand Down
13 changes: 11 additions & 2 deletions web/views/manifestations.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from flask import Blueprint
from flask_restful import reqparse, Resource, Api

from coalaip import CoalaIp
from coalaip import CoalaIp, entities
from coalaip_bigchaindb.plugin import Plugin
from web.models import manifestation_model, user_model, work_model
from web.utils import get_bigchaindb_api_url
Expand All @@ -14,6 +14,13 @@


class ManifestationApi(Resource):
def get(self, entity_id):
manifestation = entities.Manifestation.from_persist_id(
entity_id, plugin=coalaip.plugin, force_load=True)
return manifestation.to_jsonld()


class ManifestationListApi(Resource):
def post(self):
parser = reqparse.RequestParser()
parser.add_argument('manifestation', type=manifestation_model,
Expand Down Expand Up @@ -51,5 +58,7 @@ def post(self):
return res


manifestation_api.add_resource(ManifestationApi, '/manifestations',
manifestation_api.add_resource(ManifestationApi, '/manifestations/<entity_id>',
strict_slashes=False)
manifestation_api.add_resource(ManifestationListApi, '/manifestations',
strict_slashes=False)
37 changes: 24 additions & 13 deletions web/views/rights.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,28 @@
right_api = Api(right_views)


def load_right(entity_id):
# We can't be sure of the type of Right that's given by using just the
# id, so let's assume it's a normal Right first before trying to make a
# Copyright
try:
right = entities.Right.from_persist_id(entity_id,
plugin=coalaip.plugin,
force_load=True)
except ModelDataError:
right = entities.Copyright.from_persist_id(entity_id,
plugin=coalaip.plugin,
force_load=True)
return right


class RightApi(Resource):
def get(self, entity_id):
right = load_right(entity_id)
return right.to_jsonld()


class RightListApi(Resource):
def post(self):
parser = reqparse.RequestParser()
parser.add_argument('right', type=right_model, required=True,
Expand Down Expand Up @@ -78,18 +99,7 @@ def post(self):
user['public_key'] = user.pop('publicKey')
user['private_key'] = user.pop('privateKey')

# We can't be sure of the type of Right that's given by using just the
# id, so let's assume it's a normal Right first before trying to make a
# Copyright
try:
right = entities.Right.from_persist_id(right_id,
plugin=coalaip.plugin,
force_load=True)
except ModelDataError:
right = entities.Copyright.from_persist_id(right_id,
plugin=coalaip.plugin,
force_load=True)

right = load_right(right_id)
res = coalaip.transfer_right(right=right,
rights_assignment_data=rights_assignment,
current_holder=current_holder,
Expand All @@ -100,8 +110,9 @@ def post(self):
return res


right_api.add_resource(RightApi, '/rights', strict_slashes=False)
right_api.add_resource(RightApi, '/rights/<entity_id>', strict_slashes=False)
right_api.add_resource(RightHistoryApi, '/rights/history/<string:right_id>',
strict_slashes=False)
right_api.add_resource(RightListApi, '/rights', strict_slashes=False)
right_api.add_resource(RightTransferApi, '/rights/transfer',
strict_slashes=False)
22 changes: 22 additions & 0 deletions web/views/works.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from flask import Blueprint
from flask_restful import Resource, Api

from coalaip import CoalaIp, entities
from coalaip_bigchaindb.plugin import Plugin
from web.utils import get_bigchaindb_api_url


coalaip = CoalaIp(Plugin(get_bigchaindb_api_url()))

work_views = Blueprint('work_views', __name__)
work_api = Api(work_views)


class WorkApi(Resource):
def get(self, entity_id):
work = entities.Work.from_persist_id(
entity_id, plugin=coalaip.plugin, force_load=True)
return work.to_jsonld()


work_api.add_resource(WorkApi, '/work/<entity_id>', strict_slashes=False)