REST API

The Rest API currently resides in the module: hgraph.adaptors.tornado

Rest describes a standard pattern for exposing a web based API. This considers managing a data object that has a unique id. The data object is represented as a JSON value. The id is a string value.

The following operations are possible:

list

Returns a list of valid id’s

read

Returns the value for a given id

create

Creates a new instance of the data object for a given id, the id MUST NOT already exist in the collection.

update

Modifies the data object associated to the given id, the id MUST already exist in the collection.

delete

Removes the id associated to the collection.

Both a client API and a service implementation API are provided. The client API requires the service to follow the standard REST patterns for implementing these services. The client API is not required to be used when implementing the server API. The server API exposes the behaviours using a REST compliant web API.

Client API

The client API is below, to make use of the client API, the web client must be registered. This can be done by including a call to register_rest_client. The graph must be run in REAL_TIME mode for this to work.

rest_list(base_url: TS[str]) TS[RestListResponse][source]

Lists the ids available in the rest server, this is a once off operation. To force a refresh, re-tick the URL.

This is performed by sending a GET request to the rest server with the base_url provided.

Parameters:

base_url (TimeSeriesValueInput[str]) – The base url of the rest server, e.g. http://localhost:8080/my_cs/v1/cs/

Return type:

TimeSeriesValueInput[RestListResponse]

Returns:

TS[RestListResponse] contains ids property, which is a tuple of the ids available in the rest server.

rest_read(base_url: TS[str], id_: TS[str], value_type: type[COMPOUND_SCALAR]) TS[RestReadResponse][source]

Requests the value associated with the id from the rest server. This is a once off operation. To force a refresh, re-tick the id_.

This performs a GET request to the rest server with the id_ provided. The request is sent to url/id_.

Parameters:
Return type:

TimeSeriesValueInput[RestReadResponse]

Returns:

TS[RestReadResponse[value_type]] The response will contain the id and value properties.

rest_create(base_url: TS[str], id_: TS[str], value: TS[COMPOUND_SCALAR]) TS[RestCreateResponse][source]

Requests the value to be created using the id_ provided.

This converts the value to json and then performs a POST request to the rest server with content of {'id': id_, 'value': value}.

Parameters:
Return type:

TimeSeriesValueInput[RestCreateResponse]

Returns:

The response indicating if the status is OK or not.

rest_update(base_url: TS[str], id_: TS[str], value: TS[COMPOUND_SCALAR]) TS[RestUpdateResponse][source]

Requests the value to be updated using the id_ provided.

This converts the value to json and then performs a PUT request to the rest server using the URL of url/id_ and the body content being the json representation of the value.

Parameters:
Return type:

TimeSeriesValueInput[RestUpdateResponse]

Returns:

The response indicating if the status is OK or not.

rest_delete(base_url: TS[str], id_: TS[str]) TS[RestDeleteResponse][source]

Requests the id_ to be deleted.

This sends a DELETE request to the rest server using the URL of url/id_.

Parameters:
Return type:

TimeSeriesValueInput[RestDeleteResponse]

Returns:

The response indicating if the status is OK or not.

Service API

The server API makes use of a handler pattern, where the user is responsible for writing a handler function and wrapping it with the @rest_handler decorator. This decorator takes the relative URL for the end-point and the type of the data-object to be managed. The register_http_server_adaptor needs to be called to register the server process. Finally, the graph must be run in REAL_TIME mode for this to work.

rest_handler(fn: Callable = None, *, url: str, data_type: type[COMPOUND_SCALAR])[source]

A rest handler wraps a function of the form:

@rest_handler(url="http://example.com/my_cs", data_type=MyCS)
def my_fn(request: TS[RestRequest[MyCS]) -> TS[RestResponse[MyCS]]:
    ...

The function is responsible for handling individual requests and producing the appropriate responses. If the component requires full visibility to the full set of requests, then it is possible for the multiplexed signature to be used:

@rest_handler(url="http://example.com/my_cs", data_type=MyCS)
def my_fn(request: TSD[int, TS[RestRequest[MyCS]]) -> TSD[int, TS[RestResponse[MyCS]]]:
    ...

To enable the rest handler, the register_http_server_adaptor should be called to set up the processes web-service process.

Note

The rest handler is self registering, once declared and imported nothing else needs to be done.

There are a number of request objects that can be received, this allows logic to make use of the dispatch mechanism to process incoming requests. The requests are:

class RestRequest(url: str)[source]

Marker class for all rest operations

class RestCreateRequest(url: str, id: str, value: COMPOUND_SCALAR)[source]

The value associated to the id should be created

class RestUpdateRequest(url: str, id: str, value: COMPOUND_SCALAR)[source]

The value associated to the id should be updated

class RestReadRequest(url: str, id: str)[source]

The id is requested to have it’s value returned

class RestDeleteRequest(url: str, id: str)[source]

The id is requested to be removed

class RestListRequest(url: str)[source]

No attributes provided

The response makes use of an enum for indicating the result.

class RestResultEnum(*values)[source]

With the response class’ being:

class RestResponse(status: hgraph.adaptors.tornado._rest_handler.RestResultEnum, reason: str = '')[source]
class RestCreateResponse(status: RestResultEnum, reason: str = '', id: str = None, value: COMPOUND_SCALAR = None)[source]

The status property should be set as follows:

  • If successfully created, this should set the status to CREATED.

  • If the value already exists, this should be set to CONFLICT.

  • If the attempt fails due to a validation error, this should be set to BAD_REQUEST.

  • The user is not authorised, this should be set to UNAUTHORIZED

  • If the task cannot be completed, this should be set to FORBIDDEN.

The value is returned when the value is modified during the construction process. The id will always be provided if the value is created.

class RestUpdateResponse(status: RestResultEnum, reason: str = '', id: str = None, value: COMPOUND_SCALAR = None)[source]

The status property should be set as follows:

  • If successfully updated, this should set the status to OK if the value is going to be returned or NO_CONTENT if no value is to be returned.

  • If the content is not found, this should be set to NOT_FOUND.

  • If the attempt fails due to a validation error, this should be set to BAD_REQUEST.

  • The user is not authorised, this should be set to UNAUTHORIZED

  • If the task cannot be completed, this should be set to FORBIDDEN.

The id and value should be set when the value is modified during the update process.

class RestReadResponse(status: RestResultEnum, reason: str = '', id: str = None, value: COMPOUND_SCALAR = None)[source]

The status property should be set as follows:

  • If found, this should be set to OK.

  • If the content is not found, this should be set to NOT_FOUND.

  • The user is not authorised, this should be set to UNAUTHORIZED

  • If the task cannot be completed, this should be set to FORBIDDEN.

The id and value are returned if found.

class RestDeleteResponse(status: RestResultEnum, reason: str = '')[source]

The status property should be set as follows:

  • If successfully deleted, this should set the status to NO_CONTENT.

  • If the content is not found, this should be set to NOT_FOUND.

  • The user is not authorised, this should be set to UNAUTHORIZED

  • If the task cannot be completed, this should be set to FORBIDDEN.

class RestListResponse(status: RestResultEnum, reason: str = '', ids: tuple[str, ...] = ())[source]

Returns the list of id’s available.

The status property should be set as follows:

  • If the operation is successfully performed, this should set the status to OK.

  • The user is not authorised, this should be set to UNAUTHORIZED

  • If the task cannot be completed, this should be set to FORBIDDEN.