Skip to content
This repository has been archived by the owner on Feb 17, 2022. It is now read-only.

Commit

Permalink
docs: enriched docstrings
Browse files Browse the repository at this point in the history
* Enriches docstrings globally. (closes #37)

Signed-off-by: Jose Benito Gonzalez Lopez <jose.benito.gonzalez@cern.ch>
  • Loading branch information
jbenito3 committed Aug 31, 2015
1 parent 89a5fe3 commit ba5f0ce
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 16 deletions.
2 changes: 1 addition & 1 deletion claimstore/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@


def handle_restful_exceptions(error):
"""Handle invalid usage exception."""
"""Handle invalid restful request exception."""
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
Expand Down
2 changes: 2 additions & 0 deletions claimstore/core/datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ def loc_date_utc(date):
"""Localise a naive date in UTC.
:param date: naive date
:type date: datetime.
:returns: date with UTC tzinfo
:rtype: datetime.
"""
return pytz.utc.localize(date)
17 changes: 13 additions & 4 deletions claimstore/core/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,16 @@ class RestApiException(Exception):

status_code = 400

def __init__(self, message, status_code=None, payload=None, details=None):
"""Initialise the exception."""
def __init__(self, message, status_code=None, details=None):
"""Initialise the exception.
:param message: Exception message.
:type message: str.
:param status_code: HTTP status code. By default it is 400.
:type status_code: int.
:param details: Extra details of the exception.
:type details: str.
"""
Exception.__init__(self)
self.message = message
if status_code is not None:
Expand All @@ -50,14 +58,15 @@ class InvalidJSONData(RestApiException):

"""Invalid JSON Data.
Used to identify that JSON data that do not follow the appropiate schema.
This exception is raised when there is some JSON data that does not follow
its associated JSON schema.
"""

pass


class InvalidRequest(RestApiException):

"""The REST request could not be fulfilled."""
"""REST request could not be fulfilled."""

pass
9 changes: 7 additions & 2 deletions claimstore/core/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ def get_json_schema(schema):
:param schema: schema to be fetched. It must be a string with the format:
module.schema_name (e.g. claims.claimants).
:return: a str with the requested json schema.
:type schema: str.
:returns: a str with the requested json schema.
:rtype: str.
"""
module_name, schema_name = schema.split(".")
schema_file_path = os.path.join(
Expand All @@ -53,9 +55,12 @@ def validate_json(json_input, schema):
"""Validate JSON against a given schema.
:param json_input: a dict with the full json to be validated.
:type json_input: dict.
:param schema: JSON schema to use in the validation. It must be a string
with the format module.schema_name (e.g. claims.claimants).
:return: True if json_input follows the schema. False otherwise.
:type schema: str.
:returns: True if `json_input` follows the schema. False otherwise.
:rtype: bool.
"""
if schema:
schema_content = get_json_schema(schema)
Expand Down
85 changes: 80 additions & 5 deletions claimstore/modules/claims/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,63 +31,96 @@

class Claim(db.Model):

"""Represents a Claim."""
"""Model representing a Claim.
Each claim is associated to a specific Claimant and references some already
existing Identifier Types and predicate.
"""

id = db.Column(
db.Integer,
primary_key=True
)
"""Unique id of the claim."""

uuid = db.Column(
UUID,
nullable=False,
unique=True,
default=lambda: str(uuid4())
)
"""Universally Unique Identifier that represents a single claim."""

received = db.Column(
UTCDateTime,
default=now_utc,
nullable=False
)
"""Datetime in which the claim has been received and stored."""

created = db.Column(
UTCDateTime,
nullable=False
)
"""Datetime in which the claim has been created by the claimant."""

claimant_id = db.Column(
db.Integer,
db.ForeignKey('claimant.id'),
nullable=False
)
"""Id of the associated Claimant."""

subject_type_id = db.Column(
db.Integer,
db.ForeignKey('identifier_type.id'),
nullable=False
)
"""Id of the associated IdentifierType used as a subject."""

subject_value = db.Column(
db.String,
nullable=False
)
"""Value of the subject."""

predicate_id = db.Column(
db.Integer,
db.ForeignKey('predicate.id'),
nullable=False
)
"""Id of the associated Predicate."""

certainty = db.Column(
db.Float,
nullable=False
)
"""Certainty of the claim. It must be a float between 0 and 1.0."""

human = db.Column(db.Integer)
"""Whether the claims has been done by a human (1) or not (0)."""

actor = db.Column(db.String)
"""`Human` that has performed the claim."""

role = db.Column(db.String)
"""Role of the `human` who has performed the claim."""

object_type_id = db.Column(
db.Integer,
db.ForeignKey('identifier_type.id'),
nullable=False
)
"""Id of the associated IdentifierType used as an object."""

object_value = db.Column(
db.String,
nullable=False
)
"""Value of the object."""

claim_details = db.Column(JSONB)
"""JSONB representation of the full claim as received."""

def __repr__(self):
"""Printable version of the Claim object."""
Expand All @@ -96,36 +129,50 @@ def __repr__(self):

class Claimant(db.Model):

"""Represents a Claimant."""
"""Represents a Claimant.
Claimants are the main providers of claims. Each claimant may be associated
to many different claims.
"""

id = db.Column(
db.Integer,
primary_key=True,
)
"""Unique id of the claimant."""

uuid = db.Column(
UUID(),
nullable=False,
unique=True,
default=lambda: str(uuid4()),
)
"""Universally unique id of the claimant."""

joined = db.Column(
UTCDateTime,
default=now_utc,
)
"""Datetime when the claimant subscribed to ClaimStore."""

name = db.Column(
db.String,
nullable=False,
unique=True,
index=True
)
"""Claimant name. It must be unique and preferably short."""

url = db.Column(db.String)
"""URL of the claimant."""

claim = db.relationship(
'Claim',
backref='claimant',
cascade="all, delete-orphan",
lazy='dynamic'
)
"""Claim associated with this claimant."""

def __repr__(self):
"""Printable version of the Claimant object."""
Expand All @@ -134,35 +181,55 @@ def __repr__(self):

class IdentifierType(db.Model):

"""Represents an identifier type."""
"""Represents an identifier type.
An Identifier Type is a persistent identifier type that can be used in
claims by claimants.
"""

id = db.Column(
db.Integer,
primary_key=True
)
"""Unique id of the Identifier."""

id = db.Column(db.Integer, primary_key=True)
name = db.Column(
db.String,
nullable=False,
unique=True,
index=True
)
"""Unique name of the identifier type. Preferably one word in caps."""

description = db.Column(
db.String,
nullable=False
)
"""Description of the identifier type."""

url = db.Column(
db.String,
nullable=False
)
"""URL in which the identifier is used."""

example_value = db.Column(
db.String,
nullable=False
)
"""Example of a possible value for an identifier."""

example_url = db.Column(
db.String,
nullable=False
)
"""Example of a full URL in which the identifier is being used."""

claimant_id = db.Column(
db.Integer,
db.ForeignKey('claimant.id')
)
"""Id of the associated claimant that registered this identifier."""

def __repr__(self):
"""Printable version of the IdentifierType object."""
Expand All @@ -177,19 +244,27 @@ class Predicate(db.Model):
is_same_as.
"""

id = db.Column(db.Integer, primary_key=True)
id = db.Column(
db.Integer,
primary_key=True
)
"""Unique id of the predicate."""

name = db.Column(
db.String,
nullable=False,
unique=True,
index=True
)
"""Unique name of a predicate."""

claim = db.relationship(
'Claim',
backref='predicate',
cascade="all, delete-orphan",
lazy='dynamic'
)
"""Claim associated with this predicate."""

def __repr__(self):
"""Printable version of the Predicate object."""
Expand Down
43 changes: 40 additions & 3 deletions claimstore/modules/claims/restful.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ class ClaimStoreResource(Resource):
json_schema = None

def validate_json(self, json_data):
"""Validate that json_data follows the appropiate JSON schema."""
"""Validate that json_data follows the appropiate JSON schema.
:param json_data: JSON data to be validated.
:raises: InvalidJSONData
"""
try:
validate_json(json_data, self.json_schema)
except Exception as e:
Expand All @@ -65,7 +69,11 @@ class Subscription(ClaimStoreResource):
json_schema = 'claims.claimant'

def post(self):
"""Process post request."""
"""Subscribe a new claimant.
Receives JSON data with all the information of a new claimant and it
stores it in the database.
"""
json_data = request.get_json()
self.validate_json(json_data)
if not Claimant.query.filter_by(name=json_data['name']).first():
Expand Down Expand Up @@ -243,7 +251,36 @@ def post(self):
return {'status': 'success', 'uuid': new_claim.uuid}

def get(self):
"""GET service that returns the stored claims."""
"""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.
"""
args = self.get_claims_parser.parse_args()
if all(x is None for x in args.values()): # Avoid false positives (0)
claims = Claim.query.all()
Expand Down
2 changes: 1 addition & 1 deletion claimstore/modules/claims/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def subscription():

@blueprint.route('/api', methods=['GET'])
def api():
"""Render the api documenation page."""
"""Render the API documenation page."""
return render_template("api.html", active_menu='api')


Expand Down

0 comments on commit ba5f0ce

Please sign in to comment.