بنقرة واحدة
deploy-workspace
// Deploy dlt pipelines to dltHub Platform. Use when the user says "deploy to dltHub", "launch on dltHub", "run on dltHub", "schedule pipeline", or wants to deploy a pipeline or notebook to dltHub.
// Deploy dlt pipelines to dltHub Platform. Use when the user says "deploy to dltHub", "launch on dltHub", "run on dltHub", "schedule pipeline", or wants to deploy a pipeline or notebook to dltHub.
ALWAYS read and follow this skill before acting. Data quality conventions
ALWAYS read and follow this skill before acting. Data quality workflow
ALWAYS read and follow this skill before acting. Profiles
ALWAYS read and follow this skill before acting. Deploy to dltHub Platform
ALWAYS read and follow this skill before acting. Filesystem pipeline workflow
Prepare production credentials and destinations for dltHub Platform. Use when setting up prod profile secrets, splitting dev/prod credentials, or configuring a production destination like Motherduck.
| name | deploy-workspace |
| description | Deploy dlt pipelines to dltHub Platform. Use when the user says "deploy to dltHub", "launch on dltHub", "run on dltHub", "schedule pipeline", or wants to deploy a pipeline or notebook to dltHub. |
If this is a first deployment, complete (setup-runtime) and (prepare-deployment) first — they set up the workspace, configure credentials, and log in to runtime. Otherwise, continue from here.
Review each script being deployed and fix patterns that are safe locally but harmful in production:
dev_mode=True from dlt.pipeline() calls — it drops and recreates the dataset on every run, destroying production data.limit=N parameters, .add_limit(N) calls, or hardcoded date ranges meant for testing. Either remove them or make them configurable (e.g. via dlt.config.value).write_disposition — "replace" is fine for full-refresh pipelines, but confirm the user doesn't actually want "merge" or "append" for incremental loads.if __name__ == "__main__": block — every script must have one or the runtime job does nothing. The block should NOT contain interactive/debug-only code.pyproject.toml — use == not >= to prevent unexpected upgrades on runtime. If user has a pre-release (e.g. 1.23.0a3), use uv pip install to install it and pin with == in pyproject (do NOT use uv add which may downgrade to latest stable).marimo apps):
dlt.attach() (not dlt.pipeline()) and that destination and dataset_name are explicitly passed (this is a temporary limitation of the dltHub Platform) altair, ibis-framework, pandas, etc.) are in pyproject.tomlReference: scheduling-triggers.md | advanced-patterns.md
SKIP for simple workspaces without deployment manifest
If __deployment__.py is set up, first run dlthub deploy --dry-run to preview changes, then STOP — show the plan and get approval from the user before deploying.
dlthub deploy # synchronizes deployment module with runtime
Summarize the output (which jobs created/updated/archived)
dlthub run my_pipeline.py # sync code + run batch job on cloud
dlthub run my_pipeline.py -f # sync + run, stream logs while running
dlthub run my_pipeline.py --refresh # sync + run with a refresh signal
dlthub serve my_notebook.py # sync code + run interactive job on cloud
dlthub serve my_notebook.py -f # sync + serve, stream logs
dlthub local run <job_name> # run locally (uses deployment manifest, no sync)
dlthub local run <job_name> --profile prod # run under a specific profile
dlthub local run <job_name> --start 2024-01-01 --end 2024-02-01 # interval override (ISO 8601)
dlthub local run <job_name> --config KEY=VALUE # ad-hoc config override (short: -c)
dlthub local run <job_name> --dry-run # resolve entry point without launching
dlthub local serve my_notebook.py # serve locally
dlthub job logs my_pipeline # check output (use job name)
dlthub job logs my_pipeline -f # stream logs in real-time
After launching:
dlthub job logsdebug-deployment) to diagnosedlthub show to open the dltHub web UI and show the user their pipeline is liveScheduling requires a __deployment__.py manifest. Go back to (prepare-deployment) and execute Step 5 if not yet done.
Add a trigger to the @run.pipeline decorator:
from dlt.hub import run
from dlt.hub.run import trigger
@run.pipeline("my_pipeline", trigger=trigger.schedule("0 0 * * *")) # daily at midnight UTC
def run_my_pipeline():
pipeline = dlt.pipeline(
pipeline_name="my_pipeline",
destination="warehouse",
dataset_name="my_dataset",
)
pipeline.run(my_source())
A bare cron string also works: trigger="0 0 * * *".
Then deploy:
dlthub deploy # sync manifest to Runtime
dlthub deploy --dry-run # preview without applying
dlthub job list # confirm triggers are set
Other trigger types (from dlt.hub.run.trigger):
trigger.every("6h") -- every 6 hourstrigger.once("2026-12-31T23:59:59Z") -- one-shot at a timestampupstream_job.success -- chain after another job succeeds (followup trigger)Notes:
dlthub deploy reconciles all jobs -- new ones are added, removed ones are archived, unchanged ones are left alone.See scheduling-triggers.md for the full trigger types table and more examples.
See advanced-patterns.md for full examples of each pattern:
trigger=ingest_job.success. The transform runs automatically after ingest succeeds. Use when you have non-incremental pipelines that should run in sequence.interval={"start": "2026-01-01T00:00:00Z"} and read run_context["interval_start"] / interval_end from the scheduler. Runtime handles continuity and refresh resets.freshness=[upstream.is_fresh] prevents a job from running until upstream's interval is complete. Use for transforms that shouldn't observe half-loaded data.refresh="always" cascades a full-refresh signal to all downstream jobs without loading data itself.@run.job for general batch work (DQ checks, reports), @run.interactive for MCP servers, dashboards, REST APIs.require={"dependency_groups": ["ibis"]} installs extra packages only for jobs that need them. Declare groups in [dependency-groups] in pyproject.toml.execute={"timeout": "6h"} overrides the default 120-minute limit. Use for backfill or long-running jobs.Share an interactive job (notebook or dashboard) publicly:
dlthub job publish <job_name> # generate a public URL
dlthub job unpublish <job_name> # revoke public access
Note: the argument is a job name (e.g.
my_notebook), not a file path. Drop any.pyextension — passingmy_notebook.pywill fail because the CLI looks for a job literally namedmy_notebook.py.
if __name__ == "__main__": or the job does nothing.pyproject.toml — add all needed packages (e.g. uv add numpy pandas if using .df()).