Files
docker-images/python-tools/README.md
T
ajp_anton b9c886a5ea
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 43s
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 54s
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 1m18s
Restore generic Python tools documentation and tests
2026-08-16 03:17:17 +00:00

118 lines
5.4 KiB
Markdown

# Python Tools
This image is a Python 3 task runner with ExifTool and a small web control panel
for running known, mounted Python maintenance tasks. It starts the control panel
with `python -m app`.
## Control Panel
The application discovers direct `*.py` files in each non-hidden directory
under `/opt/tasks`. Each directory is a task group. Tasks in one group run
sequentially; different groups may run concurrently. It records run history and
combined output in SQLite under `/var/lib/server-maintenance`, and supports
cancellation of active task process groups.
The image contains application code only. Mount these paths at runtime:
- `/opt/tasks` read-only: reviewed task scripts and their input manifests.
- `/opt/credentials` read-only: named credential files used by those scripts.
- `/var/lib/server-maintenance`: persistent SQLite data, logs, and task state.
Task processes receive a minimal environment. To forward non-secret container
settings to tasks, list their names in `SERVER_MAINTENANCE_TASK_ENV`, separated
by commas. This allowlist prevents unrelated container configuration from
being exposed to every task; credentials should remain in `/opt/credentials`.
Tasks are never imported during discovery. Their optional description is the
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
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`:
```json
{
"version": 1,
"tasks": {
"task.py": {
"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"]}
]
}
}
}
```
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.
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.
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
dropdown. 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.
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.
Sensitive fields are redacted in the database and use a private `0600`
execution file instead. Tasks read the applicable file path from
`SERVER_MAINTENANCE_INPUT`; no user value is appended to the command line. A
task without an entry in the manifest gets an empty JSON object. Uploaded files
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
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.
## Background tasks
An optional `background-tasks.json` beside a group's task files declares
internal recurring scripts. These scripts must live below the group's
`internal/` directory, are not exposed in the UI, and are launched at most once
per configured interval. Their latest output is retained below the persistent
state directory rather than being added to normal run history.
```json
{
"version": 1,
"tasks": [
{"id": "poll", "script": "internal/poll.py", "interval_seconds": 60}
]
}
```
`compose.example.yaml` is suitable for adding the service to an existing Compose
stack. Set `PYTHON_TOOLS_VOLUME_ROOT` to the host directory that will hold
`state`, `tasks`, and `credentials`; set
`SERVER_MAINTENANCE_ALLOWED_PROXY_IPS` to the reverse proxy's direct peer
address. Keep the application behind an authenticated reverse proxy.