diff --git a/.travis.yml b/.travis.yml index fbae3a7..417233f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -60,6 +60,9 @@ before_script: - travis_retry pip install kwalitee GitPython --pre # needs recent pep257 - kwalitee check message -s ${TRAVIS_COMMIT_RANGE} - travis_retry pip install pytest-pep257 # needs older pep257 + - travis_retry pip install sphinx + - sphinx-apidoc -f -e -o docs/api/ claimstore + - if [ -n "$(git status -s)" ]; then echo "Mismatch between the output of sphinx-apidoc and the files in docs/api/*. Please, run 'sphinx-apidoc -f -e -o docs/api/ claimstore' and commit/push again." && exit 1; fi script: - python setup.py test diff --git a/claimstore/modules/claims/restful.py b/claimstore/modules/claims/restful.py index 1a2603b..d283a8f 100644 --- a/claimstore/modules/claims/restful.py +++ b/claimstore/modules/claims/restful.py @@ -25,7 +25,6 @@ from collections import defaultdict from functools import wraps -from uuid import UUID import isodate # noqa from flask import Blueprint, current_app, request @@ -111,9 +110,9 @@ def validate_json(self, json_data): raise InvalidJSONData('JSON data is not valid', extra=str(e)) -class Subscription(ClaimStoreResource): +class ClaimantResource(ClaimStoreResource): - """Register a new claimant in the database. + """Resource related to claimant subscription in the ClaimStore. This POST service expects JSON data following the JSON schema defined for claimants. @@ -122,10 +121,62 @@ class Subscription(ClaimStoreResource): json_schema = 'claims.claimant' def post(self): - """Subscribe a new claimant. + """Register a new claimant in the ClaimStore. - Receives JSON data with all the information of a new claimant and it - stores it in the database. + .. http:post:: /subscribe + + This resource is expecting JSON data with all the necessary + information of a new claimant. + + **Request**: + + .. sourcecode:: http + + POST /subscribe HTTP/1.1 + Content-Type: application/json + Host: localhost:5000 + + { + "name": "INSPIRE", + "url": "http://inspirehep.net" + } + + :reqheader Content-Type: application/json + :json body: JSON with the information of the claimant. The JSON + data should be valid according to the `JSON Schema for + claimants `_. + + **Responses**: + + .. sourcecode:: http + + HTTP/1.0 200 OK + Content-Length: 80 + Content-Type: application/json + + { + "status": "success", + "uuid": "ab19c98b-xxxx-xxxx-xxxx-1d6af3bf58b4" + } + + .. sourcecode:: http + + HTTP/1.0 400 BAD REQUEST + Content-Length: 95 + Content-Type: application/json + + { + "extra": null, + "message": "This claimant is already registered", + "status": 400 + } + + :resheader Content-Type: application/json + :statuscode 200: no error - the claimant was subscribed + :statuscode 400: invalid request - problably a malformed JSON + :statuscode 403: access denied + + .. see docs/users.rst for usage documenation. """ json_data = request.get_json() self.validate_json(json_data) @@ -159,7 +210,7 @@ def post(self): raise InvalidRequest('This claimant is already registered') -class ClaimsResource(ClaimStoreResource): +class ClaimResource(ClaimStoreResource): """Resource that handles all claims-related requests.""" @@ -251,8 +302,78 @@ def __init__(self): def post(self): """Record a new claim. - This POST service expects JSON data following the JSON schema defined - for claims. + .. http:post:: /claims + + This resource is expecting JSON data with all the necessary + information of a new claim. + + **Request**: + + .. sourcecode:: http + + POST /claims HTTP/1.1 + Accept: application/json + Content-Length: 336 + Content-Type: application/json + + { + "arguments": { + "actor": "CDS_submission", + "human": 0 + }, + "certainty": 1.0, + "claimant": "CDS", + "created": "2015-03-25T11:00:00Z", + "object": { + "type": "CDS_REPORT_NUMBER", + "value": "CMS-PAS-HIG-14-008" + }, + "predicate": "is_same_as", + "subject": { + "type": "CDS_RECORD_ID", + "value": "2003192" + } + } + + :reqheader Content-Type: application/json + :json body: JSON with the information of the claimt. The JSON + data should be valid according to the `JSON Schema for + claims `_. + + **Responses**: + + .. sourcecode:: http + + HTTP/1.0 200 OK + Content-Length: 80 + Content-Type: application/json + + { + "status": "success", + "uuid": "fad4ec9f-0e95-4a22-b65c-d01f15aba6be" + } + + .. sourcecode:: http + + HTTP/1.0 400 BAD REQUEST + Content-Length: 9616 + Content-Type: application/json + Date: Tue, 22 Sep 2015 09:02:25 GMT + Server: Werkzeug/0.10.4 Python/3.4.3 + + { + "extra": "'claimant' is a required property. Failed + validating 'required' in schema...", + "message": "JSON data is not valid", + "status": 400 + } + + :resheader Content-Type: application/json + :statuscode 200: no error - the claim was recorded + :statuscode 400: invalid request - problably a malformed JSON + :statuscode 403: access denied + + .. see docs/users.rst for usage documenation. """ json_data = request.get_json() @@ -326,33 +447,111 @@ def post(self): def get(self): """GET service that returns the stored claims. - - Many arguments can be used in order to filter the output. Only AND - queries are preformed at the moment. - - List of arguments: - - * since: datetime (YYYY-MM-DD) - it fetches claims that were created - from this given datetime. - * until: datetime (YYYY-MM-DD) - it fetches claims that were created - up to this given datetime. - * claimant: claimant's unique name - it fetches claims submitted by the - specified claimant. - * predicate: predicate's unique name - it finds claims using this - predicate (e.g. is_same_as). - * certainty: float number between 0 and 1.0. It will search for claims - with at least the specified certainty. - * human: enter 1 if searching for human-created claims, 0 for - algorithms and nothing in order to retrieve all. - * actor: it filters claims by their actor's name (one can use %). - * role: it filters claims by their actor's role (one can use %). - * type: it finds claims using a certain identifier type (either subject - or object). For instance: DOI. - * value: it fetches all the claims with that identifier value. - * subject: it fetches claims using a given identifier type as a subject - type. - * object: it fetches claims using a given identifier type as an object - type. + .. http:get:: /claims + + Returns a JSON list with all the claims matching the query + parameters. + + **Request**: + + .. sourcecode:: http + + GET /claims?type=INSPIRE_RECORD_ID&value=cond-mat/9906097& + recurse=1 HTTP/1.1 + Accept: */* + Host: localhost:5000 + + :reqheader Content-Type: application/json + :query datetime since: it must have the format 'YYYY-MM-DD'. It + fetches claims that were created from this + given datetime. + :query datetime until: it must have the format 'YYYY-MM-DD'. It + fetches claims that were created up to this + given datetime. + :query string claimant: claimant's unique name. It fetches claims + submitted by the specified claimant. + :query string predicate: predicate's unique name. It finds claims + using this predicate (e.g. is_same_as). + :query float certainty: float number between 0 and 1.0. It will + search for claims with at least the + specified certainty. + :query int human: enter 1 if searching for human-created claims, 0 + for algorithms and nothing in order to retrieve + all. + :query string actor: it filters claims by their actor's name (one + can use `%`). + :query string role: it filters claims by their actor's role (one + can use `%`). + :query string type: it finds claims using a certain identifier type + (either subject or object). For instance: DOI. + :query string value: it fetches all the claims with that identifier + value. + :query boolean recurse: used in combination with `type` and `value` + will find all the equivalent identifiers to + the specified one. + :query string subject: it fetches claims using the given identifier + type as a subject type. + :query string object: it fetches claims using the given identifier + type as an object type. + + **Response**: + + .. sourcecode:: http + + HTTP/1.0 200 OK + Content-Length: 1166 + Content-Type: application/json + + [ + { + "arguments": { + "actor": "CDS_submission", + "human": 0 + }, + "certainty": 1.0, + "claimant": "CDS", + "created": "2015-03-25T11:00:00Z", + "object": { + "type": "CDS_REPORT_NUMBER", + "value": "CMS-PAS-HIG-14-008" + }, + "predicate": "is_same_as", + "recieved": "2015-09-22T08:18:30.606912+00:00", + "subject": { + "type": "CDS_RECORD_ID", + "value": "2003192" + }, + "uuid": "44103ee2-0d87-47f9-b0e4-77673d297cdb" + }, + { + "arguments": { + "actor": "John Doe", + "human": 1, + "role": "cataloguer" + }, + "certainty": 0.5, + "claimant": "INSPIRE", + "created": "2015-05-25T11:00:00Z", + "object": { + "type": "CDS_RECORD_ID", + "value": "2003192" + }, + "predicate": "is_variant_of", + "recieved": "2015-09-22T08:18:30.638933+00:00", + "subject": { + "type": "INSPIRE_RECORD_ID", + "value": "cond-mat/9906097" + }, + "uuid": "27689445-02b9-4d5d-8f9b-da21970e2352" + } + ] + + :resheader Content-Type: application/json + :statuscode 200: no error + :statuscode 400: invalid request + :statuscode 403: access denied + + .. see docs/users.rst for usage documenation. """ args = self.get_claims_parser.parse_args() if all(x is None for x in args.values()): # Avoid false positives (0) @@ -465,7 +664,47 @@ class IdentifierResource(ClaimStoreResource): """Resource that handles Identifier requests.""" def get(self): - """GET service that returns the stored identifiers.""" + """GET service that returns the stored identifiers. + + .. http:get:: /identifiers + + Returns a JSON list with all the available identifiers. + + **Request**: + + .. sourcecode:: http + + GET /identifiers HTTP/1.1 + Accept: */* + Host: localhost:5000 + + :reqheader Content-Type: application/json + + **Response**: + + .. sourcecode:: http + + HTTP/1.0 200 OK + Content-Length: 147 + Content-Type: application/json + + [ + "ARXIV_ID", + "CDS_AUTHOR_ID", + "CDS_RECORD_ID", + "CDS_REPORT_NUMBER", + "DOI", + "INSPIRE_AUTHOR_ID", + "INSPIRE_RECORD_ID" + ] + + :resheader Content-Type: application/json + :statuscode 200: no error + :statuscode 400: invalid request + :statuscode 403: access denied + + .. see docs/users.rst for usage documenation. + """ id_types = IdentifierType.query.all() return [id_type.name for id_type in id_types] @@ -475,7 +714,45 @@ class PredicateResource(ClaimStoreResource): """Resource that handles Predicate requests.""" def get(self): - """GET service that returns the stored predicates.""" + """GET service that returns all the available predicates. + + .. http:get:: /predicates + + Returns a JSON list with all the predicates. + + **Request**: + + .. sourcecode:: http + + GET /predicates HTTP/1.1 + Accept: */* + Host: localhost:5000 + + :reqheader Content-Type: application/json + + **Response**: + + .. sourcecode:: http + + HTTP/1.0 200 OK + Content-Length: 108 + Content-Type: application/json + + [ + "is_author_of", + "is_contributor_to", + "is_erratum_of", + "is_same_as", + "is_variant_of" + ] + + :resheader Content-Type: application/json + :statuscode 200: no error + :statuscode 400: invalid request + :statuscode 403: access denied + + .. see docs/users.rst for usage documenation + """ predicates = Predicate.query.all() return [pred.name for pred in predicates] @@ -484,26 +761,76 @@ class EquivalentIdResource(ClaimStoreResource): """Resource that handles Equivalent Identifier requests.""" - def __init__(self): - """Initialise Equivalent Identifier Resource.""" - super(ClaimStoreResource, self).__init__() - self.get_eqids_parser = reqparse.RequestParser() - self.get_eqids_parser.add_argument( - 'eqid', dest='eqid', - type=str, location='args', - help='Unique equivalent identifier', - trim=True - ) - - def get(self): - """GET service that returns the stored Equivalent Identifiers.""" - args = self.get_eqids_parser.parse_args() - if args.eqid: - try: - UUID(args.eqid) - except ValueError: - raise InvalidRequest('Badly formed EQID (uuid)') - eqids = EquivalentIdentifier.query.filter_by(eqid=args.eqid) + def get(self, eqid=None): + """GET service that returns all the stored Equivalent Identifiers. + + .. http:get:: /eqids/(uuid:eqid) + + Returns all the type/value entries in the index grouped by their + equivalent identifiers. + + **Requests**: + + .. sourcecode:: http + + GET /eqids HTTP/1.1 + Accept: */* + Host: localhost:5000 + + .. sourcecode:: http + + GET /eqids/0e64606e-68ce-482e-ad59-1e9981394f84 HTTP/1.1 + Accept: */* + Host: localhost:5000 + + :reqheader Content-Type: application/json + :param eqid: query by a specific uuid which is shared by some + equivalent identifiers + + **Response**: + + .. sourcecode:: http + + HTTP/1.0 200 OK + Content-Length: 592 + Content-Type: application/json + + { + "36dfb125-5c35-4d3a-870c-76eb4bad498e": [ + { + "type": "ARXIV_ID", + "value": "cond-mat/9906097" + }, + { + "type": "DOI", + "value": "C10.1103/PhysRevE.62.7422" + } + ], + "77c4a5eb-3ed8-4c80-ba0d-644d6bc397a3": [ + { + "type": "CDS_RECORD_ID", + "value": "2003192" + }, + { + "type": "CDS_REPORT_NUMBER", + "value": "CMS-PAS-HIG-14-008" + }, + { + "type": "INSPIRE_RECORD_ID", + "value": "cond-mat/9906097" + } + ] + } + + :resheader Content-Type: application/json + :statuscode 200: no error + :statuscode 400: invalid request - problably a malformed UUID + :statuscode 403: access denied + + .. see docs/users.rst for usage documenation. + """ + if eqid: + eqids = EquivalentIdentifier.query.filter_by(eqid=str(eqid)) else: eqids = EquivalentIdentifier.query.all() output_dict = defaultdict(list) @@ -515,10 +842,10 @@ def get(self): return output_dict -claims_api.add_resource(Subscription, +claims_api.add_resource(ClaimantResource, '/subscribe', endpoint='subscribe') -claims_api.add_resource(ClaimsResource, +claims_api.add_resource(ClaimResource, '/claims', endpoint='claims') claims_api.add_resource(IdentifierResource, @@ -529,4 +856,5 @@ def get(self): endpoint='predicates') claims_api.add_resource(EquivalentIdResource, '/eqids', + '/eqids/', endpoint='eqids') diff --git a/claimstore/modules/claims/templates/claims/api.html b/claimstore/modules/claims/templates/claims/api.html deleted file mode 100644 index 2fbc321..0000000 --- a/claimstore/modules/claims/templates/claims/api.html +++ /dev/null @@ -1,557 +0,0 @@ -{# -*- coding: utf-8 -*- -# -# This file is part of ClaimStore. -# Copyright (C) 2015 CERN. -# -# ClaimStore is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 3 of the -# License, or (at your option) any later version. -# -# ClaimStore is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with ClaimStore; if not, write to the Free Software Foundation, Inc., -# 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -#} - -{% extends "claims/base.html" %} - -{% block css %} - {{ super() }} - -{% endblock %} - -{% block content %} - -
- -
-

