Repository navigation
Releases
v0.19.0 — Project triggers and sub-projects
Start a project when a file arrives, a table changes, a webhook is called or another project ends — and let one project run another — without an external scheduler or message broker.
pip install -U hydra-etlNew features
Project triggers — triggers.yaml
-
A
triggers.yamlfile at the project root, seven types:Type Starts the project when… Parameters received cronthe schedule matches ( cron, IANAtimezone)— intervalevery every— filea file matching path(glob,**) is added or modifiedtrigger.file,trigger.filesmarkera marker file such as inbox/READYappears (removed unlessconsume: false)— source_changea job source changes ( check: count | max | checksum)trigger.value,trigger.previouswebhookPOST …/triggers/{name}/webhookwith a valid tokennone (nothing from the request) after_projectanother project ends ( on: success | failure | any)trigger.project,trigger.status -
Common keys:
env,workflows(default: the thread),params(no secret),overlap(skipby default),timeout,retry: {max, delay},enabled,description. A trigger always runs the project in its own process, under.hydra/run.lock. -
hdrctl watch [PROJECT]... [--env]runs the triggers of one or more projects. It prints each trigger and its next run, then every start and end. -
hdrctl serveruns the same engine for every project of the Studio list. -
hdrctl trigger list | validate | fire <name> | history | token <name> [--rotate].validatechecks workflows, called projects, sources, webhook secrets and refusesafter_projectloops. Every run is recorded in.hydra/triggers/history.jsonl. -
Guarantees:
- a trigger still running is not started again (the missed run is recorded as
skipped); runs missed while the engine was stopped are not replayed; triggers.yamlis reloaded without restart; an invalid file keeps the previous triggers running;- a file is taken only once unchanged for
debounce(no half-copied file); a file arriving during a run starts the next run; - a
source_changemeasure runs apart from the engine (a slow database does not hold up other triggers); on PostgreSQL, MySQL/MariaDB and SQL Servercountandmaxare a singleSELECT COUNT(*)/SELECT MAX(col); - webhook tokens are
${SECRET:…}references, compared in constant time (401 / 404 / 503); keephdrctl serveon 127.0.0.1 unless an HTTPS reverse proxy stands in front; - first Ctrl+C on
hdrctl watchwaits for running projects; a second stops at once.
- a trigger still running is not started again (the missed run is recorded as
-
Cron expressions are parsed by Hydra itself (no extra package);
tzdatais installed on Windows. -
Studio — Project settings › Triggers: triggers with event, environment, next run, running state and last run; a form per type; enable/disable, delete, Run now; create or rotate a webhook token (shown once, with PowerShell and curl calls); run history. An invalid change is not written; the previous file is backed up to
~/.hydra/_backups. -
API:
GET|PUT /api/projects/{id}/triggers,…/triggers/history,POST …/triggers/{name}/fire,…/{name}/webhook,…/{name}/token.
Sub-projects — type: project step
- A workflow of a "master" project runs another project: its
thread.yaml, or only theworkflowslisted. Keys:project(relative path, orref:a Studio project),env(inheritby default),params,variables,workflows,outputs,isolation(inprocessorsubprocess),timeout,overlap(wait,skip,fail). - Nothing is passed implicitly except the environment; the called project keeps its own secrets, and
${SECRET:…}is refused inparamsandvariables. - Checked before anything runs (
hdrctl run,--dry-run,workflow validate, Studio Check): project not found or ambiguous, cycles (a → b → a), more than 5 levels.workflow validateprints the tree of called projects. - Results readable by the next steps:
{{ project:STEP.status }},.rows,.duration,.param.NAME. - A called project runs once at a time (
.hydra/run.lock, also between processes; a stale lock is taken over). hdrctl run <project> -w <workflow>(repeatable): run only these workflows.- Studio — Project node: a Projects section in the palette; a cycle is refused with its path; one window sets path, environment, workflows, parameters, outputs, process, timeout and overlap.
Tools
- VS Code extension 0.1.8 (
type: project) and 0.1.9 (triggers.yaml: the seven types,tokenas a secret reference only, 8 snippets). - MCP:
hydra_project_callsandhydra_project_triggers(read-only). - API:
POST /api/projects/{id}/project-step.
Patches and fixes
- Workflow actions lost the values of
environments/<env>.yamlwhen arequiredparameter was given at run time (-P, orparamsof a project step):{{ param:X }}fell back to the defaults while the jobs of the same run used the environment. hdrctl workflow runrefuses project steps that form a cycle, call a missing project or nest more than 5 levels, before anything runs.- An optional
{{ env:NAME }}or a parameter without value inside a text becomes an empty string instead ofNone. - Parameter errors are in English:
missing required parameter,unresolved parameter,missing environment variable.
Documentation
- White paper (FR/EN): 1.4 Sub-projects and 1.5 Project triggers. README and
03-workflows.mdupdated.
Full changelog: v0.18.0...v0.19.0
v0.18.0 — Environments, global variables and secrets per environment
One project, several environments: global variables shared by the machine, parameter values and secrets per environment, managed from the CLI or Studio.
pip install -U hydra-etlNew features
- Global environment variables, shared by every project of the machine:
~/.hydra/env(all environments) and~/.hydra/env.<env>(one environment), selected by--env/HYDRA_ENV; locationHYDRA_HOME. Order, weakest first:env<env.<env>< project.env< job.env<--env-file. When a run switches environment (Studio, API), the variables of the previous one are removed. Workflow actions see these variables and the project.envfrom the first step. - Secrets per environment:
.hydra/secrets.<env>(plain or SOPS-encrypted) wins over.hydra/secretswith--env <env>;sops.fileaccepts{env}. The.gitignorewritten byhdrctl initignores.hydra/secrets.*but keepssecrets.yamland encrypted files. --env-file FILEonhdrctl runandhdrctl workflow run: extra variables for one run, above every other layer.hdrctl workflow runaccepts--envand-P/--param.- New commands:
hdrctl env list|show|create|rename|delete|set|unset— environments and global variables;renameanddeletealso move parameter values and secrets, after a backup to~/.hydra/_backups/;hdrctl param list|set|unset— parameters, default value and value per environment;hdrctl secret list|set|delete— the value is typed hidden or read from stdin, never passed as an argument;listshows names only.
- Studio:
- active environment selector on the project page and in the editor, used by every run and by the Expression Assistant;
- Global settings › Environments: create, rename, delete environments and edit their global variables;
- Project settings: tabs Execution order, Parameters (one column per environment) and Secrets (names only).
parameters.yamlaccepts the short formname: value(it stopped the run with an internal error).- VS Code extension 0.1.7: schemas and snippets for
parameters.yaml,environments/<env>.yamland.hydra/secrets.yaml. - MCP:
hydra_project_settings(read-only; never a secret or variable value);hydra_run_workflowacceptsenv. - API:
/api/global-env;/api/secretsacceptsenv; inline job and action runs acceptenv.
Patches and fixes
hdrctl run jobs/<job>reads the.envat the project root, not only the one of the job's parent folder.bash,powershellandpythonactions withoutworking_dirrun in the project root; a relativeworking_diris resolved from there. Scheduled and webhook runs started byhdrctl serveused to run in the server's folder, so relative paths failed.- Studio: a project whose
.hydra/project.jsonhad noidgot the id""; the id is now added to the file. - Studio: the
scheduleworkflows of a project opened in Studio are planned at once, not at the next start ofhdrctl serve. - Studio: runs with no environment selected sent
env: "default"; "default" now means no environment.
Full changelog: v0.17.0...v0.18.0
v0.17.0 — Secrets masked everywhere, SOPS, window and text_to_rows
New features
Secrets
- Secrets are masked everywhere Hydra shows or keeps text: logs (every logger, step logs, API), error messages, tracebacks, the output of
bash,powershell,pythonandsshactions,webhookandemaillog lines, the rollback report and the runs stored by the API. URL-encoded and JSON-escaped forms are masked too. Values sent to connectors, scripts and webhooks are unchanged. - Visibility, as in GitLab:
plain(debugging, with a warning),masked(default,[MASKED]) orhidden(lines containing a secret are dropped and counted). Set it in.hydra/secrets.yaml, withHYDRA_SECRETS_VISIBILITYor--secrets-visibility. Values shorter than 4 characters are not masked; a warning names them. .hydra/secrets.yaml: project secrets settings, with no secret inside, safe to commit (visibility,provider). Unknown keys and providers are reported, never ignored.- SOPS provider (
provider: sops; age, PGP, cloud KMS): secrets decrypted in memory on first use; nested keys read as${SECRET:db.password}. A SOPS-encrypted.hydra/secretsor--secrets-fileis detected and decrypted as well. - Provider interface (
SecretProvider,register_provider) for external vaults.
Transformations
joinwithhow: cross(cartesian product), guarded bymax_rows(default 10,000,000 rows produced): the run stops before the batch that would exceed it.text_to_rows: one row per value of a text column ("a;b;c"→ 3 rows). Optionssep,regex,trim,keep_empty,index_column. No input row is lost.window: window functions that add columns and keep every row in order — rank (row_number,rank,dense_rank), offset (lag,lead), running (cumsum,cumcount,cummin,cummax) and whole-partition (sum,mean,min,max,count,first,last). Runs in DuckDB with the large-volume engine, same results as pandas.
Studio and tools
- Expression Assistant: lists the project's parameters (with their value in the active environment), environment variables and, on reference fields, secrets. Double-click or drag an item; Insert writes it into the field. Opens from fx on expressions and from a new {x} button on fields such as paths, host, SQL query, URL or timeouts. Numeric fields accept a reference.
- Text to Rows and Window nodes; the Join node offers
crosswith a Max rows field. - DSL specification: 20 operations. MCP:
hydra_list_operationslists them,hydra_explain_errorexplains the new errors,hydra_check_jobwarns when a request needswindow,text_to_rowsorjoin. - VS Code extension 0.1.6: schema and snippets for the additions.
Patches and fixes
- Studio: the Script node showed a generic icon in the palette and its dialog.
- Studio: the MySQL and PostgreSQL nodes show the official logos; the SQL Server node shows a database icon.
Full changelog: v0.16.1...v0.17.0
v0.16.1 — MongoDB schema drift policy now applies
New features
- None.
Patches and fixes
-
MongoDB source:
schema.drift_policynow applies. Theschemablock never reached the connector, and documents were normalised before drift detection, sofail/warn/adapt/ignorehad no effect. Now:failraisesSchemaDriftErrornaming the field and the document;warnlogs each new field once, plus a summary;adaptextends the schema;ignorestays silent.
schema.sample_sizeis honoured. Regression tests:tests/test_mongodb_drift.py.
Full changelog: v0.16.0...v0.16.1
v0.16.0 — engine: key per job, right and outer join in DuckDB
New features
engine: auto | pandas | duckdbintransformations.yaml(at the root or undertransformations:) chooses the engine of a job's global operations;HYDRA_ENGINEstill takes precedence. Studio: Engine selector on a job's canvas, kept on round-trips with the YAML files. JSON schemas (Hydra DSL, VS Code extension 0.1.5) updated.- Right and outer
joinrun in DuckDB in the large-volume engine, with the same rows, columns, order and types as pandas; only the columns the following aggregation needs are copied. 20 million rows, right join then aggregation (2 CPUs): 71.8 s / 3.4 GB → 27.7 s / 2.6 GB.
Patches and fixes
sortis stable: rows with equal sort keys keep their input order (it already was for several columns, not always for one).
Full changelog: v0.15.0...v0.16.0
v0.15.0 — Large-volume engine: 20 M rows in 34 s instead of 113 s
New features
- Large-volume engine (optional:
pip install "hydra-etl[duckdb]", which now also installs pyarrow). AboveHYDRA_LARGE_VOLUME_ROWSestimated rows (2,000,000 by default), a job with a global operation reads its CSV source with pyarrow and runsaggregateandsortin a temporary on-disk DuckDB database. pandas keeps every other step and stays the default below the threshold. HYDRA_ENGINE=auto | pandas | duckdbforces the choice.- No silent fallback: a global step DuckDB cannot translate goes back to pandas with a log message; the fast reader hands over to the Python reader with a warning.
- Measured on 20 million rows (2 CPUs): 112.8 s / 5.4 GB → 34.3 s / 1.4 GB, identical results.
--profileshows the engine chosen and why.
Patches and fixes
- DuckDB sums are byte-identical to pandas (compensated, ordered summation), so switching engine never changes a result.
Full changelog: v0.14.0...v0.15.0
v0.14.0 — Fallback after a failure, timeout per workflow
New features
- Fallback after a failure (
fallback.on_failure: true): a workflow that fails is replaced by its first backup, only if it left nothing published — no load published and no outside action done (except actions markedundo: none), or everything undone byrollback: true. If the backup fails too, the next one inuseruns. Otherwise the project stops and says why:⛔ load_crm: fallback load_crm_backup not started — step 'load1' had already published its data. The replaced run is reported as recovered (CLI↯, Studio badge replaced by …); the project succeeds if the backup does. timeoutper workflow inthread.yaml(30s,5m,1h): beyond it the workflow is stopped at the next step or batch (an all-or-nothing load is cancelled; an action already started finishes) and counts as failed, which can trigger the fallback. Shown by--dry-run, in Studio, in the VS Code schema and in the DSL reference.hdrctl run --dry-runand Studio's Check warn when a workflow withon_failurepublishes in several steps withoutrollback: true.- Studio — wait field (
delay_before) on each workflow of the execution order; the Preview shows the wait above the block, the run page a waited … badge. The run API returnswaitedon each step. - Studio — Settings has two tabs: Global settings (editor preferences) and Project settings (execution order, fallbacks, loops, written to
workflows/thread.yaml). - Studio — the project page lists the workflows with Project settings and Run project (the project is checked first; errors link to Project settings).
Patches and fixes
- Studio: the run page of a workflow kept by its condition, then replaced after a failure, is shown correctly.
- Studio: a workflow opened from the Preview opens on its Workflow configuration tab and returns to Project settings.
- Studio asks before leaving the execution order with unsaved changes.
- CLI: durations of whole minutes or hours are shown as
5m,1h.
Full changelog: v0.13.0...v0.14.0
v0.13.0 — Fallback workflows, all-or-nothing loads and workflow rollback
A failed or risky run no longer leaves half-written data behind: each job loads all or nothing, a workflow can undo what it did, and a backup workflow can take over before the start.
New features
Declarative fallback (thread.yaml)
- A workflow can declare backup workflow(s):
use(tried in order),when(condition checked just before the start) andon_probe_error(keepby default, orreplace). whenuses a closed language analysed by Hydra, never Pythoneval:source_available,destination_available,file_exists,file_size,file_age,url_ok,secret_defined,db.load,previous.status,previous.rows,and/or/not, comparisons, durations (24h) and sizes (5MB).- At run time, quick probes with a time limit (
HYDRA_PROBE_TIMEOUT, 15 s) read no data. True → the first backup runs in place (↪ Fallback: a → a_backup — <reason>). hdrctl run <project> --use-fallback <workflow>forces a fallback to rehearse a recovery.hdrctl workflow add <name> --fallback-for <workflow>;workflow listshows backups;workflow removecleans the references.--dry-runand Studio's Check check backups, their jobs and the sources/destinations named inwhen, and warn when a backup writes elsewhere.- Studio: fallback editor in Define (condition checked as you type, helper to insert functions and project resources), backups drawn as dashed blocks in Preview, the decision and its reason on the run page.
All-or-nothing load per job
- A job writes its destination through one load session (
begin → stage → publish | abort), common to every connector. Nothing is visible before the end of the job; a failure or Ctrl+C leaves the destination as it was. - On by default for
replace(PostgreSQL / SQL Server: TRUNCATE in one transaction; MySQL / MariaDB: DELETE in one transaction, InnoDB; CSV / Parquet: temporary file then swap) and for CSV / Parquetappend. load.atomic: true | falseindestinations.yaml;trueon a connector that cannot honour it is an error before anything is read.- Two jobs of the same run writing the same destination take turns.
Workflow rollback
rollback: trueinworkflow.yaml: if the workflow fails, the steps already done are undone, last first. Files restored, CSV append truncated back, replaced tables restored, rows added byappend/upsertremoved and changed rows restored (PostgreSQL, MySQL / MariaDB, SQL Server).- Actions declare
undo:(an action, ornone), required forwebhook,email,bash,powershell,ssh,python. - A destination changed by someone else since the run is not undone: the rest is kept in
.hydra/undo/<workflow>.jsonand the workflow refuses to run untilhdrctl workflow undo <workflow>finishes it. - Studio: Rollback on/off in the toolbar, Undo section on actions, undone steps on the run page.
Also
delay_beforeon a workflow: wait before starting it (staggered starts in a parallel stage).- API:
GET /api/projects/{id}/conditions,POST /api/projects/{id}/conditions/check; project run steps carry afallbackobject. - VS Code schema and DSL reference updated.
Patches and fixes
- Studio: a job whose operations were written as top-level
steps:intransformations.yaml(the form ofhdrctl initand the CLI) lost them when saved. Both forms are now read. - A job keeps one connection / one open file for all its batches; Parquet no longer copies the whole file for every batch.
- Without all-or-nothing, a failed job logs that the destination keeps the batches written before the failure.
Full changelog: v0.12.3...v0.13.0
v0.12.3 — Studio and disk stay in sync, validate counts every error
New features
- Studio and the job files stay in sync, both ways. Studio keeps a job and its
jobs/<name>/*.yamlfiles in step, and the latest change wins, made in Studio or outside (editor,hdrctl, git).- The sync button (Hydra DSL panel, or Sync with disk in the toolbar) compares canvas and files: only the disk changed → the canvas is rebuilt (node positions kept); only Studio changed → the files are written; both changed → the most recent change wins.
- Automatic sync of the open job every few seconds (Settings, default 5 s, 0 = off), and when a job is opened.
- Formatting and comments are not changes: Studio compares the content.
- API:
GET /api/jobs/filesalso returnshashes,hashandmtime.
- The Hydra DSL panel buttons show three states: ready, busy (spinning) and unavailable.
/api/healthreturnsstudio_build; a tab running an older Studio shows New Studio version — reload.
Patches and fixes
- Studio no longer loses what the canvas does not edit. A job rebuilt from its YAML and saved again reset
batch_sizeto 1000, dropped fields such asdelimiterorencoding, and renamed source/destination keys, which changedpipeline.from/to. hdrctl validateprinted "0 error(s) detected" when the only errors were inpipeline.yaml, in strict checks or a missing file. The total now counts every error shown.pipeline.yamlis checked the way the engine reads it: old nested format, missing or emptyfrom/to, unknown keys. Same check inhdrctl run <job> --dry-run.hdrctl run <project>(and--dry-run, Studio's Check and Run project) checkspipeline.yamlof every job used by an active workflow before starting: a brokenpipeline.fromno longer passes as valid.hdrctl servesendsindex.htmlwithCache-Control: no-cache, so an update is not hidden by the browser cache.- Connector messages (CSV, JSON, Parquet, PostgreSQL, MySQL/MariaDB, SQL Server) and Studio templates are in English.
Full changelog: v0.12.2...v0.12.3
v0.12.2 — Rearrange workflow cards in Studio
New features
- Studio: the workflow cards of a project page can be rearranged by drag and drop. Grab a card by its title and drop it on another card (dashed outline) to swap them. Display only: the order is kept in
.hydra/card-order.jsonand does not changethread.yamlorhdrctl run. API:PUT /api/projects/{id}/card-order.
Patches and fixes
- None.
Full changelog: v0.12.1...v0.12.2