Welcome to hydra-python-core’s documentation!¶
The core library is
used heavily in both hydrus
and agent. The core library has mainly two modules. The doc_writer
and doc_maker
module.
doc_writer¶
The doc_writer module contains the implementation of Hydra specification classes, which are the core building pieces of any Hydra powered REST APIs. The classes can be found at http://www.hydra-cg.com/spec/latest/core/#classes. These classes are used to build the APIDOC from scratch. To see how we can generate APIDOC from scratch, please refer this. The mapping of hydra classes and implementation of doc_writer is given below:
Hydra Class |
class name in doc_writer |
---|---|
HydraClassProp, HydraCollectionProp |
|
HydraStatus |
|
HydraClassOp, HydraCollectionOp |
|
IriTemplateMapping |
|
HydraLink |
|
HydraError |
|
HydraCollection |
|
HydraDoc |
|
HydraClass |
HydraEntryPoint class is the template for the entrypoint
. Entrypoint
is the location from where the agent discovers all the possible
locations it can go to. The hydrus
uses the get
method of this
class to generate the entrypoint of the API.
doc_maker¶
The doc_maker module is used to parse existing JSON-LD Hydra based APIDOC. It throws error, if anything is not spec compliant. It uses the JSON-LD expansion algorithm before parsing the apidoc. The benefit this expansion provides over processing raw apidoc is the flexibility of parsing the IRIs. Some authors prefer expanded IRIs, some use compacted IRIs and some use mixture of both. So, to correctly able to parse all the IRIs we expand the IRIs and thus start parsing the doc after coming to the same page. This allows us to parse even more variety of apidocs. Then the small parsing engine traverses through entire doc and extracts classes, collections, links, property and status by calling appropriate methods of this doc_maker module.
Also another use case of doc_maker is to update the IRIs once the doc
is generated by doc_writer. For example, if the server url changes, or
api name changes, the changes can be reflected in the entire APIDOC by
passing the doc to the create_doc
method of the doc_maker with the
updated parameters.
The doc_maker has following methods:
create_doc - To parse the doc or to update the doc according to new params.
create_collection - To parse the collection in HydraCollection of doc_writer
create_class - To parse classes in HydraClass of doc_writer
create_operation - To parse supported_operations in HydraClassOp
create_status - To parse the status in HydraStatus
create_property - To parse the supported properties in HydraClassProp
create_link - To parse properties referencing other class or collection in HydraLink
check_namespace - To check if the url provided is in the correct namespace.
Usage¶
Create a new API Documentation and a new HydraDoc object¶
The doc_writer can be used to create an API Doc itself as defined below: The first step is to create a new HydraDoc object
1 2 3 4 5 6 7 8 9 10 11 12 13 | from hydra_python_core.doc_writer import HydraDoc
# Creating the HydraDoc object, this is the primary class for the Doc
API_NAME = "api" # Name of the API, will serve as EntryPoint
BASE_URL = "http://hydrus.com/" # The base url at which the API is hosted
# NOTE: The API will be accessible at BASE_URL + ENTRY_POINT
# (http://hydrus.com/api)
# Create ApiDoc Object
api_doc = HydraDoc(API_NAME,
"Title for the API Documentation",
"Description for the API Documentation",
API_NAME,
BASE_URL,
"vocab") # vocab is the name of vocabulary
|
The API Documentation has been created, but it is not yet complete. Classes, properties, and operations must be added to the Doc.
1 2 3 4 5 | from hydra_python_core.doc_writer import HydraClass
# Creating classes for the API
class_title = "dummyClass" # Title of the Class
class_description = "A dummyClass for demo" # Description of the class
class_ = HydraClass(class_title, class_description, endpoint=False)
|
Classes need to have properties that allow them to store information related to the class. Similar to attributes in a Python class, these are stored as supportedProperty of the HydraClass. Properties are defined as HydraClassProp objects:
1 2 3 4 5 6 7 | from hydra_python_core.doc_writer import HydraClassProp
# Create new properties for the class
# The URI of the class of the property
prop1_uri = "http://props.hydrus.com/prop1"
prop1_title = "Prop1" # Title of the property
dummyProp1 = HydraClassProp(prop1_uri, prop1_title,
required=False, read=False, write=True)
|
Besides these properties, classes also need to have operations that can modify the data stored within their instances. These operation are defined as HydraClassOp and are stored in supportedOperation of the HydraClass
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | from hydra_python_core.doc_writer import HydraClassOp, HydraStatus
# Create operations for the class
op_name = "UpdateClass" # The name of the operation
op_method = "POST" # The method of the Operation [GET, POST, PUT, DELETE]
# URI of the object that is expected for the operation
op_expects = class_.id_
op_returns = None # URI of the object that is returned by the operation
op_returns_header = ["Content-Type", "Content-Length"]
op_expects_header = []
# List of statusCode for the operation
op_status = [HydraStatus(code=200, desc="dummyClass updated.")]
op1 = HydraClassOp(op_name,
op_method,
op_expects,
op_returns,
op_expects_header,
op_returns_header,
op_status)
|
Once the classes and properties have been defined, add them to the class.
1 2 | class_.add_supported_prop(dummyProp1)
class_.add_supported_op(op1)
|
After defining a class along with its properties and operations, add this class to the APIDocumentation.
1 | api_doc.add_supported_class(class_)
|
We can also define a collection in the same we defined class. A collection is the set of somehow related resource
1 2 3 4 5 6 7 8 9 10 11 12 13 | from hydra_python_core.doc_writer import HydraCollection
collection2_title = "dummyClass collection"
collection2_name = "dummyclasses"
collection2_description = "This collection comprises of instances of dummyClass"
# A manages block is a way to declare additional, implicit statements about members of a collection.
# Here we are defining that all the members of this collection is of type class_.
collection2_managed_by = {
"property": "rdf:type",
"object": class_.id_,
}
collection_2 = HydraCollection(collection_name=collection2_name,
collection_description=collection2_description, manages=collection2_managed_by, get=True,
post=True, collection_path="DcTest")
|
Now we add this collection to the HydraDoc object.
1 2 | # add the collection to the HydraDoc.
api_doc.add_supported_collection(collection_2)
|
Other than this, an API Documentation also needs to have the Resource and the Collection classes, so that the server can identify the class members. This can be done automatically using the add_baseResource and add_baseCollection methods.
1 2 3 | # Other operations
api_doc.add_baseResource() # Creates the base Resource Class and adds it to the API Documentation
api_doc.add_baseCollection() # Creates the base Collection Class and adds it to the API Documentation
|
Finally, create the EntryPoint object for the API Documentation. All Collections are automatically assigned endpoints in the EntryPoint object. Classes that had their endpoint variables set to True are also assigned endpoints in the EntryPoint object. This object is created automatically by the HydraDoc object and can be created using the gen_EntryPoint method.
1 | api_doc.gen_EntryPoint() # Generates the EntryPoint object for the Doc using the Classes and Collections
|
The final API Documentation can be viewed by calling the generate method which returns a Python dictionary containing the entire API Documentation. The generate method can be called for every class defined in the doc_writer module to generate its own Python dictionary.
1 | doc = api_doc.generate()
|
The complete script for this API Documentation can be found in samples/doc_writer_sample.py
, and the generated ApiDocumentation can be found in samples/doc_writer_sample_output.py
.
Use an existing API Documentation to create a new HydraDoc object¶
If there is an existing apidoc in JSON-LD, to work with the tools of Hydra Ecosystem it needs to be converted in HydraDoc object.
Any existing doc can be converted in HydraDoc by simply calling the create_doc
method of doc_maker
module.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # Sample to convert the API Doc into doc_writer classes
from hydra_python_core.doc_maker import create_doc
# Note: It would be better to use json.loads from the python json library to create 'doc'
doc = {
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
"@id": "http://api.example.com/doc/",
"@type": "ApiDocumentation",
"title": "The name of the API",
"description": "A short description of the API",
"entrypoint": "URL of the API's main entry point",
"supportedClass": [
# ... Classes known to be supported by the Web API ...
],
"possibleStatus": [
# ... Statuses that should be expected and handled properly ...
]
}
APIDoc = create_doc(doc)
|
doc_writer¶
API Doc templates generator.
-
class
hydra_python_core.doc_writer.
Context
(address: str, class_: Optional[hydra_python_core.doc_writer.HydraClass] = None, collection: Optional[hydra_python_core.doc_writer.HydraCollection] = None, entrypoint: Optional[hydra_python_core.doc_writer.HydraEntryPoint] = None)¶ Class for JSON-LD context.
-
add
(key: str, value: Union[Dict[str, str], str]) → None¶ Add entry to context.
-
createContext
(object_: Dict[str, Any]) → None¶ Create the context for the given object.
-
generate
() → Dict[str, Any]¶ Get as a python dict.
-
-
class
hydra_python_core.doc_writer.
EntryPointClass
(class_: hydra_python_core.doc_writer.HydraClass)¶ Class for a Operation Entry to the EntryPoint object.
-
generate
() → Dict[str, Any]¶ Get as Python Dict.
-
-
class
hydra_python_core.doc_writer.
EntryPointCollection
(collection: hydra_python_core.doc_writer.HydraCollection)¶ Class for a Collection Entry to the EntryPoint object.
-
generate
() → Dict[str, Any]¶ Get as a python dict.
-
-
class
hydra_python_core.doc_writer.
EntryPointOp
(id_: str, method: str, desc: str, expects: Optional[str], returns: Optional[str], expects_header: List[str] = [], returns_header: List[str] = [], possible_status: List[Union[HydraStatus, HydraError]] = [], type_: Optional[str] = None, label: str = '')¶ supportedOperation for EntryPoint.
-
generate
() → Dict[str, Any]¶ Get as Python Dict.
-
get_type
(method: str) → str¶ Return @type for op based on method type.
-
-
class
hydra_python_core.doc_writer.
HydraClass
(title: str, desc: str, path: str = None, endpoint: bool = True, sub_classof: None = None, _id: str = None)¶ Template for a new class.
-
add_supported_op
(op: Union[EntryPointOp, HydraClassOp]) → None¶ Add a new supportedOperation.
- Raises:
TypeError: If op is not an instance of HydraClassOp or EntryPointOp
-
add_supported_prop
(prop: Union[HydraClassProp, EntryPointClass, EntryPointCollection]) → None¶ Add a new supportedProperty.
- Raises:
- TypeError: If prop is not an instance of HydraClassProp or EntryPointClass
or EntryPointCollection
-
generate
() → Dict[str, Any]¶ Get the Hydra class as a python dict.
-
-
class
hydra_python_core.doc_writer.
HydraClassOp
(title: str, method: str, expects: Optional[str], returns: Optional[str], expects_header: List[str] = [], returns_header: List[str] = [], possible_status: List[Union[HydraStatus, HydraError]] = [])¶ Template for a new supportedOperation.
-
generate
() → Dict[str, Any]¶ Get the Hydra op as a python dict.
-
get_type
(method: str) → str¶ Return @type for op based on method type.
-
-
class
hydra_python_core.doc_writer.
HydraClassProp
(prop: Union[str, HydraLink], title: str, read: bool, write: bool, required: bool, desc: str = '', **kwargs)¶ Template for a new property.
-
generate
() → Dict[str, Any]¶ Get the Hydra prop as a python dict.
-
-
class
hydra_python_core.doc_writer.
HydraCollection
(collection_name: str = None, collection_path: str = None, collection_description: str = None, manages: Union[Dict[str, Any], List] = None, get: bool = True, post: bool = True, put: bool = True, delete: bool = True)¶ Class for Hydra Collection.
-
generate
() → Dict[str, Any]¶ Get as a python dict.
-
-
class
hydra_python_core.doc_writer.
HydraCollectionOp
(id_: str, type_: str, method: str, desc: str, expects: Optional[str], returns: Optional[str], expects_header: List[str] = [], returns_header: List[str] = [], possible_status: List[Union[HydraStatus, HydraError]] = [])¶ Operation class for Collection operations.
-
generate
() → Dict[str, Any]¶ Get as a Python dict.
-
-
class
hydra_python_core.doc_writer.
HydraDoc
(API: str, title: str, desc: str, entrypoint: str, base_url: str, doc_name: str)¶ Class for an API Doc.
-
add_baseCollection
() → None¶ Add Collection class to the API Doc.
-
add_baseResource
() → None¶ Add Resource class to the API Doc.
-
add_possible_status
(status: Union[HydraStatus, HydraError]) → None¶ Add a new possibleStatus.
- Raises:
TypeError: If status is not an instance of HydraStatus.
-
add_supported_class
(class_: hydra_python_core.doc_writer.HydraClass) → None¶ Add a new supportedClass.
- Raises:
TypeError: If class_ is not an instance of HydraClass
-
add_supported_collection
(collection_: hydra_python_core.doc_writer.HydraCollection) → None¶ Add a supported Collection
- Raises:
TypeError: If collection_ is not an instance of HydraCollection
-
add_to_context
(key: str, value: Union[Dict[str, str], str]) → None¶ Add entries to the vocabs context.
-
gen_EntryPoint
() → None¶ Generate the EntryPoint for the Hydra Doc.
-
generate
() → Dict[str, Any]¶ Get the Hydra API Doc as a python dict.
-
-
class
hydra_python_core.doc_writer.
HydraEntryPoint
(base_url: str, entrypoint: str)¶ Template for a new entrypoint.
-
add_Class
(class_: hydra_python_core.doc_writer.HydraClass) → None¶ Add supportedProperty to the EntryPoint.
- Raises:
TypeError: If class_ is not an instance of HydraClass.
-
add_Collection
(collection: hydra_python_core.doc_writer.HydraCollection) → None¶ Add supportedProperty to the EntryPoint.
- Raises:
TypeError: If collection is not an instance of HydraCollection.
-
generate
() → Dict[str, Any]¶ Get as a Python dict.
-
get
() → Dict[str, str]¶ Create the EntryPoint object to be returnd for the get function.
-
-
class
hydra_python_core.doc_writer.
HydraError
(code: int, id_: str = None, title: str = '', desc: str = '')¶ Class for Hydra Error to represent error details.
-
generate
() → Dict[str, Any]¶ Get error response body
-
-
class
hydra_python_core.doc_writer.
HydraIriTemplate
(template: str, iri_mapping: List[hydra_python_core.doc_writer.IriTemplateMapping] = [], basic_representation: bool = True)¶ Class for hydra IriTemplates
-
generate
() → Dict[str, Any]¶ Get IriTemplate as a python dict
-
-
class
hydra_python_core.doc_writer.
HydraLink
(id_: str, title: str = '', desc: str = '', domain: str = '', range_: str = '')¶ Template for a link property.
-
add_supported_op
(op: Union[EntryPointOp, HydraClassOp]) → None¶ Add a new supportedOperation.
- Raises:
TypeError: If op is not an instance of HydraClassOp or EntryPointOp
-
generate
() → Dict[str, Any]¶ Get the Hydra link as a python dict.
-
doc_maker¶
Contsructor to take a Python dict containing an API Documentation and create a HydraDoc object for it
-
hydra_python_core.doc_maker.
check_namespace
(id_: str = None) → str¶ A helper method to check if the classes and properties are in the same namespace and if not bring them into the right namespace :param id_ The id to check :return: correct url
-
hydra_python_core.doc_maker.
create_class
(expanded_class: Dict[str, Any], endpoint: bool) → hydra_python_core.doc_writer.HydraClass¶ Creates HydraClass from the expanded API document;
- Parameters
apidoc – object of HydraDoc type
expanded_class – the expanded class
endpoint – boolean True if class is an endpoint, False if class is not endpoint
- Returns
HydraClass object that can be added to api doc
-
hydra_python_core.doc_maker.
create_collection
(endpoint_collection: Dict[str, Any]) → hydra_python_core.doc_writer.HydraCollection¶ Creates the instance of HydraCollection from expanded APIDOC
- Parameters
endpoint_collection – creates HydraCollection from expanded API doc
- Returns
instance of HydraCollection
-
hydra_python_core.doc_maker.
create_doc
(doc: Dict[str, Any], HYDRUS_SERVER_URL: str = None, API_NAME: str = None) → hydra_python_core.doc_writer.HydraDoc¶ Create the HydraDoc object from the API Documentation.
- Parameters
doc – dictionary of hydra api doc
HYDRUS_SERVER_URL – url of the hydrus server
API_NAME – name of the api
- Returns
instance of HydraDoc which server and agent can understand
- Raises
SyntaxError – If the doc doesn’t have an entry for @id , @context, @type key.
-
hydra_python_core.doc_maker.
create_link
(supported_property: Dict[str, Any]) → hydra_python_core.doc_writer.HydraLink¶ Creates the instances of HydraLink
- Parameters
supported_property – expanded Property
- Returns
instance of HydraLink
-
hydra_python_core.doc_maker.
create_operation
(supported_operation: Dict[str, Any]) → hydra_python_core.doc_writer.HydraClassOp¶ Creates the instance of HydraClassOp
- Parameters
supported_operation – The expanded supported operation from the API DOC
- Returns
HydraClassOp
-
hydra_python_core.doc_maker.
create_property
(supported_property: Dict[str, Any]) → Union[hydra_python_core.doc_writer.HydraLink, hydra_python_core.doc_writer.HydraClassProp]¶ Creates the HydraClassProp from the expanded supported property
- Parameters
supported_property – supported property dict from the expanded api doc
- Returns
HydraClassProp
-
hydra_python_core.doc_maker.
create_status
(possible_status: List[Any]) → List[hydra_python_core.doc_writer.HydraStatus]¶ Creates instance of HydraStatus from expanded API doc
- Parameters
possible_status – possible status from the expanded API doc
- Returns
List of instances of HydraStatus