Shareable object represents a communication between server and client.
Technically a Shareable object is implemented as a Python dict. This dict contains two kinds of information:
A special item in the Shareable is “headers”, which is a dict itself. The headers are used to carry meta information about the communication (e.g. peer identity name, peer’s job id / run number, cookies, return code, etc.). Headers are usually added and processed by the framework.
All other items in the Shareable object are the contents of the communication. You can place any elements into the Shareable object, but never use ReservedHeaderKey.HEADERS as the key of your content elements.
For all methods of Shareable, see
When processing requests or responses (which are all Shareable objects), you can get the information about the peer site using:
peer_props = shareable.get_peer_props()
This is a Python dictionary that contains peer site information.
If you are a workflow developer, when processing the client’s Get Task Request, you sometimes want to keep some contextual info with the task assignment sent to the client, and expect this info echoed back in the client’s task result submission. This can be done through the cookie mechanism.
A cookie is just a named piece of data (key/value pair). During the task request processing, any involved component (Controller, Filters, Event Handlers, etc.) can add a cookie to the FLContext:
The headers of the Shareable object can keep a special public prop called “Cookie Jar”, which is just a Python dict.
The NVIDIA FLARE framework guarantees that the cookie jar prop will be sent back to the server when the client submits the task result to the server.
Cookie data is for the server’s consumption only. Client processing logic should not rely on the knowledge of cookie data.
Another special header element from the client’s task result submission (which is a Shareable object too) is “return code”. This is a string that indicates whether the task was successfully executed. If this element is not present in the headers, it is considered to be successful.
You can get the return code with:
The return code specifies error condition that prevented the task from being executed:
MISSING_PEER_CONTEXT = "MISSING_PEER_CONTEXT" BAD_PEER_CONTEXT = "BAD_PEER_CONTEXT" RUN_MISMATCH = "RUN_MISMATCH" TASK_UNKNOWN = "TASK_UNKNOWN" TASK_DATA_FILTER_ERROR = "TASK_DATA_FILTER_ERROR" TASK_RESULT_FILTER_ERROR = "TASK_RESULT_FILTER_ERROR" EXECUTION_EXCEPTION = "EXECUTION_EXCEPTION" EXECUTION_RESULT_ERROR = "EXECUTION_RESULT_ERROR"
Some error conditions should never occur (e.g. MISSING_PEER_CONTEXT, BAD_PEER_CONTEXT).
RUN_MISMATCH - client and server are out of sync on the RUN. When this happens, the client will automatically end the RUN.
TASK_UNKNOWN - client cannot find an executor for the assigned task. This is usually caused by misconfiguration of the task table.
TASK_DATA_FILTER_ERROR - client failed to filter task data. Usually bugs in one of the filters.
TASK_RESULT_FILTER_ERROR - client failed to filter results generated by the task executor. Usually bugs in one of the filters.
EXECUTION_EXCEPTION - client failed the task execution. Usually bugs in the executor code.
EXECUTION_RESULT_ERROR - the executor failed to generate a Shareable object as the result - bugs in the code.