def generateEntrypoint(api_doc: HydraDoc) -> None: """ Generates Entrypoint , Base Collection and Base Resource for the documentation :param api_doc: contains the Hydra Doc created """ api_doc.add_baseCollection() api_doc.add_baseResource() api_doc.gen_EntryPoint()
# Add the classes to the HydraDoc api_doc.add_supported_class(class_) api_doc.add_supported_class(class_3) api_doc.add_supported_class(class_2) api_doc.add_supported_class(class_1) api_doc.add_supported_class(class_1) # add the collection to the HydraDoc. api_doc.add_supported_collection(collection_1) api_doc.add_supported_collection(collection_2) # Other operations needed for the Doc # Creates the base Resource Class and adds it to the API Documentation api_doc.add_baseResource() # Creates the base Collection Class and adds it to the API Documentation api_doc.add_baseCollection() # Generates the EntryPoint object for the Doc using the Classes and Collections api_doc.gen_EntryPoint() # Generate the complete API Documentation doc = api_doc.generate( ) # type: Union[Dict[str, Any], str] # Returns the entire API Documentation as a Python dict if __name__ == "__main__": """Print the complete sample Doc in doc_writer_sample_output.py.""" import json dump = json.dumps(doc, indent=4, sort_keys=True) doc = '''"""Generated API Documentation sample using doc_writer_sample.py."""
def doc_gen(API, BASE_URL): """Generate API Doc for server.""" # Main API Doc api_doc = HydraDoc(API, "API Doc for the server side API", "API Documentation for the server side system", API, BASE_URL) # State Class state = HydraClass("State", "State", "Class for drone state objects") # Properties # Status include Active, Inactive, Off, Charging state.add_supported_prop( HydraClassProp("http://auto.schema.org/speed", "Speed", False, False, True)) state.add_supported_prop( HydraClassProp("http://schema.org/geo", "Position", False, False, True)) state.add_supported_prop( HydraClassProp("http://schema.org/Property", "Direction", False, False, True)) state.add_supported_prop( HydraClassProp("http://schema.org/fuelCapacity", "Battery", False, False, True)) state.add_supported_prop( HydraClassProp("https://schema.org/status", "Status", False, False, True)) state.add_supported_prop( HydraClassProp("http://schema.org/identifier", "DroneID", False, False, True)) state.add_supported_op( HydraClassOp("GetState", "GET", None, "vocab:State", [{ "statusCode": 404, "description": "State not found" }, { "statusCode": 200, "description": "State Returned" }])) # Drone Class drone = HydraClass("Drone", "Drone", "Class for a drone") # Properties drone.add_supported_prop( HydraClassProp("vocab:State", "State", False, False, True)) drone.add_supported_prop( HydraClassProp("http://schema.org/name", "name", False, False, True)) drone.add_supported_prop( HydraClassProp("http://schema.org/model", "model", False, False, True)) drone.add_supported_prop( HydraClassProp("http://auto.schema.org/speed", "MaxSpeed", False, False, True)) drone.add_supported_prop( HydraClassProp("http://schema.org/device", "Sensor", False, False, True)) # Operations # Drones will submit their state to the server at certain intervals or when some event happens drone.add_supported_op( HydraClassOp("SubmitDrone", "POST", "vocab:Drone", None, [{ "statusCode": 200, "description": "Drone updated" }])) drone.add_supported_op( HydraClassOp("UpdateDrone", "PUT", "vocab:Drone", None, [{ "statusCode": 200, "description": "Drone updated" }])) # Mechanics or GUI need to get the drone, it contains the state object of the drone already. drone.add_supported_op( HydraClassOp("GetDrone", "GET", None, "vocab:Drone", [{ "statusCode": 404, "description": "Drone not found" }, { "statusCode": 200, "description": "Drone Returned" }])) drone.add_supported_op( HydraClassOp("DeleteDrone", "DELETE", None, None, [{ "statusCode": 404, "description": "Drone not found" }, { "statusCode": 200, "description": "Drone successfully deleted." }])) # NOTE: Commands are stored in a collection. You may GET a command or you may DELETE it, there is not UPDATE. command = HydraClass("Command", "Command", "Class for drone commands") command.add_supported_prop( HydraClassProp("http://schema.org/identifier", "DroneID", False, False, True)) command.add_supported_prop( HydraClassProp("vocab:State", "State", False, False, True)) # Used by mechanics to get newly added commands command.add_supported_op( HydraClassOp("GetCommand", "GET", None, "vocab:Command", [{ "statusCode": 404, "description": "Command not found" }, { "statusCode": 200, "description": "Command Returned" }])) # Used by server to add new commands command.add_supported_op( HydraClassOp("AddCommand", "PUT", "vocab:Command", None, [{ "statusCode": 201, "description": "Command added" }])) # Data is stored as a collection. Each data object can be read. # New data added to the collection datastream = HydraClass("Datastream", "Datastream", "Class for a datastream entry") datastream.add_supported_prop( HydraClassProp("http://schema.org/QuantitativeValue", "Temperature", False, False, True)) datastream.add_supported_prop( HydraClassProp("http://schema.org/identifier", "DroneID", False, False, True)) datastream.add_supported_prop( HydraClassProp("http://schema.org/geo", "Position", False, False, True)) datastream.add_supported_op( HydraClassOp("ReadDatastream", "GET", None, "vocab:Datastream", [{ "statusCode": 404, "description": "Data not found" }, { "statusCode": 200, "description": "Data returned" }])) dronelog = HydraClass("DroneLog", "DroneLog", "Class for a drone log entry") dronelog.add_supported_prop( HydraClassProp("http://schema.org/identifier", "DroneID", False, False, True)) dronelog.add_supported_prop( HydraClassProp("http://schema.org/Text", "LogString", False, False, True)) dronelog.add_supported_op( HydraClassOp("ReadDroneLog", "GET", None, "vocab:DroneLog", [{ "statusCode": 404, "description": "DroneLog not found" }, { "statusCode": 200, "description": "DroneLog returned" }])) controllerlog = HydraClass("ControllerLog", "ControllerLog", "Class for a controller log entry") controllerlog.add_supported_prop( HydraClassProp("http://schema.org/Text", "LogString", False, False, True)) controllerlog.add_supported_prop( HydraClassProp("http://schema.org/identifier", "DroneID", False, False, True)) controllerlog.add_supported_op( HydraClassOp("ReadControllerLog", "GET", None, "vocab:ControllerLog", [{ "statusCode": 404, "description": "ControllerLog not found" }, { "statusCode": 200, "description": "ControllerLog returned" }])) httpapilog = HydraClass("HttpApiLog", "HttpApiLog", "Class for a http api log entry") httpapilog.add_supported_prop( HydraClassProp("http://schema.org/identifier", "Subject", False, False, True)) httpapilog.add_supported_prop( HydraClassProp("http://schema.org/Action", "Predicate", False, False, True)) httpapilog.add_supported_prop( HydraClassProp("http://schema.org/identifier", "Object", False, False, True)) httpapilog.add_supported_op( HydraClassOp("ReadHttpApiLog", "GET", None, "vocab:HttpApiLog", [{ "statusCode": 404, "description": "HttpApiLog not found" }, { "statusCode": 200, "description": "HttpApiLog returned" }])) # Single object representing the area of interest. No collections. location = HydraClass("Location", "Location", "Class for location of the central controller.", endpoint=True) # Using two positions to have a bounding box location.add_supported_prop( HydraClassProp("http://schema.org/geo", "Location", False, False, True)) # Allowing updation of the area of interest location.add_supported_op( HydraClassOp( "UpdateLocation", "POST", "vocab:Location", None, [{ "statusCode": 200, "description": "Controller location updated successfully." }])) location.add_supported_op( HydraClassOp( "AddLocation", "PUT", "vocab:Location", None, [{ "statusCode": 200, "description": "Controller location added successfully." }])) location.add_supported_op( HydraClassOp("GetLocation", "GET", None, "vocab:Location", [{ "statusCode": 404, "description": "Location of Controller not found." }, { "statusCode": 200, "description": "Location of controller returned." }])) message = HydraClass("Message", "Message", "Class for messages received by the GUI interface") message.add_supported_prop( HydraClassProp("http://schema.org/Text", "MessageString", False, False, True)) message.add_supported_op( HydraClassOp("GetMessage", "GET", None, "vocab:Message", [{ "statusCode": 404, "description": "Message not found" }, { "statusCode": 200, "description": "Message returned" }])) message.add_supported_op( HydraClassOp("DeleteMessage", "DELETE", None, None, [{ "statusCode": 404, "description": "Message not found" }, { "statusCode": 200, "description": "Message successfully deleted." }])) anomaly = HydraClass( "Anomaly", "Anomaly", "Class for Temperature anomalies that need to be confirmed") anomaly.add_supported_prop( HydraClassProp("vocab:Location", "Location", False, False, True)) anomaly.add_supported_prop( HydraClassProp("http://schema.org/identifier", "DroneID", False, False, True)) # Status of any anomaly can be ["Positive", "Negative", "Confirming", "To be confirmed"] anomaly.add_supported_prop( HydraClassProp("http://schema.org/eventStatus", "Status", False, False, True)) anomaly.add_supported_prop( HydraClassProp("http://schema.org/identifier", "AnomalyID", False, False, True)) anomaly.add_supported_op( HydraClassOp("GetAnomaly", "GET", None, "vocab:Anomaly", [{ "statusCode": 404, "description": "Anomaly not found" }, { "statusCode": 200, "description": "Anomaly returned" }])) anomaly.add_supported_op( HydraClassOp("AddAnomaly", "PUT", "vocab:Anomaly", None, [{ "statusCode": 200, "description": "Anomaly added successfully." }])) anomaly.add_supported_op( HydraClassOp("UpdateAnomaly", "POST", "vocab:Anomaly", None, [{ "statusCode": 201, "description": "Anomaly updated successfully." }])) anomaly.add_supported_op( HydraClassOp("DeleteAnomaly", "DELETE", None, None, [{ "statusCode": 404, "description": "Anomaly not found" }, { "statusCode": 200, "description": "Anomaly successfully deleted." }])) api_doc.add_supported_class(drone, collection=True) api_doc.add_supported_class(state, collection=True) api_doc.add_supported_class(datastream, collection=True) api_doc.add_supported_class(dronelog, collection=True) api_doc.add_supported_class(controllerlog, collection=True) api_doc.add_supported_class(httpapilog, collection=True) api_doc.add_supported_class(location, collection=False) api_doc.add_supported_class(command, collection=True) api_doc.add_supported_class(message, collection=True) api_doc.add_supported_class(anomaly, collection=True) api_doc.add_baseResource() api_doc.add_baseCollection() api_doc.gen_EntryPoint() return api_doc
class_2.add_supported_op(class_2_op2) class_2.add_supported_op(class_2_op3) class_2.add_supported_op(class_2_op4) class_1.add_supported_op(class_1_op1) # Add the classes to the HydraDoc api_doc.add_supported_class(class_, collection=True, collection_path="DcTest") api_doc.add_supported_class(class_3, collection=True, collection_path="EcTest") api_doc.add_supported_class(class_2, collection=False) api_doc.add_supported_class(class_1, collection=False) # NOTE: Using collection=True creates a HydraCollection for the class. # The name of the Collection is class_.title+"Collection" # The collection inherently supports GET and PUT operations # Other operations needed for the Doc api_doc.add_baseResource( ) # Creates the base Resource Class and adds it to the API Documentation # Creates the base Collection Class and adds it to the API Documentation api_doc.add_baseCollection() # Generates the EntryPoint object for the Doc using the Classes and Collections api_doc.gen_EntryPoint() # Generate the complete API Documentation doc = api_doc.generate( ) # type: Union[Dict[str, Any], str] # Returns the entire API Documentation as a Python dict if __name__ == "__main__": """Print the complete sample Doc in doc_writer_sample_output.py.""" import json dump = json.dumps(doc, indent=4, sort_keys=True) doc = '''"""Generated API Documentation sample using doc_writer_sample.py."""
def create_doc(doc: Dict[str, Any], HYDRUS_SERVER_URL: str = None, API_NAME: str = None) -> HydraDoc: """ Create the HydraDoc object from the API Documentation. :param doc: dictionary of hydra api doc :param HYDRUS_SERVER_URL: url of the hydrus server :param API_NAME: name of the api :return: instance of HydraDoc which server and agent can understand :raise SyntaxError: If the `doc` doesn't have an entry for `@id` , `@context`, `@type` key. """ # These keys must be there in the APIDOC: @context, @id, @type if not all(key in doc for key in ('@context', '@id', '@type')): raise SyntaxError( "Please make sure doc contains @context, @id and @type") _context = doc['@context'] base_url = '' entrypoint = '' doc_name = 'vocab' doc_url = '' _id = '' _entrypoint = '' _title = "The default title" _description = "This is the default description" _classes = [] _collections = [] _endpoints = [] _possible_status = [] _endpoint_class = [] _endpoint_collection = [] _non_endpoint_classes = [] expanded_doc = jsonld.expand(doc) for item in expanded_doc: _id = item['@id'] # Extract base_url, entrypoint and API name base_url = urlparse(_id).scheme + '//' + urlparse(_id).netloc entrypoint = _entrypoint doc_name = urlparse(_id).path.split('/')[-1] doc_url = DocUrl(HYDRUS_SERVER_URL, api_name=API_NAME, doc_name=doc_name).doc_url for entrypoint in item[hydra['entrypoint']]: _entrypoint = entrypoint['@id'] if hydra['title'] in item: for title in item[hydra['title']]: _title = title['@value'] if hydra['description'] in item: for description in item[hydra['description']]: _description = description['@value'] for classes in item[hydra['supportedClass']]: isCollection = False if hydra['manages'] in classes: isCollection = True _collections.append(classes) for supported_prop in classes[hydra['supportedProperty']]: for prop in supported_prop[hydra['property']]: if '@type' in prop: for prop_type in prop['@type']: if prop_type == hydra['Link']: # find the range of the link for resource_range in prop[rdfs['range']]: _endpoints.append( check_namespace(resource_range['@id'])) if not isCollection: _classes.append(classes) for status in item[hydra['possibleStatus']]: _possible_status.append(status) for classes in _classes: if classes['@id'] == hydra['Resource'] or classes['@id'] == hydra[ 'Collection']: continue endpoint = False if classes['@id'].find("EntryPoint") != -1: classes['@id'] = "{}{}".format(doc_url, "EntryPoint") else: classes['@id'] = check_namespace(classes['@id']) for endpoints in _endpoints: if classes['@id'] == endpoints: endpoint = True _endpoint_class.append(classes) if not endpoint: _non_endpoint_classes.append(classes) for collections in _collections: collections['@id'] = check_namespace(collections['@id']) for endpoints in _endpoints: if collections['@id'] == endpoints: _endpoint_collection.append(collections) # Main doc object if HYDRUS_SERVER_URL is not None and API_NAME is not None: apidoc = HydraDoc(API_NAME, _title, _description, API_NAME, HYDRUS_SERVER_URL, doc_name) else: apidoc = HydraDoc(entrypoint, _title, _description, entrypoint, base_url, doc_name) # additional context entries for entry in _context: apidoc.add_to_context(entry, _context[entry]) # make endpoint classes for endpoint_classes in _endpoint_class: if endpoint_classes['@id'] == hydra['Resource'] or endpoint_classes['@id'] == hydra['Collection'] or \ endpoint_classes['@id'].find("EntryPoint") != -1: continue class_ = create_class(endpoint_classes, endpoint=True) apidoc.add_supported_class(class_) # make non-endpoint classes for classes in _non_endpoint_classes: if classes['@id'] == hydra['Resource'] or classes['@id'] == hydra['Collection'] or \ classes['@id'].find("EntryPoint") != -1: continue class_ = create_class(classes, endpoint=False) apidoc.add_supported_class(class_) # make endpoint collections for endpoint_collection in _endpoint_collection: collection_ = create_collection(endpoint_collection) apidoc.add_supported_collection(collection_) # add possibleStatus status_list = create_status(_possible_status) for status in status_list: apidoc.add_possible_status(status) # add base collection and resource apidoc.add_baseResource() apidoc.add_baseCollection() apidoc.gen_EntryPoint() return apidoc
def create_doc(doc: Dict[str, Any], HYDRUS_SERVER_URL: str = None, API_NAME: str = None) -> HydraDoc: """Create the HydraDoc object from the API Documentation. Raises: SyntaxError: If the `doc` doesn't have an entry for `@id` key. SyntaxError: If the `@id` key of the `doc` is not of the form : '[protocol] :// [base url] / [entrypoint] / vocab' """ # Check @id try: id_ = doc["@id"] except KeyError: raise SyntaxError("The API Documentation must have [@id]") # Extract base_url, entrypoint and API name match_obj = re.match(r'(.*)://(.*)/(.*)/vocab#?', id_, re.M | re.I) if match_obj: base_url = "{0}://{1}/".format(match_obj.group(1), match_obj.group(2)) entrypoint = match_obj.group(3) # Syntax checks else: raise SyntaxError( "The '@id' of the Documentation must be of the form:\n" "'[protocol] :// [base url] / [entrypoint] / vocab'") doc_keys = { "description": False, "title": False, "supportedClass": False, "@context": False, "possibleStatus": False } result = {} for k, literal in doc_keys.items(): result[k] = input_key_check(doc, k, "doc", literal) # EntryPoint object # getEntrypoint checks if all classes have @id entrypoint_obj = get_entrypoint(doc) # Main doc object if HYDRUS_SERVER_URL is not None and API_NAME is not None: apidoc = HydraDoc(API_NAME, result["title"], result["description"], API_NAME, HYDRUS_SERVER_URL) else: apidoc = HydraDoc(entrypoint, result["title"], result["description"], entrypoint, base_url) # additional context entries for entry in result["@context"]: apidoc.add_to_context(entry, result["@context"][entry]) # add all parsed_classes for class_ in result["supportedClass"]: class_obj, collection, collection_path = create_class( entrypoint_obj, class_) if class_obj: apidoc.add_supported_class(class_obj, collection=collection, collection_path=collection_path) # add possibleStatus for status in result["possibleStatus"]: status_obj = create_status(status) apidoc.add_possible_status(status_obj) apidoc.add_baseResource() apidoc.add_baseCollection() apidoc.gen_EntryPoint() return apidoc
def doc_gen(API: str, BASE_URL: str) -> HydraDoc: """Generate API Doc for server.""" # Main API Doc api_doc = HydraDoc(API, "API Doc for the server side API", "API Documentation for the server side system", API, BASE_URL) # State Class state = HydraClass("State", "State", "Class for drone state objects") # Properties state.add_supported_prop( HydraClassProp("http://auto.schema.org/speed", "Speed", False, False, True)) state.add_supported_prop( HydraClassProp("http://schema.org/geo", "Position", False, False, True)) state.add_supported_prop( HydraClassProp("http://schema.org/Property", "Direction", False, False, True)) state.add_supported_prop( HydraClassProp("http://schema.org/fuelCapacity", "Battery", False, False, True)) state.add_supported_prop( HydraClassProp("https://schema.org/status", "SensorStatus", False, False, True)) state.add_supported_prop( HydraClassProp("http://schema.org/identifier", "DroneID", False, False, True)) # Operations state.add_supported_op( HydraClassOp("GetState", "GET", None, "vocab:State", [{ "statusCode": 404, "description": "State not found" }, { "statusCode": 200, "description": "State Returned" }])) # Drone Class drone = HydraClass("Drone", "Drone", "Class for a drone") # Properties drone.add_supported_prop( HydraClassProp("vocab:State", "DroneState", False, False, True)) drone.add_supported_prop( HydraClassProp("http://schema.org/name", "name", False, False, True)) drone.add_supported_prop( HydraClassProp("http://schema.org/model", "model", False, False, True)) drone.add_supported_prop( HydraClassProp("http://auto.schema.org/speed", "MaxSpeed", False, False, True)) drone.add_supported_prop( HydraClassProp("http://schema.org/device", "Sensor", False, False, True)) # Operations # Drones will submit their state to the server at certain intervals or # when some event happens drone.add_supported_op( HydraClassOp("SubmitDrone", "POST", "vocab:Drone", None, [{ "statusCode": 200, "description": "Drone updated" }])) drone.add_supported_op( HydraClassOp("CreateDrone", "PUT", "vocab:Drone", None, [{ "statusCode": 200, "description": "Drone added" }])) drone.add_supported_op( HydraClassOp("GetDrone", "GET", None, "vocab:Drone", [{ "statusCode": 404, "description": "Drone not found" }, { "statusCode": 200, "description": "Drone Returned" }])) # NOTE: Commands are stored in a collection. You may GET a command or you # may DELETE it, there is not UPDATE. command = HydraClass("Command", "Command", "Class for drone commands") command.add_supported_prop( HydraClassProp("http://schema.org/identifier", "DroneID", False, False, True)) command.add_supported_prop( HydraClassProp("vocab:State", "State", False, False, True)) # Used by mechanics to get newly added commands command.add_supported_op( HydraClassOp("GetCommand", "GET", None, "vocab:Command", [{ "statusCode": 404, "description": "Command not found" }, { "statusCode": 200, "description": "Command Returned" }])) # Used by server to add new commands command.add_supported_op( HydraClassOp("AddCommand", "PUT", "vocab:Command", None, [{ "statusCode": 201, "description": "Command added" }])) command.add_supported_op( HydraClassOp("DeleteCommand", "DELETE", None, None, [{ "statusCode": 201, "description": "Command deleted" }])) # Logs to be accessed mostly by the GUI. Mechanics should add logs for # every event. log = HydraClass("LogEntry", "LogEntry", "Class for a log entry") # Subject log.add_supported_prop( HydraClassProp("http://schema.org/identifier", "DroneID", True, True, False)) # Predicate log.add_supported_prop( HydraClassProp("http://schema.org/UpdateAction", "Update", False, True, False)) log.add_supported_prop( HydraClassProp("http://schema.org/ReplyAction", "Get", False, True, False)) log.add_supported_prop( HydraClassProp("http://schema.org/SendAction", "Send", False, True, False)) # Objects log.add_supported_prop( HydraClassProp("vocab:State", "State", False, True, False)) log.add_supported_prop( HydraClassProp("vocab:Datastream", "Data", False, True, False)) log.add_supported_prop( HydraClassProp("vocab:Command", "Command", False, True, False)) # GUI will get a certain log entry. log.add_supported_op( HydraClassOp("GetLog", "GET", None, "vocab:LogEntry", [{ "statusCode": 404, "description": "Log entry not found" }, { "statusCode": 200, "description": "Log entry returned" }])) log.add_supported_op( HydraClassOp("AddLog", "PUT", "vocab:LogEntry", None, [{ "statusCode": 201, "description": "Log entry created" }])) # Data is stored as a collection. Each data object can be read. # New data added to the collection datastream = HydraClass("Datastream", "Datastream", "Class for a datastream entry") datastream.add_supported_prop( HydraClassProp("http://schema.org/QuantitativeValue", "Temperature", False, False, True)) datastream.add_supported_prop( HydraClassProp("http://schema.org/identifier", "DroneID", False, False, True)) datastream.add_supported_prop( HydraClassProp("http://schema.org/geo", "Position", False, False, True)) datastream.add_supported_op( HydraClassOp("ReadDatastream", "GET", None, "vocab:Datastream", [{ "statusCode": 404, "description": "Data not found" }, { "statusCode": 200, "description": "Data returned" }])) datastream.add_supported_op( HydraClassOp("UpdateDatastream", "POST", "vocab:Datastream", None, [{ "statusCode": 200, "description": "Data updated" }])) datastream.add_supported_op( HydraClassOp("DeleteDatastream", "DELETE", None, None, [{ "statusCode": 200, "description": "Data deleted" }])) # Single object representing the area of interest. No collections. area = HydraClass("Area", "Area", "Class for Area of Interest of the server", endpoint=True) # Using two positions to have a bounding box area.add_supported_prop( HydraClassProp("http://schema.org/geo", "TopLeft", False, False, True)) area.add_supported_prop( HydraClassProp("http://schema.org/geo", "BottomRight", False, False, True)) # Allowing updation of the area of interest area.add_supported_op( HydraClassOp("UpdateArea", "POST", "vocab:Area", None, [{ "statusCode": 200, "description": "Area of interest changed" }])) area.add_supported_op( HydraClassOp("GetArea", "GET", None, "vocab:Area", [{ "statusCode": 404, "description": "Area of interest not found" }, { "statusCode": 200, "description": "Area of interest returned" }])) message = HydraClass("Message", "Message", "Class for messages received by the GUI interface") message.add_supported_prop( HydraClassProp("http://schema.org/Text", "MessageString", False, False, True)) message.add_supported_op( HydraClassOp("GetMessage", "GET", None, "vocab:Message", [{ "statusCode": 404, "description": "Message not found" }, { "statusCode": 200, "description": "Message returned" }])) message.add_supported_op( HydraClassOp("DeleteMessage", "DELETE", None, None, [{ "statusCode": 200, "description": "Message deleted" }])) api_doc.add_supported_class(drone, collection=True) api_doc.add_supported_class(state, collection=True) api_doc.add_supported_class(datastream, collection=True) api_doc.add_supported_class(log, collection=True) api_doc.add_supported_class(area, collection=False) api_doc.add_supported_class(command, collection=True) api_doc.add_supported_class(message, collection=True) api_doc.add_baseResource() api_doc.add_baseCollection() api_doc.gen_EntryPoint() return api_doc
def doc_gen(API, BASE_URL): """Generate API Doc for drone.""" # Main API Doc api_doc = HydraDoc(API, "API Doc for the drone side API", "API Documentation for the drone side system", API, BASE_URL) # State Class # NOTE: Each drone will have only one State Class, this can't be deleted. Only read and update. state = HydraClass("State", "State", "Class for drone state objects") # Properties state.add_supported_prop(HydraClassProp( "http://auto.schema.org/speed", "Speed", True, False, False)) state.add_supported_prop(HydraClassProp( "http://schema.org/geo", "Position", True, False, False)) state.add_supported_prop(HydraClassProp( "http://schema.org/Property", "Direction", True, False, False)) state.add_supported_prop(HydraClassProp( "http://schema.org/fuelCapacity", "Battery", True, True, False)) state.add_supported_prop(HydraClassProp( "https://schema.org/status", "Status", True, False, False)) # Drone Class # NOTE: The actual changes to the drone are to be made at the /api/Drone URI. # GET will return current State. POST will update the State. drone = HydraClass("Drone", "Drone", "Class for a drone", endpoint=True) # Properties drone.add_supported_prop(HydraClassProp( "vocab:State", "State", False, False, True)) drone.add_supported_prop(HydraClassProp( "http://schema.org/name", "name", False, False, True)) drone.add_supported_prop(HydraClassProp( "http://schema.org/model", "model", False, False, True)) drone.add_supported_prop(HydraClassProp( "http://auto.schema.org/speed", "MaxSpeed", False, False, True)) drone.add_supported_prop(HydraClassProp( "http://schema.org/device", "Sensor", False, False, True)) drone.add_supported_prop(HydraClassProp( "http://schema.org/identifier", "DroneID", False, False, True)) # Operations drone.add_supported_op(HydraClassOp("GetDrone", "GET", None, "vocab:Drone", [{"statusCode": 404, "description": "Drone not found"}, {"statusCode": 200, "description": "Drone returned"}])) # When new commands are issued, mechanics will need to change the state of the drone drone.add_supported_op(HydraClassOp("UpdateDrone", "POST", "vocab:Drone", None, [{"statusCode": 200, "description": "Drone updated"}])) drone.add_supported_op(HydraClassOp("AddDrone", "PUT", "vocab:Drone", None, [{"statusCode": 200, "description": "Drone added"}])) # Command Class # NOTE: Commands are stored in a collection. You may GET a command or you may DELETE it, there is not UPDATE. command = HydraClass("Command", "Command", "Class for drone commands") command.add_supported_prop(HydraClassProp( "http://schema.org/identifier", "DroneID", False, False, True)) command.add_supported_prop(HydraClassProp( "vocab:State", "State", False, False, True)) # Used by mechanics to get newly added commands command.add_supported_op(HydraClassOp("GetCommand", "GET", None, "vocab:Command", [{"statusCode": 404, "description": "Command not found"}, {"statusCode": 200, "description": "Command Returned"}])) # Used by server to add new commands command.add_supported_op(HydraClassOp("AddCommand", "PUT", "vocab:Command", None, [{"statusCode": 201, "description": "Command added"}])) # Used by mechanics to delete command after it has been executed command.add_supported_op(HydraClassOp("DeleteCommand", "DELETE", None, None, [{"statusCode": 200, "description": "Command deleted"}])) # Datastream class # NOTE: This is for the Datastream to be captured/generated. The mechanics module will enter random data and POST it. # The server will read[GET] the data when it needs it. No need for collections. Only one instance showing current reading of sensor # The URI is /api/Datastream datastream = HydraClass("Datastream", "Datastream", "Class for a data entry from drone sensors", endpoint=True) datastream.add_supported_prop(HydraClassProp( "http://schema.org/QuantitativeValue", "Temperature", False, False, True)) datastream.add_supported_prop(HydraClassProp( "http://schema.org/identifier", "DroneID", False, False, True)) datastream.add_supported_prop(HydraClassProp( "http://schema.org/geo", "Position", False, False, True)) datastream.add_supported_op(HydraClassOp("GetDatastream", "GET", None, "vocab:Datastream", [{"statusCode": 404, "description": "Datastream not found"}, {"statusCode": 200, "description": "Datastream returned"}])) datastream.add_supported_op(HydraClassOp("UpdateDatastream", "POST", "vocab:Datastream", None, [{"statusCode": 200, "description": "Datastream updated"}])) datastream.add_supported_op(HydraClassOp("AddDatastream", "PUT", "vocab:Datastream", None, [{"statusCode": 200, "description": "Datastream added"}])) anomaly = HydraClass( "Anomaly", "Anomaly", "Class for Temperature anomalies that need to be confirmed", endpoint=True) anomaly.add_supported_prop(HydraClassProp( "vocab:Location", "Location", False, False, True)) anomaly.add_supported_prop(HydraClassProp( "http://schema.org/identifier", "DroneID", False, False, True)) # Status of any anomaly can be ["Positive", "Negative", "Confirming"] anomaly.add_supported_prop(HydraClassProp( "http://schema.org/eventStatus", "Status", False, False, True)) anomaly.add_supported_prop(HydraClassProp( "http://schema.org/identifier", "AnomalyID", False, False, True)) anomaly.add_supported_op(HydraClassOp("GetAnomaly", "GET", None, "vocab:Anomaly", [{"statusCode": 404, "description": "Anomaly not found"}, {"statusCode": 200, "description": "Anomaly returned"}])) anomaly.add_supported_op(HydraClassOp("AddAnomaly", "PUT", "vocab:Anomaly", None, [{"statusCode": 201, "description": "Anomaly added successfully"}])) anomaly.add_supported_op(HydraClassOp("UpdateAnomaly", "POST", "vocab:Anomaly", None, [{"statusCode": 201, "description": "Anomaly updated successfully"}])) api_doc.add_supported_class(state, collection=False) api_doc.add_supported_class(drone, collection=False) api_doc.add_supported_class(command, collection=True) api_doc.add_supported_class(datastream, collection=False) api_doc.add_supported_class(anomaly, collection=False) api_doc.add_baseCollection() api_doc.add_baseResource() api_doc.gen_EntryPoint() return api_doc