API Documentation

-

To be completed

-

Resources

-

List of resources available at ClaimStore

-
-

Subscribe to ClaimStore

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
POST /subscribe
DescriptionRegisters a new claimant into ClaimStore
URLhttp://localhost:5000/subscribe
MethodPOST
Request headersContent-Type: application/json
Data parameters -

JSON with the information of the claimant. The JSON data should be valid according to the JSON Schema for claimants.

-
Success response -
    -
  • Code: 200 OK
  • -
  • Body: JSON with status and message
  • -
-
Error response -
    -
  • Code: 40X
  • -
  • Body: JSON with status and message
  • -
-
Example - -
-
-
-
http POST http://localhost:5000/subscribe < json/examples/claimant.cds.json
-
-
-
-
curl http://localhost:5000/subscribe -H "Content-Type: application/json" -d '{"name":"INSPIRE", "url": "http://inspirehep.net", "persistent_identifiers":[{"type":"INSPIRE_RECORD_ID", "description":"INSPIRE record", "url": "http://inspirehep.net/record/<INSPIRE_RECORD_ID>", "example_value": "123", "example_url":"http://inspirehep.net/record/123"}, {"type": "INSPIRE_AUTHOR_ID", "description": "INSPIRE author", "url": "http://inspirehep.net/author/<INSPIRE_AUTHOR_ID>", "example_value": "J.R. Ellis.1", "example_url": "http://inspirehep.net/author/J.R.Ellis.1"}]}' -X POST -v
-
-
-
-
-import json
-import requests
-
-url = "http://localhost:5000/subscribe/
-headers = {"Content-Type": "application/json"}
-with open('$PROJECT_HOME/claimstore/static/json/examples/claimant.cds.json') as f:
-    data=json.dumps(f.read())
-r = requests.post(url, data=data, headers=headers)
-                    
-
-
-
-
-
-
-

