-
Notifications
You must be signed in to change notification settings - Fork 2
Tutorials
To enable the user application to define application requirements, also known as functional requirements, it should allow the user to specify preferences for the orchestration of resources where the function will be offloaded. This will empower users to customize and optimize the resource allocation based on their specific needs.
These requirements should match with the data model define in the following file: data model
The meaning of the available requirements is the following:
- FLAVOUR: It is a string that describes the flavour of the runtime. It is mandatory to set this requirement as it is used to define in which type of serverless runtime will the functions be executed in terms of dependencies and computing resources.
- MAX_LATENCY: It defines the maximun latency that the user application will tolerate when offloading a function. It is an integer optional parameter that, when it is established, it will select the Edge Cluster with the least latency. Therefore, the COGNIT framework is currently a best effort service.
- MAX_FUNCTION_EXECUTION_TIME: It is a float optional requirement that sets the max execution time allowed for the offloaded function.
- MIN_ENERGY_RENEWABLE_USAGE: An integer optional requirement that sets the minimum energy renewable percentage to be used when executing the function.
- GEOLOCATION: It is a mandatory requirement as it is used to select the nearest Edge Cluster for the user application if the MAX_LATENCY requirement is not set. This parameter is composed of a dictionary with two keys ("latitude" and "longitude") that have to be filled with float values.
- ID: Unique identifier assigned to each device. Used to estimate load and improve optimizer decisions. This field is mandatory and must be of type string.
- PROVIDER: It is an optional field that provides a list of provider identifiers used to restrict cluster selection by provider.
- IS_CONFIDENTIAL: It is an optional requirement and indicates if Confidential Computing is required for the execution of the functions. By default this requirement is set to false.
The way to set these requirements is demonstrated in this example
Before going deep on what COGNIT offers in regard to MinIO, it's important to note that MinIO does not differentiate between files and folders: everything inside a bucket is considered an object.
However, externally MinIO does support a linux like estructure using slash ("/"). To understand this difference, consider these two examples:
-
Save a file to the root bucket path:
minio_client.upload_object( bucket="ikerlan", objectPath="testData.csv", data=data )
Result inside MinIO:
ikerlan(bucket) └── testData.csv
-
Save a file inside a folder:
minio_client.upload_object( bucket="ikerlan", objectPath="recordings/20250512/recording1.csv", data=data )
Result inside MinIO:
ikerlan(bucket) └── recordings └── 20250512 └── recording1.csv
In order to enable communication between an offloaded function and the MinIO service, a Minio Client has been developed within the Serverless Runtime. This client provides a set of methods to interact with the service. As for bucket-oriented methods it has:
-
create_bucket(bucket_name)- Create a bucket.
-
list_buckets() -> List[str]- List all buckets.
-
delete_bucket(bucket_name)- Delete an empty bucket.
-
enable_versioning(bucket_name)- Enable versioning for a bucket.
-
set_bucket_policy(bucket_name, policy)- Set a JSON policy document on a bucket.
While object-based methods the Minio Client has:
-
list_objects(bucket_name) -> List[str]- List all object keys in a bucket.
-
upload_object(bucket, objectPath, data, extraArgs=None) -> str- Upload raw bytes (
data) tobucketat keyobjectPath, with optionalextraArgs(metadata, ACL).
- Upload raw bytes (
-
download_object(bucket: str, key: str, download_path: str = None) -> Union[bytes, str, Exception]- If
download_pathis provided, save the object to that Serverless Runtime path and return the path; otherwise return raw bytes.
WARNING: If
download_pathis provided, the downloaded file stays in the SR, meaning that no data is transferred back to the DR. - If
-
delete_object(bucket_name, object_name)- Delete a single object from a bucket.
-
get_object_metadata(bucket_name, object_name) -> dict- Retrieve the user-defined metadata for an object.
-
copy_object(source_bucket, source_key, destination_bucket, destination_key)- Copy an object from one bucket/key to another bucket/key.
There are also Serverless Runtime local disk methods:
-
download_file_to_sr_disk(bucket_name, object_name, download_path)- Download a single file from a bucket to the Serverless Runtime’s local disk at
download_path.
- Download a single file from a bucket to the Serverless Runtime’s local disk at
-
download_objects_with_prefix_to_sr_disk(bucket_name, prefix, target_local_directory, preserve_nested_structure=False)- Download all objects in
bucket_namewhose keys start withprefixintotarget_local_directory.- If
preserve_nested_structureisFalse, files are flattened intotarget_local_directory. - If
True, the full key path underprefixis recreated undertarget_local_directory.
- If
- Download all objects in
-
download_object(bucket: str, key: str, download_path: str = None) -> Union[bytes, str, Exception]- For the cases that
download_pathis provided, as it is explained in "Object level methods" section.
- For the cases that
To use MinIO within a function that is offloaded to the serverless runtime, you should import and use the MinIO client provided by the Serverless Runtime library directly inside the function. The sentence that imports the client withing the function is:
from modules._minio_client import MinioClientSo the MinIO client can connect to the MinIO service, the following parameters must be provided when initializing the MinIO client:
-
endpoint_url- String defining the Minio endpoint.
- It must have the format "
http://IP:PORT" (Important: "http://" must be included). - Note: Not tested with HTTPS.
-
access_key- String defining the Minio username.
-
secret_key- String defining the Minio password.
An example of a function to be offloaded using MinIO is the following:
def offload_function_example():
from modules._minio_client import MinioClient
minio_client = MinioClient(
endpoint_url=MINIO_ENDPOINT,
access_key="minio_user",
secret_key="minio_psw"
)
response = minio_client.list_buckets()
return responseAdditionally, you can find a broader example here
Tip
Since the function is offloaded from the Serverless Runtime, it is the Serverless Runtime that must connect to the MinIO service. Please ensure that the Serverless Runtime has network access to the specified endpoint_url.
There is a possibility to log the internal state of the offloaded funcions inside the Serverless Runtime app log. To do so, the user will need to include the Serverless Runtime logger class inside of each offloaded function that wants to log within the SR log:
from modules._logger import CognitLogger
cognit_logger = CognitLogger()
Afterwards the user can use the log levels:
cognit_logger.debug("This is a DEBUG level message")
cognit_logger.info("This is an INFO level message")
cognit_logger.warning("This is a WARNING level message")
cognit_logger.error("This is an ERROR level message")
cognit_logger.critical("This is a CRITICAL level message")When the SR app runs the offloaded function, the logger will also include the logs registered within that function. An example of log registrations can be found here
To obtain a device's geolocation coordinates based on its IP address, you can use ipinfo.io . Signing up is required to obtain a token, which allows access to certain restricted features of the RESTful API.
Once the user has registered and obtained a token, the following script demonstrates how to retrieve geolocation information that can be used in a given example:
It uses both restricted and unrestricted endpoints to fetch the device's public IP address and retrieve geolocation information based on it.
import requests
def get():
endpoint = 'https://ipinfo.io/ip'
response = requests.get(endpoint, verify = True)
if response.status_code != 200:
return 'Status:', response.status_code, 'Problem with the request. Exiting.'
exit()
#data = response.json()
data = response.text.strip()
#return data['ip']
return data
token="<your_token_value_here>"
my_addr=get()
endp = "https://ipinfo.io/{0}?token={1}".format(my_addr, token)
#get my ip
r = requests.get(endp, verify = True)
#print my geoloc
print(r.text)Output of the example script that can be parsed to use as COGNIT's geolocation coordinate input:
{
"ip": "XXX.XXX.XXX.XXX",
"city": "Your city",
"region": "Basque Country",
"country": "ES",
"loc": "XX.xx,YY.yy",
"org": "XX Autonomous System",
"postal": "20500",
"timezone": "Europe/Madrid"
}