-
Notifications
You must be signed in to change notification settings - Fork 0
Oldstuff‐Usage
- Capabilities of the server
- Submitting requests and getting the results
- Connecting as a tenant providing data (intention-agnostic tenant)
- Posting results
The server has two endpoints that can provide information about what kinds of results the currently subscribed tenants are able to produce, as well as the limitations on the conditions in which they can work (min/max temperature, available chemicals, etc).
The first one is the /capabilities
endpoint. It contains the information that defines a methodology:
[
# There will be a list of objects, each with a different (quantity, method) pair,
# for describing the different capabilities of the server
{
"quantity": str,
# this is the name of the quantity
"method": str,
# this is the name of the method used to obtain the quantity
"json_schema_specifications": dict,
# this is a json schema that describes what the dictionary of parameters
# for the method should look like
"json_schema_result_output": dict,
# this is a json schema that describes what the output dictionary in the
# posted results should look like
}
]
Follow the instructions in this section, if your tenant shall be operated in an intention-agnostic way during the operation of the MAP. This applies to tenants providing experimental data as well as computational results.
Your tenant needs to provide the following abilities to be able to communicate with FINALES:
-
Login to FINALES
The tenant needs to be able to login to the server. The login is achieved using the\authenticate
endpoint of FINALES providing a username and password. For this to work, a user for the tenant needs to be registered beforehand following the instructions given in the section "User registration" of this Wiki. The call for logging in should read as follows:
access_information = requests.post(
(
f"http://<FINALES_host>:"
f"<FINALES_port>/user_management/authenticate/"
),
data={
"grant_type": "",
"username": f"<username>",
"password": f"<password>",
"scope": "",
"client_id": "",
"client_secret": "",
},
headers={
"accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded",
},
)
The information enclosed by <>
is provided to you by the server and user administrator.
Based on the output of this call, an autorization header needs to be assembled according to the following scheme:
access_information = access_information.json()
{
"accept": "application/json",
"Authorization": (
f"{access_information['token_type'].capitalize()} "
f"{access_information['access_token']}"
),
}
This Authorization header needs to be updated after each new login and must be provided to every endpoint. For examples on how to pass it on, please see the following code examples in this section.
An example of the use of this call in the context of a tenant can be found in the reference tenant. An example of how to assemble and use the authentication header can be found in the reference tenant.
-
Pull pending requests from FINALES
The pending requests may be pulled using the\get_pending_requests
endpoint. The endpoint allows to filter the pending requests for a quantity and method, which may be passed as parameters. This endpoint should be called repeatedly in a time interval. The tenant developer is free to define the interval for the requests. This interval is not predefined by FINALES. The call for getting pending requests should read as follows:
pendingRequests = requests.get(
f"http://<FINALES_host>"
f":<FINALES_port>/pending_requests/",
params={},
headers=<authorization_header>,
)
The <authorization_header>
is the one you created after the login.
An example of the use of this call in the context of a tenant can be found in the reference tenant.
-
Filter the requests
The tenant needs to be able to filter the requests obtained from the\get_pending_requests
endpoint to assure, that they correspond to its capabilities. This requires at least to check the request against the limitations of the tenant. If the prefiltering function of the endpoint is not used, filtering by the quantity and method is additionally required to be done by the tenant. -
Select request(s) to work on
Once the feasibility of a request is ensured, the tenant needs to select one or several requests to process. Whether requests are processed one by one or batchwise depends on the typical mode of operation of the tenant. - Processing the request In order to process a request, the tenant needs to provide a functionality to perform its method to produce the requested quantity based on the input schema as it was previously defined for the respective quantity and method in the schemas repository https://github.com/BIG-MAP/FINALES2_schemas.
Parts of these functionalities are provided in the Tenant
class defined in src/FINALES2/tenants/referenceTenant.py
. This class may be set up providing the following information:
-
general_meta: GeneralMetaData
This field comprises a name and a short description of the tenant. -
quantities: dict[str, Quantity]
This field lists all the quantities, which the tenant can deliver. TheQuantity
objects comprise a method for the respective quantity. -
sleep_time_s: int
This field defines the time interval, after which the tenant pulls the pending requests. -
tenant_config: Any
This field allows to provide information regarding the configuration of the tenant used for the current session. The form, in which the configuration is provided, is currently free to be selected by the developer. This field is thought to e.g. comprise an ID of a commit defining the version of the code. -
run_method: Callable
The method provided in this key is the one used by the tenant to run it's method. If the tenant provides several methods, this function needs to be parametrized to allow calling the same function for executing different methods. -
prepare_results: Callable
This field takes a function, which translates the output of the respectiverun_method
function to the format, which can be processed to FINALES. This means, this function needs to fit the output ofrun_method
into the output format secified fo the quantity and method in https://github.com/BIG-MAP/FINALES2_schemas. -
FINALES_server_config: ServerConfig
In this field, the information regarding FINALES is stored to define the host and port, to which the communication of the tenant needs to be addressed. -
end_run_time: Optional[datetime]
This field allows to define a time, after which the tenant does not collect further requests from the server and will not process any further requests. This may be used e.g. to implement working hours or schedule maintenance tasks like restocking consumables in experimental tenants. -
authorization_header: Optional[dict]
This field is auto-populated by the tenant upon login to FINALES and does not need to be provided by the developer when instantiating the tenant. -
operator: User
This field collects the user associated as the operator of the tenant. This should be a user associated with a human operator responsible for the tenant and should serve mainly to enable communication between the different operators in case of malfunctions of tenants. -
tenant_user: User
This field represents a user assigned for the tenant itself, which it uses to login for pulling requests and posting results. -
tenant_uuid: str
This ID is assigned to the tenant upon registration according to the instructions given in the section "Tenant registration" in this Wiki. This ID needs to be stored in this field to be able to add it to posted requests.
The reference tenant is currently implemented for intention-agnostic tenants providing experimental results only. It does (not yet) support posting requests to and retrieving results from FINALES.
After processing a request, the tenant needs to post its results in the format as it is defined for the respective quantity and method in the schemas repository https://github.com/BIG-MAP/FINALES2_schemas wrapped in data
field of the Result
object as defined in src/FINALES2/server/schemas.py
.
The call for posting results should read as follows:
_postedResult = requests.post(
f"http://<FINALES_host>"
f":<FINALES_port>/results/",
json=result,
params={},
headers=<authorization_header>,
)
An example of the use of this call in the context of a tenant can be found in the reference tenant.