Submit a claim

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
POST /claims
DescriptionStores a new claim in ClaimStore
URLhttp://localhost:5000/claims
MethodPOST
Request headersContent-Type: application/json
Data parameters -

JSON with the information of the claim. The JSON data should be valid according to the JSON Schema for claims.

-
Success response -
    -
  • Code: 200 OK
  • -
  • Body: JSON with status and message
  • -
-
Error response -
    -
  • Code: 40X
  • -
  • Body: JSON with status and message
  • -
-
Example - -
-
-
-
http POST http://localhost:5000/claims < json/examples/claim.cds.json
-
-
-
-
curl http://localhost:5000/claims -H "Content-Type: application/json" -d '{"claimant":"CDS", "object": {"type": "CDS_RECORD_ID", "value": "CMS-PAS-HIG-14-008"}, "claim": {"predicate": "is_same_as", "created": "2015-05-25 11:00:00 UTC", "certainty": 1, "arguments":{"human": 0, "actor": "CDS_submission"}}, "subject": {"type": "CDS_REPORT_NUMBER", "value": "2001192"}}' -X POST -v
-
-
-
-
-import json
-import requests
-
-url = "http://localhost:5000/claims/
-headers = {"Content-Type": "application/json"}
-with open('$PROJECT_HOME/claimstore/static/json/examples/claim.cds.1.json') as f:
-    data=json.dumps(f.read())
-r = requests.post(url, data=data, headers=headers)
-
-
-
-
-
-
-

