Refine Python tools task interface
Build custom container images / build (map[base_image:php:8-fpm-alpine build_args:PHP_VERSION=8
context:php8-pgsql fingerprint_command:{ apk info -v | LC_ALL=C sort; find /usr/local/lib/php/extensions /usr/local/etc/php/conf.d -type f -exec sha256sum {} + | LC_ALL=C sort; }
name:ph… (push) Successful in 39s
Build custom container images / build (map[base_image:postgres:18 build_args:PG_VERSION=18
POSTGIS_VERSION=3
VCHORD_VERSION=0.5.3
context:postgres fingerprint_command:{ dpkg-query -W -f='${binary:Package}=${Version}\n' | LC_ALL=C sort; find /usr/lib/postgresql -type f -exec sha256su… (push) Successful in 53s
Build custom container images / build (map[base_image:python:3 build_args:PYTHON_VERSION=3
context:python-tools fingerprint_command:{ dpkg-query -W -f='${binary:Package}=${Version}\n' | LC_ALL=C sort; pip freeze | LC_ALL=C sort; }
name:python-tools oci_labels:org.opencontainers.ima… (push) Successful in 1m17s
Build custom container images / build (map[base_image:php:8-fpm-alpine build_args:PHP_VERSION=8
context:php8-pgsql fingerprint_command:{ apk info -v | LC_ALL=C sort; find /usr/local/lib/php/extensions /usr/local/etc/php/conf.d -type f -exec sha256sum {} + | LC_ALL=C sort; }
name:ph… (push) Successful in 39s
Build custom container images / build (map[base_image:postgres:18 build_args:PG_VERSION=18
POSTGIS_VERSION=3
VCHORD_VERSION=0.5.3
context:postgres fingerprint_command:{ dpkg-query -W -f='${binary:Package}=${Version}\n' | LC_ALL=C sort; find /usr/lib/postgresql -type f -exec sha256su… (push) Successful in 53s
Build custom container images / build (map[base_image:python:3 build_args:PYTHON_VERSION=3
context:python-tools fingerprint_command:{ dpkg-query -W -f='${binary:Package}=${Version}\n' | LC_ALL=C sort; pip freeze | LC_ALL=C sort; }
name:python-tools oci_labels:org.opencontainers.ima… (push) Successful in 1m17s
This commit is contained in:
+75
-37
@@ -28,51 +28,89 @@ first line of their module docstring. A task must not require stdin or command
|
||||
line arguments, should write useful output, and must return a non-zero exit
|
||||
code on failure.
|
||||
|
||||
## Task inputs
|
||||
## Task definitions
|
||||
|
||||
An optional `task-inputs.json` beside a group's task files declares the fields
|
||||
for its web forms and its task order. It is parsed as data only and uses version
|
||||
`1`:
|
||||
Each non-hidden directory directly below `/opt/tasks` is a task group. Its
|
||||
direct `*.py` files are the exposed tasks. Use an optional
|
||||
`task-inputs.json` beside those files to define the group's title, task titles
|
||||
and descriptions, task order, and web form fields. It is parsed as data only
|
||||
and currently uses version `1`:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"label": "Example Tasks",
|
||||
"title": "Example Tasks",
|
||||
"tasks": {
|
||||
"task.py": {
|
||||
"inspect.py": {
|
||||
"title": "Inspect item",
|
||||
"description": "Checks one item without changing it.",
|
||||
"inputs": [
|
||||
{"name": "identifier", "label": "Identifier", "type": "text", "required": true},
|
||||
{"name": "attempts", "label": "Attempts", "type": "integer", "minimum": 1, "maximum": 5, "default": 2},
|
||||
{"name": "mode", "label": "Mode", "type": "choice", "options": ["standard", "extended"]},
|
||||
{"name": "alerts", "label": "Alerts", "type": "multi_choice", "options": ["email", "webhook"]}
|
||||
]
|
||||
{"name": "alerts", "label": "Alerts", "type": "multi_choice", "options": ["email", "webhook"]},
|
||||
{"name": "review_csv", "label": "Review CSV", "type": "file", "accept": [".csv"], "maximum_bytes": 10485760}
|
||||
],
|
||||
"wait_for_result": true,
|
||||
"execution": {
|
||||
"field": "mode",
|
||||
"dry_run_value": "review",
|
||||
"dry_run_label": "Review",
|
||||
"execute_value": "apply",
|
||||
"execute_label": "Execute"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Supported field types are `text`, `integer`, `date`, `datetime`, `choice`,
|
||||
`multi_choice`, and `file`. Text may also define a regular-expression
|
||||
`pattern`; integer fields accept `minimum`, `maximum`, and `step`. Choices may
|
||||
use strings or objects with `value` and `label`. File fields accept a list of
|
||||
lowercase filename extensions in `accept` and a byte limit in `maximum_bytes`.
|
||||
An input can define `required` and `default`.
|
||||
Set `sensitive` to `true` for a value or upload that must not appear in run
|
||||
history. The form masks sensitive text, the database records `[redacted]`, and
|
||||
the original value is available only through a private execution input file.
|
||||
Tasks listed in the manifest appear in JSON order. A listed task may use `{}`
|
||||
when it only needs ordering; unlisted scripts appear afterward in alphabetical
|
||||
order. `label` is optional and overrides the group name displayed in the UI.
|
||||
Set `wait_for_result` to `true` for a short task whose form should wait for its
|
||||
final success or failure status. This disables the form and warns before
|
||||
leaving the page while the task is running; tasks without it keep the normal
|
||||
queued-run behavior.
|
||||
`title` is optional on a group and task. A group otherwise uses its directory
|
||||
name; a task otherwise uses its filename without `.py`, with underscores made
|
||||
readable. `description` is optional on a task and otherwise comes from the
|
||||
first non-empty line of its module docstring. The order of keys in `tasks`
|
||||
controls the listed tasks' display order. Include a task as `{}` when only
|
||||
ordering is needed. Unlisted direct Python files follow alphabetically.
|
||||
|
||||
For a task with a review-first operation, declare `execution` with the input
|
||||
field and its review and execution values. The control panel generates the
|
||||
mode selector attached to the submit button. A successful review run offers a
|
||||
button that repeats the same saved inputs using the execution value; it does not reuse a stale filesystem
|
||||
snapshot, so the task must still validate its inputs before changing anything.
|
||||
Each task declaration may contain `title`, `description`, `inputs`,
|
||||
`wait_for_result`, `download_artifacts`, and `execution`. Set
|
||||
`wait_for_result` for short tasks where the form should remain blocked until it
|
||||
reports success or failure. The control panel disables its controls and warns
|
||||
before page unload while such a task runs. `download_artifacts` additionally
|
||||
starts the first non-JSON artifact download after a successful browser run;
|
||||
reserve it for files such as archives that the browser should download
|
||||
automatically.
|
||||
|
||||
Every input has `name`, `label`, and `type`; `required` defaults to `false`.
|
||||
`default` is allowed for every type except `file`.
|
||||
|
||||
- `text`: optional `pattern`, a Python-compatible regular expression.
|
||||
- `integer`: optional `minimum`, `maximum`, and positive `step`.
|
||||
- `date` and `datetime`: ISO-formatted browser date controls.
|
||||
- `choice`: `options` is required, as strings or `{ "value", "label" }` objects.
|
||||
- `multi_choice`: the same required `options`; its `default` is an array.
|
||||
- `file`: optional lowercase extension list in `accept` and positive byte cap
|
||||
in `maximum_bytes`.
|
||||
|
||||
Set `sensitive` to `true` on text or file inputs that must not appear in run
|
||||
history. Text is masked, the database records `[redacted]`, and the original
|
||||
value is available only through a private execution-input file. Uploaded files
|
||||
are likewise retained privately for the run and then removed.
|
||||
|
||||
For review-first tasks, use `execution`. It produces one split button: click
|
||||
the main part to use its current mode, or use the arrow to select the other
|
||||
mode. A successful review run can be repeated with its saved inputs in the
|
||||
execution mode from the run-detail page. The task must still revalidate the
|
||||
live filesystem before changing anything.
|
||||
|
||||
```json
|
||||
{
|
||||
"field": "mode",
|
||||
"dry_run_value": "review",
|
||||
"dry_run_label": "Review",
|
||||
"execute_value": "apply",
|
||||
"execute_label": "Execute"
|
||||
}
|
||||
```
|
||||
|
||||
The server validates every submitted value before a run is queued. It records
|
||||
the validated object in the run database and writes it to a per-run file.
|
||||
@@ -84,15 +122,15 @@ are stored in a private per-run directory; their absolute paths are provided in
|
||||
the input JSON and the files are removed when the task finishes, fails, or is
|
||||
cancelled.
|
||||
|
||||
## Downloads
|
||||
## Artifacts
|
||||
|
||||
Tasks can write downloadable files to the directory named by
|
||||
`SERVER_MAINTENANCE_ARTIFACTS`. Set `download_artifacts` to `true` alongside
|
||||
`wait_for_result` to start the first artifact download after a successful web
|
||||
run. Run-detail pages also show available downloads. The server deletes an
|
||||
artifact after its HTTP transfer ends; any undownloaded artifact is removed
|
||||
after 24 hours. A browser cannot confirm that a downloaded file was retained
|
||||
on the client device.
|
||||
Tasks can write files to the directory named by
|
||||
`SERVER_MAINTENANCE_ARTIFACTS`. Run-detail pages show them when the task
|
||||
finishes. JSON artifacts offer an **Open** link that renders the JSON in a new
|
||||
tab and leaves the artifact available; other artifacts offer a download link.
|
||||
The server deletes an artifact after its download transfer ends; any artifact
|
||||
not downloaded is removed after 24 hours. A browser cannot confirm that a
|
||||
downloaded file was retained on the client device.
|
||||
|
||||
## Background tasks
|
||||
|
||||
|
||||
Reference in New Issue
Block a user