{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Prioritize annotation tasks\n",
"\n",
"This example demonstrates how to set up an agent node early in a Workflow to automatically assign a [priority](https://docs.encord.com/platform-documentation/Annotate/annotate-projects/annotate-manage-annotation-projects#task-priority) to each task before advancing the task to the annotation stage.\n",
"\n",
"### Example Workflow\n",
"\n",
"The following workflow illustrates how tasks are prioritized:\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
" \n",
" Project Workflow\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Notice how the workflow has a purple Agent node called \"prioritize\".\n",
"This node will allow every piece of data to be prioritized by the custom code written in this example."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Installation\n",
"\n",
"Please ensure that you have the `encord-agents` library installed:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!python -m pip install encord-agents"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Authentication\n",
"\n",
"The library authenticates via ssh-keys. Below, is a code cell for setting the `ENCORD_SSH_KEY` environment variable. It should contain the raw content of your private ssh key file.\n",
"\n",
"If you have not yet setup an ssh key, please follow the [documentation](https://agents-docs.encord.com/authentication/).\n",
"\n",
"> 💡 **Colab users**: In colab, you can set the key once in the secrets in the left sidebar and load it in new notebooks with\n",
"> ```python\n",
"> from google.colab import userdata\n",
"> key_content = userdata.get(\"ENCORD_SSH_KEY\")\n",
"> ```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"\n",
"os.environ[\"ENCORD_SSH_KEY\"] = \"private_key_file_content\"\n",
"# or you can set a path to a file\n",
"# os.environ[\"ENCORD_SSH_KEY_FILE\"] = \"/path/to/your/private/key\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### [Alternative] Temporary Key\n",
"There's also the option of generating a temporary (fresh) ssh key pair via the code cell below.\n",
"Please follow the instructions printed when executing the code."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# ⚠️ Safe to skip if you have authenticated already\n",
"import os\n",
"\n",
"from encord_agents.utils.colab import generate_public_private_key_pair_with_instructions\n",
"\n",
"private_key_path, public_key_path = generate_public_private_key_pair_with_instructions()\n",
"os.environ[\"ENCORD_SSH_KEY_FILE\"] = private_key_path.as_posix()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Workflow creation\n",
"\n",
"Before we dive into the code, we need to set up a workflow similar to the example shown above.\n",
"The important thing here is that it begins with an agent node that routes to the annotation node. Naming is not important.\n",
"\n",
"[📖 here](https://docs.encord.com/platform-documentation/Annotate/annotate-projects/annotate-workflows-and-templates#creating-workflows) is the documentation for creating a workflow with Encord.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Agent definition\n",
"\n",
"In the following code cell, we define the custom code that will put a priority on a task.\n",
"\n",
"Please fill in\n",
"- ``: You obtain it from the project page in the Encord platform.\n",
"- ``: It would be \"1e775...\" in the example workflow above.\n",
"- ``: It will be listed when you expand the agent node of the workflowe on the project page. (You can also use the pathway name that you gave it)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from encord.objects.ontology_labels_impl import LabelRowV2\n",
"\n",
"from encord_agents.tasks import Runner\n",
"\n",
"runner = Runner(project_hash=\"\")\n",
"\n",
"\n",
"@runner.stage(\"\")\n",
"def by_file_name(lr: LabelRowV2) -> str | None:\n",
" # Assuming the data_title is of the format \"%d.jpg\"\n",
" # and in the range [0; 100]\n",
" priority = int(lr.data_title.split(\".\")[0]) / 100\n",
" lr.set_priority(priority=priority)\n",
" return \"\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- **Task Runner:** The code initializes a runner to process tasks.\n",
"- **Priority Assignment:** It defines a stage implementation that:\n",
" - Extracts the data title of a task.\n",
" - Parses the stem of the data title as an integer.\n",
" - Assigns a priority as a number between `0` and `1`.\n",
"- **Task Routing:** Passes the task to the annotation stage by returning the correct pathway `UUID`.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Running the agent\n",
"Now that we've defined the project, workflow, and the agent, it's time to try it out.\n",
"The `runner` object is callable which means that you can just call it to prioritize your tasks."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Run the agent\n",
"runner()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Your agent now assigns priorities to tasks based on their file names and routes them appropriately through the Workflow.\n",
"\n",
"> 💡*Hint:* If you execute this as a Python script, you can run it as a command line interface by putting the above code in an `agents.py` file and replacing\n",
"> ```python\n",
"> runner()\n",
"> ```\n",
"> with\n",
"> ```python\n",
"> if __name__ == \"__main__\":\n",
"> runner.run()\n",
"> ```\n",
"> Which allows you to set, for example the Project hash using the command line:\n",
"> ```bash\n",
"> python agent.py --project-hash \"...\"\n",
"> ```\n"
]
}
],
"metadata": {
"colab": {
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": "encord-agents-Cw_LL1Rx-py3.11",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}