Skip to content

Release Notes

v2.4.3

Fixes two task queue issues: pydantic secret params were masked when a task run was serialized to the queue, and a params validation error on the consumer side crashed the worker.

  • Secret params now survive the round-trip through the task queue and the cpu-bound subprocess. Task runs are serialized for the queue with secret values revealed via the new params_dump helper; all other dumps (logs, endpoints) keep secrets masked. (#103)
  • A task run consumed from the queue with invalid params no longer kills the consumer worker. The broker raises the new TaskParamsError carrying the task run, and the consumer logs the error and marks the run as failed. (#103)

v2.4.2

Tasks can now be tagged at registration time.

  • The task registration methods accept an optional tags argument. When provided, the extra tags are merged into each task's own tags as it is registered — applied across register_task, register_from_module, and register_from_dict. (#102)
  • Bumped python-json-logger to >= 4.1.0 and switched JSON logging to the new pythonjsonlogger.json formatter path (the old pythonjsonlogger.jsonlogger module is deprecated). (#102)

v2.4.1

Task history can now be filtered by task tags.

  • Added a tags field to task history queries. Runs match when their task carries at least one of the given tags, resolved against the live registry. (#101)

v2.4.0

Lazy settings via pydantic-settings, JSONB params filtering for task history, and customisable route prefixes.

  • Settings are now lazy — resolved on first access instead of at import time. Env vars use a FLUID_ prefix by default; legacy unprefixed names are kept as aliases. (#100)
  • The task database plugin accepts a route_prefix parameter for customising history route URLs and replaces with_task_history_router() with a register_routes() method. (#100)
  • Task history queries support filtering by run params via a new params field (renamed from HistoryQuery to TaskHistoryQuery). (#99)
  • Database migration required: the params column is now JSONB with a GIN index. See the example migration for the schema changes.
  • Removed get_logger from fluid.utils.log. Task loggers are now obtained directly via logging.getLogger(module).

v2.3.1

v2.3.0 is broken — do not use it.

Fixes a regression in v2.3.0 where the httpx2 dependency was pinned to >=2.2.0, which fails on Python 3.14 builds missing the _zstd C extension. Pins httpx2 to >=2.0.0, <2.1.0 and switches all httpx imports to httpx2 for correct namespace resolution.

  • httpx2 is now pinned to >=2.0.0, <2.1.0 — versions 2.1.0+ require the compression.zstd stdlib module which is not available in all Python 3.14 builds. (#98)
  • All import httpx statements replaced with import httpx2 as httpx (or from httpx2 import ...) to ensure correct namespace resolution regardless of httpx2 version.
  • Added test coverage for HttpxClient and HttpxResponse.

v2.3.0

Moves development and documentation dependencies from optional-dependencies to dependency groups, switches to httpx2 for HTTP client support, and removes the inflection dependency.

  • dev and docs dependencies are now declared under [dependency-groups] instead of [project.optional-dependencies]. Installed via uv sync --all-groups.
  • The http extra now uses httpx2 instead of httpx. httpx2 provides the same httpx module so no code changes are required. (#97)
  • The inflection dependency has been removed. (#96)

v2.2.6

Adds tag filtering for task listings and fixes a race in the task database plugin.

  • Task listings can be filtered by tag: the GET /tasks endpoint and the ls command of the task CLI accept a repeatable tags option that returns only tasks carrying at least one of the given tags, and TaskInfo now reports each task's tags. (#94)
  • The task database plugin now serialises its per-run lifecycle writes with a dedicated task-run lock. CrudDB.db_upsert is not atomic — it issues an UPDATE and only INSERTs when nothing matched — so when the scheduler wrote the queued row and a consumer wrote the running row a few milliseconds later, the consumer's UPDATE could miss the not-yet-committed INSERT, fall through to its own INSERT and violate the task-runs primary key. Holding the lock around the upsert removes the race. (#95)
  • TaskRun.lock accepts an optional name to acquire a named sub-lock for the task run, and timeout now defaults to None. (#95)

v2.2.5

  • The task decorator accepts an env mapping of extra environment variables, injected into the subprocess for CPU-bound tasks and forwarded to the container for tasks dispatched as Kubernetes Jobs. (#90)

v2.2.4

Bug-fix release for the task scheduler.

  • Fix task interruption handling. (#89)
  • Fix stale concurrent tasks not being released. (#88)
  • Fix task abort behaviour. (#87)
  • Patch pydanclick to work with StrEnum. (#86)