List claims

-
- - - - - - - - - - - - - - - - - - - - - -

All parameters are optional.

- - - - - - - - - - - - - - - - - - - -
GET /claims
DescriptionList of claims in ClaimStore
URLhttp://localhost:5000/claims
URL parameters -
    -
  • since: claims created from this date (format: YYYY-MM-DD).
  • -
  • until: claims created until this date (format: YYYY-MM-DD).
  • -
  • claimant: claimant's name as it was registered (e.g. CDS).
  • -
  • predicate: predicate's name (e.g. is_same_as)
  • -
  • certainty: number between 0 and 1.0 (e.g. 0.5). It will search for claims with at least the specified certainty.
  • -
  • human: enter 1 if searching for human-created claims, 0 for algorithms and nothing for retrieving all.
  • -
  • actor: actor's name (one can use %).
  • -
  • role: actor's role (one can use %).
  • -
  • type: identifier type (e.g. DOI).
  • -
  • value: identifier value (e.g. 20110301).
  • -
  • recurse: used in combination with "type" and "value" will find all the equivalent identifiers to the specified one.
  • -
  • subject: identifier type used as a subject type.
  • -
  • object: identifier type used as an object type.
  • -
-
MethodGET
Success response -

JSON list with all the claims.

-
Error response -
    -
  • Code: 40X
  • -
  • Body: JSON with status and message
  • -
-
Example - -
-
-
-
http GET http://localhost:5000/claims
-
-
-
-
curl http://localhost:5000/claims
-
-
-
-
-import requests
-response = requests.get("http://localhost:5000/claims")
-print response.json()
-                    
-
-
-
-
-
-
-

List identifiers

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
GET /identifiers
DescriptionList of identifiers in ClaimStore
URLhttp://localhost:5000/identifiers
MethodGET
Success response -

JSON list with all the identifiers.

-
Error response -
    -
  • Code: 40X
  • -
  • Body: JSON with status and message
  • -
-
Example - -
-
-
-
http GET http://localhost:5000/identifiers
-
-
-
-
curl http://localhost:5000/identifiers
-
-
-
-
-import requests
-response = requests.get("http://localhost:5000/identifiers")
-print response.json()
-                    
-
-
-
-
-
-
-

List predicates

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
GET /predicates
DescriptionList of predicates in ClaimStore
URLhttp://localhost:5000/predicates
MethodGET
Success response -

JSON list with all the predicates.

-
Error response -
    -
  • Code: 40X
  • -
  • Body: JSON with status and message
  • -
-
Example - -
-
-
-
http GET http://localhost:5000/predicates
-
-
-
-
curl http://localhost:5000/predicates
-
-
-
-
-import requests
-response = requests.get("http://localhost:5000/predicates")
-print response.json()
-                    
-
-
-
-
-
-
-

