API¶
proTES implements the GA4GH Task Execution Service (TES)
API, version 1.0
(specification),
at /ga4gh/tes/v1/. A deployment's Swagger UI (/ga4gh/tes/v1/ui/) shows
the endpoints and lets you try them; the specification is served at
/ga4gh/tes/v1/openapi.json. All endpoints except GET /service-info, the
specification and the Swagger UI require an access token (see Access
control).
| Endpoint | Description |
|---|---|
GET /service-info |
The service info of the deployment (see Service info). |
POST /tasks |
Create a task: proTES forwards it to a TES instance (see Tasks) and returns its own identifier of the task. |
GET /tasks |
List the caller's tasks, newest first, one page at a time (page_size, at most max_page_size of the config, and max_page_size_full for the view FULL; page_token from next_page_token of the previous page, which is empty on the last page), optionally only those whose name starts with name_prefix (taken literally; matched against the name of the task as submitted, before plugins may have renamed it). |
GET /tasks/{id} |
Get a task of the caller, with its state as last tracked from the TES instance. |
GET /tasks/{id}/provenance |
proTES extension: get the provenance of a task, for its owner and for admins (see Provenance). |
GET /plugins |
proTES extension (FOCA's plugin listing): list the plugins and presets that the caller may choose for its tasks, and the limits, for users; the default pipeline only for callers who may choose pipelines (see Choices of clients). |
GET /plugins/{plugin_id} |
proTES extension: describe a plugin that the caller may choose (404 Not Found otherwise). |
POST /tasks/{id}:cancel |
Cancel a task of the caller that has not finished yet (also in state UNKNOWN, e.g., not tracked yet), at the TES instance that runs it; finished tasks are left as they are, also tasks that finish while they are canceled (their final state is kept). Unfinished tasks whose identifier at their TES instance is unknown (e.g., while they are being forwarded, or if forwarding failed unexpectedly) can't be canceled (409 Conflict). |
Only the owner of a task, the user who created it, can read and cancel it
(see Task ownership). Admins can manage
the access control rules at runtime through FOCA's permissions API at
/admin/access-control/permissions (see Access
control).
GET /tasks and GET /tasks/{id} return the views MINIMAL (the default;
identifier and state), BASIC (without the contents of inputs, the system
logs and the executors' standard output and error) and FULL (view), as
the TES specification describes. Times (creation_time, and start_time
and end_time of proTES's log of a task) are in UTC, in RFC 3339 format.
Tasks¶
For POST /tasks, proTES:
- stores the task as received, with a new identifier
(see Tasks for its format) and its
creation_time(tasks that setcreation_time, which the TES specification marks read-only, are rejected with400 Bad Request, as are tasks with credentials in the URLs of inputs or outputs, unless proTES is configured to remove them, and tasks with inline contents of inputs overmax_inline_content, with413 Content Too Large: see Tasks); - runs the pipeline of plugins, which may change the task
and select the TES instances to try and their order (by default, in random
order; routing by the distance to the input data and FOCA's ordered
failover need an explicit pipeline, see Plugins);
a plugin may reject the task (with
its status, e.g.,
403 Forbidden), a step whose plugins all fail fails the request (500 Internal Server Error), tasks without TES instances fail with503 Service Unavailable, and tasks whose inline contents plugins make too large with413 Content Too Large; none of these is kept; - forwards the task to the first of these TES instances that accepts it,
after the plugins of the
forwardphase, and returns its own identifier of the task (plugins may change the response); if no TES instance accepts it (withinplugins.defaults.forward_timeout), the request fails with503 Service Unavailable, and the task is not kept (it is deleted, with its owner's roles on it). Each TES instance gets its own copy of the task, without tags undergateway., with the credentials of proTES for it (see Credentials of TES instances), in a single request; the next TES instance is tried only if a TES instance certainly did not accept the task (see TES instances). If a TES instance may have accepted it without confirming it (e.g., the response timed out), the task is not sent to other TES instances, its state is set toSYSTEM_ERROR, and the request fails with502 Bad Gateway: the task may run at that TES instance, but proTES can neither track nor cancel it. Once a TES instance accepted the task, proTES stores the task with its TES instance and the remote identifier, and then with the state that the TES instance reports for it (it staysUNKNOWNif the state can't be got); - tracks the task at the TES instance in the background (a Celery worker polls its state until it has finished; see Tasks), and updates its state and logs.
proTES keeps the task as received (task_original) as well as the task as
forwarded; the TES instance and the remote identifier of the task are in its
gateway tags (gateway.backend and gateway.backend_task_id, see below).
Since the move to plugins, proTES no longer records them in the logs of tasks
(logs[].metadata.forwarded_to, an array of objects in the string map
metadata, which the TES specification doesn't allow), and serves tasks
stored by earlier versions without them (see
Upgrading).
Gateway tags¶
proTES adds tags to each new task (FOCA's gateway tags, under the reserved
prefix plugins.tags.prefix, gateway. by default), served with the task in
the views BASIC and FULL, besides the client's own tags:
| Tag | Value | Added |
|---|---|---|
gateway.pipeline_source |
default, preset:<name> or client |
when the task is stored |
gateway.pipeline_hash |
sha256: hash of the resolved pipeline |
when the task is stored |
gateway.plugins |
the plugins that ran in the request and route phases, as id@version, comma-separated |
when the task is stored |
gateway.provenance |
the path of the task's provenance (/ga4gh/tes/v1/tasks/<id>/provenance) |
when the task is stored |
gateway.backend |
the URL of the TES instance that accepted the task (or may have) | after forwarding |
gateway.backend_task_id |
the identifier of the task at that TES instance, if it accepted it | after forwarding |
gateway.forwarded_at |
when the task was sent to it (RFC 3339, UTC) | after forwarding |
gateway.attempts |
the number of TES instances tried | after forwarding |
gateway.route |
the last attempts as compact JSON (url, outcome, reason) |
after forwarding |
gateway.route_truncated |
true if gateway.route leaves out attempts |
after forwarding |
Tracking a task doesn't change its tags. If tags can't be built (an internal error, which is logged), the task is created without them; its provenance is stored nevertheless.
Clients can't set these tags (400 Bad Request; only gateway.backends,
and gateway.pipeline if enabled, are theirs, see
Plugins), and plugins can't change them.
TES instances get tasks without any tag under the prefix. Clients that
submit a fetched task again drop the tags under the prefix first, except
their own choices. Tasks created by earlier versions have none.
Provenance¶
GET /tasks/{id}/provenance (a proTES extension) returns the provenance of
a task: the record that FOCA's plugin engine made when the task was created
and forwarded (see Task provenance), with
the builds of the plugins that ran (builds, by build hash) and the
resolved pipeline (pipeline.resolved), e.g., shortened:
{
"engine": {"foca": "0.19.0", "plugin_api": 1,
"app": {"name": "proTES", "version": "0.4.0"}},
"request_id": "4f3c...",
"pipeline": {"source": "default", "preset": null, "requested": null,
"resolved": [{"id": "route", "alternatives": ["..."]}],
"resolved_hash": "sha256:9a1e..."},
"plugins": {"sha256:77b0...": "foca.routing.ordered"},
"builds": {"sha256:77b0...": {"id": "foca.routing.ordered",
"distribution": "foca", "version": "0.19.0"}},
"executions": [{"step": "route", "phase": "route", "outcome": "ok"}],
"route": {"candidates_in": ["https://tes.example.org"],
"candidates_out": ["https://tes.example.org"]},
"selection": null,
"attempts": [{"number": 1, "backend": "https://tes.example.org",
"outcome": "accepted", "reason": null, "remote_id": "task-1",
"started_at": "2026-10-31T09:00:00.020Z", "duration_ms": 80.1}],
"final_reason": null
}
The owner of the task and admins may get it; everyone else gets
403 Forbidden, also for unknown tasks (see Access
control); admins get 404 Not Found for
unknown tasks. Tasks without provenance (e.g.,
created by earlier versions) give 404 Not Found. The record holds no
inputs, logs, IP addresses, tokens, header values or claims: plugins'
changes are recorded as paths and hashes only.
Errors¶
Errors are problem details (with
title, status and detail; errors of the plugin engine also with
problem_type, a URI in FOCA's documentation), sent as application/json,
as the GA4GH
specification declares: 400 Bad Request for invalid requests (e.g.,
invalid tasks or query parameters, or invalid or reserved tags under
gateway.), 401 Unauthorized for requests
without a valid access token (with a Bearer challenge), 403 Forbidden for
users without the required role and for tasks of others or unknown tasks
(see Access control), 404 Not Found for tasks of the
caller deleted from the database, 409 Conflict for unfinished tasks
whose identifier at their TES instance is unknown, which can't be canceled,
413 Content Too Large for request bodies over the size
limit and tasks with inline contents
of inputs over max_inline_content (see
Tasks), the status of a plugin that rejected a
task, 500 Internal Server Error if all plugins of a step failed,
502 Bad Gateway if a TES instance did not confirm a request to create or
cancel a task, which it may have processed (see Tasks),
503 Service Unavailable if no TES instance accepted a task (in time; it
is not kept), and 508 Loop Detected for tasks that passed proTES before
(see Plugins). The
mapping of exceptions to problem details is
exceptions in
pro_tes.exceptions.
The TES specification declares only the successful responses. The served
specification adds, as proTES extensions, 413 Content Too Large to
POST /tasks and 409 Conflict to POST /tasks/{id}:cancel, with the
schema ProblemDetails (cf.
additions.openapi.yaml),
as clients don't get these from TES servers in general; the operations are
otherwise those of the TES specification. The other errors are those of
any HTTP API, and are not declared.