Skip to main content

Local mode

autoair local runs the standalone server with a settings preset for a single user on a workstation. It needs no Airflow server: you design, validate, preview and deploy DAG files, then run them in an Airflow of your choice.

Install and start​

autoair local needs the standalone extra (uvicorn) and something to put in the operator palette. The airflow extra installs Apache Airflow and the standard provider, which gives you BashOperator, PythonOperator, EmptyOperator, the standard sensors and the DagBag import check.

# one-off, with uv
uvx --from 'autoair[standalone,airflow]' autoair local --open

# or in a virtual environment
python -m venv .venv && . .venv/bin/activate
pip install 'autoair[standalone,airflow,format]'
autoair local --open

Released versions come from PyPI (published by the release workflow on v* tags). For an unreleased commit, install the wheel built by make build (pip install 'dist/autoair-<version>-py3-none-any.whl[standalone,airflow]') or run from a source checkout.

From a source checkout, uv sync installs the development group (which already contains Airflow and uvicorn); build the frontend once:

uv sync
(cd frontend && npm ci && npm run build)
uv run autoair local --open

The command prints where it writes and a sign-in link with a random access token created for this run:

AutoAir (local mode): DAGs in dags
Open http://127.0.0.1:8765/ui/#token=autoair-local-...
(this per-run link signs you in; keep it to yourself)

--open opens that link. The UI keeps the token for the browser tab and removes it from the address bar; the token sits in the URL fragment, which the browser never sends to a server. The holder of the token gets local.roles (default ["Admin"]: edit, validate, deploy). Other programs and web pages on your machine cannot use the API without it. After a restart the old link no longer works: open the new one.

warning

uvx autoair local without extras does not start: the core package has no HTTP server. The command exits with code 1 and says which extras to install: "autoair local needs an HTTP server, which comes with the 'standalone' extra (uvicorn). Install it with: pip install 'autoair[standalone,airflow]'", followed by the uvx --from 'autoair[standalone,airflow]' autoair local --open form. Without Airflow or providers installed, the palette shows no operators.

Options​

OptionEnvironment variableDefaultEffect
--dags-folder PATH(sets AUTOAIR_DAGS_FOLDER)./dagsFolder the spec and generated files are written to. Local mode writes directly into it (no autoair/ sub-folder).
--host HOST127.0.0.1Bind address. Keep it on loopback.
--port PORT8765Port.
--token TOKENAUTOAIR_LOCAL__TOKENa random token per runRequire this access token instead of a generated one. The sign-in page shows "This local server requires an access token (autoair local --token)." API clients send Authorization: Bearer <token>.
--no-tokenoffServe without authentication (loopback only). Visitors get iam.anonymous_roles, default ["Viewer"] (read-only); set AUTOAIR_IAM__ANONYMOUS_ROLES='["Admin"]' to let them edit and deploy. Requests whose Host or Origin is not a loopback address (or the host of server.public_url) get 403.
(config only)AUTOAIR_LOCAL__ROLES["Admin"]AutoAir roles of the token holder; never deploy:direct_push.
--open / --no-openAUTOAIR_LOCAL__OPEN_BROWSERoffOpen the UI in the default browser once /api/health answers.
--config FILE, -c FILEAUTOAIR_CONFIG_FILEnoneConfiguration file (YAML, JSON, INI, Python); repeatable.

Binding anything other than a loopback address requires a token you set yourself:

autoair local --host 0.0.0.0 --token "$(openssl rand -hex 16)"

Without a token the command exits with code 2: refusing to serve 0.0.0.0 without --token: local mode has no other authentication.

What the preset changes​

Local mode applies these settings on top of your configuration:

SettingValue in local modeConsequence
modelocal
dags_folder / subfolder--dags-folder (default dags) / emptyFiles go straight into the folder; AutoAir state goes into <dags_folder>/.autoair
features.runs, features.test_runs, features.airflowfalseNo trigger, backfill, clear, test runs, run overlay, task logs, connection/pool/variable pickers, DAG status, or import from Airflow
catalog_strategystaticOperators are found by parsing installed packages, nothing is imported
import_check_on_deploytrue only when Airflow is importableDeploys run the DagBag import check if Airflow is installed
dagbag_poolfalseOne import check at a time, no warm worker pool
sso.enabledfalseNo Airflow sign-in

Everything else (policy rules, environments, templates, AI, a Git deploy target) is configured as usual. For example, to deploy to a Git repository instead of ./dags:

export AUTOAIR_STORAGE__MODE=git
export AUTOAIR_STORAGE__GIT__PROVIDER=local
export AUTOAIR_STORAGE__GIT__REPO=git@github.com:acme/airflow-dags.git
export AUTOAIR_STORAGE__GIT__SUBDIR=dags
export AUTOAIR_STORAGE__GIT__MODE=push
autoair local

provider=local drives the git command-line tool against any remote and pushes the pending branch without opening a pull request. github, gitlab, bitbucket and azure use the host's REST API, and gitea (Gitea or Forgejo) pushes with the git CLI and opens pull requests through the Gitea API; these five open pull requests in storage.git.mode=pr (the default) with AUTOAIR_STORAGE__GIT__TOKEN. See Deploy and Git bundles.

Adding operators​

The palette lists what is installed next to AutoAir. Add providers to the same environment:

uvx --from 'autoair[standalone,airflow]' \
--with apache-airflow-providers-amazon \
--with apache-airflow-providers-common-sql \
autoair local

Custom operators in a folder are found with AUTOAIR_CUSTOM_OPERATOR_PATHS='["/path/to/include"]', and internal operator packages with AUTOAIR_EXTRA_OPERATOR_PACKAGES or AUTOAIR_EXTRA_OPERATOR_DISTRIBUTIONS. The catalog is cached on disk (AUTOAIR_CACHE_DIR, default $XDG_CACHE_HOME/autoair) and rebuilt when the installed packages change. See Catalog sources.

Running the DAGs​

Local mode does not talk to Airflow. To run what you built, point an Airflow at the same folder (for example AIRFLOW__CORE__DAGS_FOLDER=$PWD/dags airflow standalone) or push to the repository your Airflow reads. When you need runs, logs and pickers inside AutoAir, switch to the plugin or standalone mode; specs written in local mode are read unchanged.

Security notes​

  • Anyone holding the token has local.roles (default Admin). Do not share the sign-in link; with --token keep the token secret.
  • With --no-token, anyone who can reach the loopback port has iam.anonymous_roles (default Viewer). Other users of a shared machine can reach it.
  • Python task bodies and inline functions are imported by the DagBag check in a subprocess on your machine. Do not deploy specs from untrusted sources without reviewing them.