List equivalent identifiers

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
GET /eqids
DescriptionList of equivalent identifiers in ClaimStore
URLhttp://localhost:5000/eqids
MethodGET
Success response -

JSON list with all the equivalent identifiers.

-
Error response -
    -
  • Code: 40X
  • -
  • Body: JSON with status and message
  • -
-
Example - -
-
-
-
http GET http://localhost:5000/eqids
-
-
-
-
curl http://localhost:5000/eqids
-
-
-
-
-import requests
-response = requests.get("http://localhost:5000/eqids")
-print response.json()
-                    
-
-
-
-
-
-
-
- -{% endblock %} - -{% block scripts %} - -{{ super() }} - - - -{% endblock %} diff --git a/claimstore/modules/claims/templates/claims/base.html b/claimstore/modules/claims/templates/claims/base.html index 5e06d99..2c5f476 100644 --- a/claimstore/modules/claims/templates/claims/base.html +++ b/claimstore/modules/claims/templates/claims/base.html @@ -54,7 +54,7 @@

diff --git a/claimstore/modules/claims/views.py b/claimstore/modules/claims/views.py index fcd194d..457e020 100644 --- a/claimstore/modules/claims/views.py +++ b/claimstore/modules/claims/views.py @@ -59,12 +59,6 @@ def claimsubmit(): ) -@views_bp.route('/api', methods=['GET']) -def api(): - """Render the API documenation page.""" - return render_template("claims/api.html", active_menu='api') - - @views_bp.route('/contact', methods=['GET']) def contact(): """Render the contact page.""" diff --git a/docs/Makefile b/docs/Makefile index 3db932d..4cc054f 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -50,6 +50,7 @@ clean: rm -rf $(BUILDDIR)/* html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." diff --git a/docs/api.rst b/docs/api.rst deleted file mode 100644 index 619c1ff..0000000 --- a/docs/api.rst +++ /dev/null @@ -1,154 +0,0 @@ -API ---- - -This part of the documentation describes every public module, class or function. - -claimstore ----------- - -.. automodule:: claimstore - :members: - -claimstore.app --------------- - -.. automodule:: claimstore.app - :members: - -claimstore.cli --------------- - -.. automodule:: claimstore.cli - :members: - -claimstore.config ------------------ - -.. automodule:: claimstore.config - :members: - -claimstore.core ---------------- - -.. automodule:: claimstore.core - :members: - -claimstore.core.json -~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: claimstore.core.json - :members: - -claimstore.core.datetime -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: claimstore.core.datetime - :members: - -claimstore.core.exception -~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: claimstore.core.exception - :members: - -claimstore.core.db -~~~~~~~~~~~~~~~~~~ - -.. automodule:: claimstore.core.db - :members: - -claimstore.core.db.types -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: claimstore.core.db.types - :members: - -claimstore.ext --------------- - -.. automodule:: claimstore.ext - :members: - -claimstore.ext.collect -~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: claimstore.ext.collect - :members: - -claimstore.ext.sqlalchemy -~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: claimstore.ext.sqlalchemy - :members: - -claimstore.modules ------------------- - -.. automodule:: claimstore.modules - :members: - -claimstore.modules.claims -~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: claimstore.modules.claims - :members: - -claimstore.modules.claims.fixtures -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: claimstore.modules.claims.fixtures - :members: - -claimstore.modules.claims.fixtures.claim -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: claimstore.modules.claims.fixtures.claim - :members: - -claimstore.modules.claims.fixtures.claimant -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: claimstore.modules.claims.fixtures.claimant - :members: - -claimstore.modules.claims.fixtures.predicate -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: claimstore.modules.claims.fixtures.predicate - :members: - -claimstore.modules.claims.cli -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: claimstore.modules.claims.cli - :members: - -claimstore.modules.claims.models -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: claimstore.modules.claims.models - :members: - -claimstore.modules.claims.restful -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: claimstore.modules.claims.restful - :members: - -claimstore.modules.claims.views -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: claimstore.modules.claims.views - :members: - -claimstore.version ------------------- - -.. automodule:: claimstore.version - :members: - -claimstore.wsgi ---------------- - -.. automodule:: claimstore.wsgi - :members: diff --git a/docs/api/claimstore.app.rst b/docs/api/claimstore.app.rst new file mode 100644 index 0000000..8fa06a9 --- /dev/null +++ b/docs/api/claimstore.app.rst @@ -0,0 +1,7 @@ +claimstore.app module +===================== + +.. automodule:: claimstore.app + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.cli.rst b/docs/api/claimstore.cli.rst new file mode 100644 index 0000000..8c02d9a --- /dev/null +++ b/docs/api/claimstore.cli.rst @@ -0,0 +1,7 @@ +claimstore.cli module +===================== + +.. automodule:: claimstore.cli + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.config.rst b/docs/api/claimstore.config.rst new file mode 100644 index 0000000..41c14f1 --- /dev/null +++ b/docs/api/claimstore.config.rst @@ -0,0 +1,7 @@ +claimstore.config module +======================== + +.. automodule:: claimstore.config + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.core.datetime.rst b/docs/api/claimstore.core.datetime.rst new file mode 100644 index 0000000..18b812e --- /dev/null +++ b/docs/api/claimstore.core.datetime.rst @@ -0,0 +1,7 @@ +claimstore.core.datetime module +=============================== + +.. automodule:: claimstore.core.datetime + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.core.db.rst b/docs/api/claimstore.core.db.rst new file mode 100644 index 0000000..e0a5c50 --- /dev/null +++ b/docs/api/claimstore.core.db.rst @@ -0,0 +1,17 @@ +claimstore.core.db package +========================== + +Submodules +---------- + +.. toctree:: + + claimstore.core.db.types + +Module contents +--------------- + +.. automodule:: claimstore.core.db + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.core.db.types.rst b/docs/api/claimstore.core.db.types.rst new file mode 100644 index 0000000..7bae1ae --- /dev/null +++ b/docs/api/claimstore.core.db.types.rst @@ -0,0 +1,7 @@ +claimstore.core.db.types module +=============================== + +.. automodule:: claimstore.core.db.types + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.core.exception.rst b/docs/api/claimstore.core.exception.rst new file mode 100644 index 0000000..86a75f3 --- /dev/null +++ b/docs/api/claimstore.core.exception.rst @@ -0,0 +1,7 @@ +claimstore.core.exception module +================================ + +.. automodule:: claimstore.core.exception + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.core.json.rst b/docs/api/claimstore.core.json.rst new file mode 100644 index 0000000..b4205a8 --- /dev/null +++ b/docs/api/claimstore.core.json.rst @@ -0,0 +1,7 @@ +claimstore.core.json module +=========================== + +.. automodule:: claimstore.core.json + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.core.rst b/docs/api/claimstore.core.rst new file mode 100644 index 0000000..6ee611c --- /dev/null +++ b/docs/api/claimstore.core.rst @@ -0,0 +1,26 @@ +claimstore.core package +======================= + +Subpackages +----------- + +.. toctree:: + + claimstore.core.db + +Submodules +---------- + +.. toctree:: + + claimstore.core.datetime + claimstore.core.exception + claimstore.core.json + +Module contents +--------------- + +.. automodule:: claimstore.core + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.ext.collect.rst b/docs/api/claimstore.ext.collect.rst new file mode 100644 index 0000000..fbed7c4 --- /dev/null +++ b/docs/api/claimstore.ext.collect.rst @@ -0,0 +1,7 @@ +claimstore.ext.collect module +============================= + +.. automodule:: claimstore.ext.collect + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.ext.rst b/docs/api/claimstore.ext.rst new file mode 100644 index 0000000..ea3dd51 --- /dev/null +++ b/docs/api/claimstore.ext.rst @@ -0,0 +1,18 @@ +claimstore.ext package +====================== + +Submodules +---------- + +.. toctree:: + + claimstore.ext.collect + claimstore.ext.sqlalchemy + +Module contents +--------------- + +.. automodule:: claimstore.ext + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.ext.sqlalchemy.rst b/docs/api/claimstore.ext.sqlalchemy.rst new file mode 100644 index 0000000..5751e51 --- /dev/null +++ b/docs/api/claimstore.ext.sqlalchemy.rst @@ -0,0 +1,7 @@ +claimstore.ext.sqlalchemy module +================================ + +.. automodule:: claimstore.ext.sqlalchemy + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.modules.claims.cli.rst b/docs/api/claimstore.modules.claims.cli.rst new file mode 100644 index 0000000..58e0e83 --- /dev/null +++ b/docs/api/claimstore.modules.claims.cli.rst @@ -0,0 +1,7 @@ +claimstore.modules.claims.cli module +==================================== + +.. automodule:: claimstore.modules.claims.cli + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.modules.claims.config.rst b/docs/api/claimstore.modules.claims.config.rst new file mode 100644 index 0000000..68dd221 --- /dev/null +++ b/docs/api/claimstore.modules.claims.config.rst @@ -0,0 +1,7 @@ +claimstore.modules.claims.config module +======================================= + +.. automodule:: claimstore.modules.claims.config + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.modules.claims.models.rst b/docs/api/claimstore.modules.claims.models.rst new file mode 100644 index 0000000..81f04ff --- /dev/null +++ b/docs/api/claimstore.modules.claims.models.rst @@ -0,0 +1,7 @@ +claimstore.modules.claims.models module +======================================= + +.. automodule:: claimstore.modules.claims.models + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.modules.claims.restful.rst b/docs/api/claimstore.modules.claims.restful.rst new file mode 100644 index 0000000..a17acb8 --- /dev/null +++ b/docs/api/claimstore.modules.claims.restful.rst @@ -0,0 +1,7 @@ +claimstore.modules.claims.restful module +======================================== + +.. automodule:: claimstore.modules.claims.restful + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.modules.claims.rst b/docs/api/claimstore.modules.claims.rst new file mode 100644 index 0000000..18da5fb --- /dev/null +++ b/docs/api/claimstore.modules.claims.rst @@ -0,0 +1,21 @@ +claimstore.modules.claims package +================================= + +Submodules +---------- + +.. toctree:: + + claimstore.modules.claims.cli + claimstore.modules.claims.config + claimstore.modules.claims.models + claimstore.modules.claims.restful + claimstore.modules.claims.views + +Module contents +--------------- + +.. automodule:: claimstore.modules.claims + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.modules.claims.views.rst b/docs/api/claimstore.modules.claims.views.rst new file mode 100644 index 0000000..d8b051f --- /dev/null +++ b/docs/api/claimstore.modules.claims.views.rst @@ -0,0 +1,7 @@ +claimstore.modules.claims.views module +====================================== + +.. automodule:: claimstore.modules.claims.views + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.modules.rst b/docs/api/claimstore.modules.rst new file mode 100644 index 0000000..25bc73e --- /dev/null +++ b/docs/api/claimstore.modules.rst @@ -0,0 +1,17 @@ +claimstore.modules package +========================== + +Subpackages +----------- + +.. toctree:: + + claimstore.modules.claims + +Module contents +--------------- + +.. automodule:: claimstore.modules + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.rst b/docs/api/claimstore.rst new file mode 100644 index 0000000..2f0de18 --- /dev/null +++ b/docs/api/claimstore.rst @@ -0,0 +1,30 @@ +claimstore package +================== + +Subpackages +----------- + +.. toctree:: + + claimstore.core + claimstore.ext + claimstore.modules + +Submodules +---------- + +.. toctree:: + + claimstore.app + claimstore.cli + claimstore.config + claimstore.version + claimstore.wsgi + +Module contents +--------------- + +.. automodule:: claimstore + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.version.rst b/docs/api/claimstore.version.rst new file mode 100644 index 0000000..a64e068 --- /dev/null +++ b/docs/api/claimstore.version.rst @@ -0,0 +1,7 @@ +claimstore.version module +========================= + +.. automodule:: claimstore.version + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/claimstore.wsgi.rst b/docs/api/claimstore.wsgi.rst new file mode 100644 index 0000000..6f59394 --- /dev/null +++ b/docs/api/claimstore.wsgi.rst @@ -0,0 +1,7 @@ +claimstore.wsgi module +====================== + +.. automodule:: claimstore.wsgi + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/modules.rst b/docs/api/modules.rst new file mode 100644 index 0000000..a9389ad --- /dev/null +++ b/docs/api/modules.rst @@ -0,0 +1,7 @@ +claimstore +========== + +.. toctree:: + :maxdepth: 4 + + claimstore diff --git a/docs/conf.py b/docs/conf.py index 9c05370..1c111cb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -32,6 +32,7 @@ 'sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.coverage', + 'sphinxcontrib.httpdomain', ] # Add any paths that contain templates here, relative to this directory. @@ -102,7 +103,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'alabaster' +html_theme = 'sphinx_rtd_theme' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -260,3 +261,20 @@ # If true, do not generate a @detailmenu in the "Top" node's menu. #texinfo_no_detailmenu = False + + +# Extenstion to generate simple docstrings from a given method +from sphinx.ext import autodoc + +class SimpleDocumenter(autodoc.MethodDocumenter): + objtype = "simple" + + #do not indent the content + content_indent = "" + + #do not add a header to the docstring + def add_directive_header(self, sig): + pass + +def setup(app): + app.add_autodocumenter(SimpleDocumenter) diff --git a/docs/description.rst b/docs/description.rst index 7a02782..85066ba 100644 --- a/docs/description.rst +++ b/docs/description.rst @@ -1,3 +1,4 @@ +----------- Description ----------- diff --git a/docs/design.rst b/docs/design.rst index 60bab34..36ed6d9 100644 --- a/docs/design.rst +++ b/docs/design.rst @@ -1,3 +1,4 @@ +------ Design ------ diff --git a/docs/developers.rst b/docs/developers.rst index 727aa98..e474ea7 100644 --- a/docs/developers.rst +++ b/docs/developers.rst @@ -1,3 +1,4 @@ +---------- Developers ---------- diff --git a/docs/index.rst b/docs/index.rst index dfcb419..fc7135a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -23,45 +23,19 @@ The driving idea behind ClaimStore is to offer a neutral micro-service that would be (1) storing claims that various collaborating services perform and (2) answering questions about claims. -Description -=========== +Table of contents +================= .. toctree:: - :maxdepth: 2 + :maxdepth: 1 + :numbered: description - -Design -====== - -.. toctree:: - :maxdepth: 2 - design - -Releases -======== - -.. toctree:: - :maxdepth: 2 - releases - -API -=== - -.. toctree:: - :maxdepth: 2 - - api - -Developers -========== - -.. toctree:: - :maxdepth: 2 - + Users developers + API Indices and tables ================== diff --git a/docs/releases.rst b/docs/releases.rst index 49fd4c5..3a90ca7 100644 --- a/docs/releases.rst +++ b/docs/releases.rst @@ -1,3 +1,4 @@ +-------- Releases -------- diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..c38e6ce --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +Flask +sphinxcontrib.httpdomain diff --git a/docs/users.rst b/docs/users.rst new file mode 100644 index 0000000..2998c7c --- /dev/null +++ b/docs/users.rst @@ -0,0 +1,188 @@ +----------------- +Restful Resources +----------------- + + +Subscribe to ClaimStore +======================= + +.. autosimple:: claimstore.modules.claims.restful.ClaimantResource.post + +**Usage**: + +* From python: + + .. sourcecode:: python + + import json + import requests + + url = "http://localhost:5000/subscribe/ + headers = {"Content-Type": "application/json"} + with open( + '$PROJECT_HOME/tests/config/claimants/cds.json' + ) as f: + data=json.dumps(f.read()) + r = requests.post(url, data=data, headers=headers) + +* From `httpie `_: + + .. sourcecode:: bash + + $http POST http://localhost:5000/subscribe < tests/myclaimstore/config/claimants/cds.json + +* From cURL: + + .. sourcecode:: bash + + $curl http://localhost:5000/subscribe -H "Content-Type: application/json" -d @tests/myclaimstore/config/claimants/inspire.json -X POST -v + + + +Submit a claim +============== + +.. autosimple:: claimstore.modules.claims.restful.ClaimResource.post + +**Usage**: + +* From python: + + .. sourcecode:: python + + import json + import requests + + url = "http://localhost:5000/claims/ + headers = {"Content-Type": "application/json"} + with open( + '$PROJECT_HOME/tests/config/claims/cds.1.json' + ) as f: + data=json.dumps(f.read()) + r = requests.post(url, data=data, headers=headers) + +* From `httpie `_: + + .. sourcecode:: bash + + $http POST http://localhost:5000/claims < tests/myclaimstore/data/claims/cds.1.json + +* From cURL: + + .. sourcecode:: bash + + $curl http://localhost:5000/claims -H "Content-Type: application/json" -d @tests/myclaimstore/data/claims/inspire.1.json -X POST -v + + +List claims +=========== + +.. autosimple:: claimstore.modules.claims.restful.ClaimResource.get + +**Usage**: + +* From python: + + .. sourcecode:: python + + import requests + response = requests.get("http://localhost:5000/claims") + print response.json() + +* From `httpie `_: + + .. sourcecode:: bash + + $http GET http://localhost:5000/claims + +* From cURL: + + .. sourcecode:: bash + + $curl http://localhost:5000/claims + + +List identifiers +================ + +.. autosimple:: claimstore.modules.claims.restful.IdentifierResource.get + +**Usage**: + +* From python: + + .. sourcecode:: python + + import requests + response = requests.get("http://localhost:5000/identifiers") + print response.json() + +* From `httpie `_: + + .. sourcecode:: bash + + $http GET http://localhost:5000/identifiers + +* From cURL: + + .. sourcecode:: bash + + $curl http://localhost:5000/identifiers + + +List predicates +=============== + +.. autosimple:: claimstore.modules.claims.restful.PredicateResource.get + +**Usage**: + +* From python: + + .. sourcecode:: python + + import requests + response = requests.get("http://localhost:5000/predicates") + print response.json() + +* From `httpie `_: + + .. sourcecode:: bash + + $http GET http://localhost:5000/predicates + +* From cURL: + + .. sourcecode:: bash + + $curl http://localhost:5000/predicates + + +List equivalent identifiers +=========================== + +.. autosimple:: claimstore.modules.claims.restful.EquivalentIdResource.get + +**Usage**: + +* From python: + + .. sourcecode:: python + + import requests + response = requests.get("http://localhost:5000/eqids") + print response.json() + +* From `httpie `_: + + .. sourcecode:: bash + + $http GET http://localhost:5000/eqids + +* From cURL: + + .. sourcecode:: bash + + $curl http://localhost:5000/eqids + + diff --git a/run-tests.sh b/run-tests.sh index a8d9639..749a30b 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -18,6 +18,12 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, # USA. +sphinx-apidoc -f -e -o docs/api/ claimstore +if [ -n "$(git status -s)" ]; then + echo + echo "ERROR: there is a mismatch between sphinx-apidoc output and the actual content of docs/api/. Check 'git status'." + exit 1 +fi sphinx-build -qnNW docs docs/_build/html python setup.py test sphinx-build -qnNW -b doctest docs docs/_build/doctest diff --git a/setup.py b/setup.py index 849f1b7..a652b5d 100644 --- a/setup.py +++ b/setup.py @@ -112,7 +112,11 @@ def run_tests(self): ], extras_require={ 'development': ['Flask-DebugToolbar'], - 'docs': ['shpinx'], + 'docs': [ + 'shpinx', + 'sphinx_rtd_theme>=0.1.7', + 'sphinxcontrib.httpdomain' + ], }, tests_require=tests_require, cmdclass={'test': PyTest}, diff --git a/tests/myclaimstore/data/claims/claim.cds.1.json b/tests/myclaimstore/data/claims/cds.1.json similarity index 100% rename from tests/myclaimstore/data/claims/claim.cds.1.json rename to tests/myclaimstore/data/claims/cds.1.json diff --git a/tests/myclaimstore/data/claims/claim.inspire.1.json b/tests/myclaimstore/data/claims/inspire.1.json similarity index 100% rename from tests/myclaimstore/data/claims/claim.inspire.1.json rename to tests/myclaimstore/data/claims/inspire.1.json diff --git a/tests/myclaimstore/data/claims/claim.inspire.2.json b/tests/myclaimstore/data/claims/inspire.2.json similarity index 100% rename from tests/myclaimstore/data/claims/claim.inspire.2.json rename to tests/myclaimstore/data/claims/inspire.2.json diff --git a/tests/test_restful_api.py b/tests/test_restful_api.py index 16c9364..9997256 100644 --- a/tests/test_restful_api.py +++ b/tests/test_restful_api.py @@ -214,3 +214,15 @@ def test_get_predicates(webtest_app): resp = webtest_app.get('/predicates') assert resp.status_code == 200 assert len(resp.json) == 5 + + +@populate_all +def test_get_eqids(webtest_app): + """Testing GET eqids api.""" + resp = webtest_app.get('/eqids') + assert resp.status_code == 200 + assert len(resp.json) == 2 + eqid = list(resp.json)[0] + resp = webtest_app.get('/eqids/{}'.format(eqid)) + assert resp.status_code == 200 + assert len(resp.json) == 1