Skip to content

Commit 6a00ee3

Browse files
authored
Merge pull request #53 from priyanshunayan/doc-update
Doc update
2 parents d3d61e9 + 0c44f19 commit 6a00ee3

File tree

2 files changed

+270
-3
lines changed

2 files changed

+270
-3
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# hydra-python-core
22
This library provides the core functions to implement Hydra Official Specification in Python.
33

4-
Currently the library mainly consists of 2 modules `doc_writer` and `doc_maker` which help hydrus generalise a lot of things.
4+
Currently the library mainly consists of 2 modules `doc_writer` and `doc_maker` which help hydrus generalise a lot of things. The documentation is available at
5+
https://hydra-python-core.readthedocs.io/en/develop/
56

67
-> `doc_writer` creates a new API Documentation as well as a `HydraDoc` object while,
7-
-> `doc_maker` uses an existing API Documentation to create a `HydraDoc` object c`
8+
-> `doc_maker` uses an existing API Documentation to create a `HydraDoc` object
89

910

1011

docs/source/index.rst

Lines changed: 267 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,274 @@
33
Welcome to hydra-python-core's documentation!
44
=============================================
55

6+
The `core library <https://github.com/HTTP-APIs/hydra-python-core>`__ is
7+
used heavily in both `hydrus <https://github.com/http-apis/hydrus>`__
8+
and agent. The core library has mainly two modules. The ``doc_writer``
9+
and ``doc_maker`` module.
10+
11+
doc\_writer
12+
-----------
13+
14+
The doc\_writer module contains the implementation of Hydra
15+
specification classes, which are the core building pieces of any Hydra
16+
powered REST APIs. The classes can be found at
17+
http://www.hydra-cg.com/spec/latest/core/#classes. These classes are used
18+
to build the APIDOC from scratch. To see how we can generate APIDOC from
19+
scratch, please refer
20+
`this <https://www.hydraecosystem.org/01-Usage#newdoc>`__. The mapping
21+
of hydra classes and implementation of doc\_writer is given below:
22+
23+
.. list-table:: Mapping
24+
:widths: 50 50
25+
:header-rows: 1
26+
27+
* - Hydra Class
28+
- class name in doc_writer
29+
* - hydra:SupportedProperty
30+
- HydraClassProp, HydraCollectionProp
31+
* - hydra:Status
32+
- HydraStatus
33+
* - hydra:Operation
34+
- HydraClassOp, HydraCollectionOp
35+
* - hydra:IriTemplateMapping
36+
- IriTemplateMapping
37+
* - hydra:Link
38+
- HydraLink
39+
* - hydra:Error
40+
- HydraError
41+
* - hydra:Collection
42+
- HydraCollection
43+
* - hydra:ApiDocumentation
44+
- HydraDoc
45+
* - hydra:Class
46+
- HydraClass
47+
48+
HydraEntryPoint class is the template for the ``entrypoint``. Entrypoint
49+
is the location from where the agent discovers all the possible
50+
locations it can go to. The ``hydrus`` uses the ``get`` method of this
51+
class to generate the entrypoint of the API.
52+
53+
doc\_maker
54+
----------
55+
56+
The doc\_maker module is used to parse existing JSON-LD Hydra based
57+
APIDOC. It throws error, if anything is not spec compliant. It uses the
58+
JSON-LD `expansion
59+
algorithm <https://json-ld.org/spec/latest/json-ld-api/#expansion>`__
60+
before parsing the apidoc. The benefit this expansion provides over
61+
processing raw apidoc is the flexibility of parsing the IRIs. Some
62+
authors prefer expanded IRIs, some use compacted IRIs and some use
63+
mixture of both. So, to correctly able to parse all the IRIs we expand
64+
the IRIs and thus start parsing the doc after coming to the same page.
65+
This allows us to parse even more variety of apidocs. Then the small
66+
parsing engine traverses through entire doc and extracts classes,
67+
collections, links, property and status by calling appropriate methods
68+
of this doc\_maker module.
69+
70+
Also another use case of doc\_maker is to update the IRIs once the doc
71+
is generated by doc\_writer. For example, if the server url changes, or
72+
api name changes, the changes can be reflected in the entire APIDOC by
73+
passing the doc to the ``create_doc`` method of the doc\_maker with the
74+
updated parameters.
75+
76+
The doc\_maker has following methods:
77+
78+
1. create\_doc - To parse the doc or to update the doc according to new
79+
params.
80+
2. create\_collection - To parse the collection in HydraCollection of
81+
doc\_writer
82+
3. create\_class - To parse classes in HydraClass of doc\_writer
83+
4. create\_operation - To parse supported\_operations in HydraClassOp
84+
5. create\_status - To parse the status in HydraStatus
85+
6. create\_property - To parse the supported properties in
86+
HydraClassProp
87+
7. create\_link - To parse properties referencing other class or
88+
collection in HydraLink
89+
8. check\_namespace - To check if the url provided is in the correct
90+
namespace.
91+
92+
93+
Usage
94+
--------
95+
96+
Create a new API Documentation and a new HydraDoc object
97+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
98+
The doc_writer can be used to create an API Doc itself as defined below:
99+
The first step is to create a new HydraDoc object
100+
101+
.. code-block:: python
102+
:linenos:
103+
104+
from hydra_python_core.doc_writer import HydraDoc
105+
# Creating the HydraDoc object, this is the primary class for the Doc
106+
API_NAME = "api" # Name of the API, will serve as EntryPoint
107+
BASE_URL = "http://hydrus.com/" # The base url at which the API is hosted
108+
# NOTE: The API will be accessible at BASE_URL + ENTRY_POINT
109+
# (http://hydrus.com/api)
110+
# Create ApiDoc Object
111+
api_doc = HydraDoc(API_NAME,
112+
"Title for the API Documentation",
113+
"Description for the API Documentation",
114+
API_NAME,
115+
BASE_URL,
116+
"vocab") # vocab is the name of vocabulary
117+
118+
119+
The API Documentation has been created, but it is not yet complete. Classes, properties, and operations must be added to the Doc.
120+
121+
.. code-block:: python
122+
:linenos:
123+
124+
from hydra_python_core.doc_writer import HydraDoc
125+
# Creating classes for the API
126+
class_title = "dummyClass" # Title of the Class
127+
class_description = "A dummyClass for demo" # Description of the class
128+
class_ = HydraClass(class_title, class_description, endpoint=False)
129+
130+
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:
131+
132+
.. code-block:: python
133+
:linenos:
134+
135+
from hydra_python_core.doc_writer import HydraClassProp
136+
# Create new properties for the class
137+
# The URI of the class of the property
138+
prop1_uri = "http://props.hydrus.com/prop1"
139+
prop1_title = "Prop1" # Title of the property
140+
dummyProp1 = HydraClassProp(prop1_uri, prop1_title,
141+
required=False, read=False, write=True)
142+
143+
144+
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
145+
146+
.. code-block:: python
147+
:linenos:
148+
149+
from hydra_python_core.doc_writer import HydraClassOp, HydraStatus
150+
151+
# Create operations for the class
152+
op_name = "UpdateClass" # The name of the operation
153+
op_method = "POST" # The method of the Operation [GET, POST, PUT, DELETE]
154+
# URI of the object that is expected for the operation
155+
op_expects = class_.id_
156+
op_returns = None # URI of the object that is returned by the operation
157+
op_returns_header = ["Content-Type", "Content-Length"]
158+
op_expects_header = []
159+
# List of statusCode for the operation
160+
op_status = [HydraStatus(code=200, desc="dummyClass updated.")]
161+
162+
op1 = HydraClassOp(op_name,
163+
op_method,
164+
op_expects,
165+
op_returns,
166+
op_expects_header,
167+
op_returns_header,
168+
op_status)
169+
170+
171+
Once the classes and properties have been defined, add them to the class.
172+
173+
.. code-block:: python
174+
:linenos:
175+
176+
class_.add_supported_prop(dummyProp1)
177+
class_.add_supported_op(op1)
178+
179+
After defining a class along with its properties and operations, add this class to the APIDocumentation.
180+
181+
.. code-block:: python
182+
:linenos:
183+
184+
api_doc.add_supported_class(class_)
185+
186+
We can also define a collection in the same we defined class. A collection is the set of somehow related resource
187+
188+
.. code-block:: python
189+
:linenos:
190+
191+
from hydra_python_core.doc_writer import HydraCollection
192+
collection2_title = "dummyClass collection"
193+
collection2_name = "dummyclasses"
194+
collection2_description = "This collection comprises of instances of dummyClass"
195+
# A manages block is a way to declare additional, implicit statements about members of a collection.
196+
# Here we are defining that all the members of this collection is of type class_.
197+
collection2_managed_by = {
198+
"property": "rdf:type",
199+
"object": class_.id_,
200+
}
201+
collection_2 = HydraCollection(collection_name=collection2_name,
202+
collection_description=collection2_description, manages=collection2_managed_by, get=True,
203+
post=True, collection_path="DcTest")
204+
205+
Now we add this collection to the HydraDoc object.
206+
207+
.. code-block:: python
208+
:linenos:
209+
210+
# add the collection to the HydraDoc.
211+
api_doc.add_supported_collection(collection_2)
212+
213+
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.
214+
215+
.. code-block:: python
216+
:linenos:
217+
218+
# Other operations
219+
apidoc.add_baseResource() # Creates the base Resource Class and adds it to the API Documentation
220+
apidoc.add_baseCollection() # Creates the base Collection Class and adds it to the API Documentation
221+
222+
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.
223+
224+
.. code-block:: python
225+
:linenos:
226+
227+
apidoc.gen_EntryPoint() # Generates the EntryPoint object for the Doc using the Classes and Collections
228+
229+
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.
230+
231+
.. code-block:: python
232+
:linenos:
233+
234+
doc = apidoc.generate()
235+
236+
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``.
237+
238+
239+
Use an existing API Documentation to create a new HydraDoc object
240+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
241+
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.
242+
Any existing doc can be converted in HydraDoc by simply calling the ``create_doc`` method of ``doc_maker`` module.
243+
244+
Example:
245+
246+
.. code-block:: python
247+
:linenos:
248+
249+
# Sample to convert the API Doc into doc_writer classes
250+
251+
from hydra_python_core.doc_maker import create_doc
252+
253+
# Note: It would be better to use json.loads from the python json library to create 'doc'
254+
doc = {
255+
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
256+
"@id": "http://api.example.com/doc/",
257+
"@type": "ApiDocumentation",
258+
"title": "The name of the API",
259+
"description": "A short description of the API",
260+
"entrypoint": "URL of the API's main entry point",
261+
"supportedClass": [
262+
# ... Classes known to be supported by the Web API ...
263+
],
264+
"possibleStatus": [
265+
# ... Statuses that should be expected and handled properly ...
266+
]
267+
}
268+
269+
APIDoc = create_doc(doc)
270+
271+
6272
.. toctree::
7-
:maxdepth: 2
273+
:maxdepth: 3
8274
:caption: Contents:
9275

10276
doc_writer

0 commit comments

Comments
 (0)