Practical Postgres 🐘 CDC with StreamkapLivestream July 15

Skip to main content

Running Python with Flights

Preview
This feature is in preview and is subject to change.

A Flight is a Python program that runs on MotherDuck, on demand or on a recurring schedule. Use Flights to pull data in from external sources, refresh aggregates, run dbt, scrape a page, or post a scheduled summary to Slack.

Flights complement SQL: where SQL handles transformation against your tables, Flights add everything Python can do (HTTP calls, the full PyPI ecosystem, file processing, custom logic) right next to your data.

info

For scheduled or production-like Flights, test with an on-demand run first, use a service account token instead of a personal token, and keep the Flight's database permissions as narrow as the workload allows.

Anatomy of a Flight

FieldWhat it is
NameHuman-readable identifier shown in the UI and logs.
Source codeA single-file Python program. The runtime executes it as a plain script, so end it with if __name__ == "__main__": main() to invoke your entrypoint.
RequirementsA requirements.txt-style list of pip packages, one per line.
MotherDuck tokenThe name of an access token. MotherDuck injects the token value into the Flight as the MOTHERDUCK_TOKEN environment variable.
ConfigA map of non-sensitive key/value pairs surfaced to the Flight as environment variables (for example, a region or a batch size).
ScheduleA standard 5-field cron expression in UTC. Omit to make the Flight on-demand only.

Each edit to source code, requirements, config, or the token produces a fresh version. Renaming a Flight or changing its schedule is a metadata-only update and does not produce one.

Create your first Flight

Connect the MotherDuck MCP Server to your AI assistant, then ask it to create a Flight:

"Create a Flight named heartbeat that connects to MotherDuck, creates docs_playground.heartbeat if it doesn't exist, inserts one row, and prints how many rows it wrote. Use the latest MotherDuck-supported DuckDB version in the requirements."

The agent will call create_flight with the right source_code and requirements_txt. It can then call run_flight to trigger an immediate run and get_flight_run_logs to read the output back into the conversation.

You can iterate with the agent the same way you would on a script: "add a config value for the table name and use it instead of hard-coding heartbeat."

What happens when a Flight runs

When you trigger a run (manually or on schedule), MotherDuck:

  1. Allocates a Python runtime for the Flight.
  2. Injects MOTHERDUCK_TOKEN and your config keys into the environment.
  3. Installs the packages in requirements.txt.
  4. Executes main(), capturing stdout and stderr.
  5. Records the run's status and logs.

Runs are asynchronous. A new run starts in RUN_STATUS_PENDING, moves to RUN_STATUS_RUNNING, and ends in one of RUN_STATUS_SUCCEEDED, RUN_STATUS_FAILED, or RUN_STATUS_CANCELLED. Poll for completion with list_flight_runs (MCP) or MD_LIST_FLIGHT_RUNS (SQL).

Versioning

Every edit to a Flight's content fields (source_code, requirements_txt, config, or the access token) produces a fresh version. Renames and schedule changes do not.

When a run starts, it locks to the version that was current at that moment. If you update the Flight while a run is in progress, that run finishes against the version it started with; only the next run picks up the updated source.

You can browse versions in the MotherDuck UI or read them programmatically with list_flight_versions and get_flight (passing a specific version number).

  • Flights concept — the mental model and where Flights fit alongside SQL, Dives, and external orchestrators.
  • MotherDuck MCP Servercreate_flight, run_flight, and the rest of the Flight tool surface for AI agents.