When an execution in Control Room starts, the first input item is automatically reserved. This first item is also loaded by the library when the task execution starts.
After an item has been handled, it should be released as either passed or failed. There can only be one reserved input item at a time.
Reserving can be done explicitly by calling the reserve method, which also acts as a context manager:
Another option is to loop through all inputs, which implicitly reserves and releases the corresponding items:
Releasing can also be done explicitly to set specific errors, or to mark items as done before exiting the block:
For each input work item, you can create any amount of output work items. These will be forwarded to the next step of a process, or set as the final result if there are no further steps.
In most cases, it's enough to create an output item directly using
Internally, Control Room keeps a relationship between the parent and child work items. The above example always uses the currently reserved item as the parent, but it's also possible to create an output explicitly from the input item:
In some cases, it's also useful to create an output item and then modify it before saving:
If you are developing in VSCode with the Robocorp Code extension, you can utilize the built in local development features described in the Developing with work items locally section of the Using work items development guide.
This allows you to develop and test your work items before deploying to Control Room.
It's also possible to develop locally with a custom editor, but it requires some configuration.
To enable the development mode for the library, you should set the environment
RC_WORKITEM_ADAPTER with the value
FileAdapter. This tells the
library to use local files for simulating input and output queues for work
items, in the form of JSON files.
The environment variables
should also be set, and should contain the paths to the input and output JSON
files. The output file will be created by the library, but the input file
should be created manually.
An example of an input file with one work item:
The format of the file is a list of objects, where each item in the list
corresponds to one work item. The
payload key can contain any arbitrary JSON,
files key is pairs of names and paths to files.
A process can be started in Control Room by sending an email, after which the
payload and files will contain the email metadata, text, and possible attached files.
This requires the
Parse email configuration option to be enabled for the
process in Control Room.
An input work item in this library has a helper method called
which can be used to parse an email into a typed container:
The email content in the payload is parsed into the following typed container:
When Control Room can not parse the email, for example when the content is too
large to handle, it will set specific error fields. These are parsed by the
work items library and raised as a corresponding exception. These errors
can also be ignored with the
ignore_errors argument to the
In some use-cases, it's necessary to access additional metadata such as custom
headers. Control Room attaches the raw unparsed email as a file attachment,
which can be parsed by the Robot code. One option for this is the Python built-in
To learn more about email triggering in Control Room, see the docs page.
Sometimes it's necessary to reduce multiple input work items into one output work item, e.g. for reporting purposes. The tricky part is that there needs to be a reserved input work item to create an output, and there is an unknown amount of input work items. This means that it's not possible to first loop all inputs and then create the output.
One way to solve this is to create an output from the first item, and then modify it later:
Failures for input work items can be set explicitly with the
which takes in an exception type (e.g.
APPLICATION), and an
optional custom error code and human-readable message.
However, sometimes complicated business logic needs to fail the entire input
item within a function that does not have direct access to it. For this use-case
the library exposes two exceptions:
When the library catches either of these exceptions, it knows to use it to set the failure state of the work item accordingly.
Where the exceptions are caught depends on the calling code, as there are several boundaries where it can happen.
The outermost boundary is the task itself. If a library exception is thrown from within the task and no other code catches it, the values are used to set the input work item's state before the task fails.
Note: The task itself will always fail when an exception is caught on this level.
A reserved input item can be used as a context manager, which automatically sets the pass or fail state depending on whether an exception happens before exiting the block or not.
Note: When the context manager catches a work item exception, it continues without failing the entire task.
While iterating the input queue automatically reserves and releases items, it can't catch the exceptions while iterating. If these exceptions are used in a looping task, they should be combined as follows:
Although not recommended, it's possible to modify input work items. As an example, a process might need to store additional metadata for failed items.
This is potentially dangerous, as it will reduce traceability of the process and maybe even make it behave in unexpected ways. If a modified item is retried, it could result in something that was not intended.
With these caveats, modifying an input item is relatively easy:
This example would clear all payloads from input work items.