Pixi Connection¶
The Pixi connection type holds the credentials of a private conda channel or PyPI index, such as a
channel on prefix.dev, on anaconda.org, or in Artifactory or Nexus. Operators
that run pixi on the worker use it through pixi_conn_id; the hook is
PixiHook.
Configuring the connection¶
- Host
- The host of the channel or index, such as
repo.prefix.dev. A URL is reduced to its host name, sohttps://repo.prefix.dev/my-channelworks too.*.prefix.devmatches every subdomain, for conda channels only. - Username (login)
- The username, for
basic_httpandnetrc. Leave it empty for a token. - Password
- The token, or the password for
basic_httpandnetrc. Required. It is masked in the task log. - Auth type
-
How pixi sends the credentials:
auth_typeSent as Typical server auto(default)basic_httpif the connection has a username, otherwisebearer_tokenbearer_tokenan Authorization: Bearer <token>headerprefix.dev conda_tokenthe token in the channel URL anaconda.org, quetz basic_httpHTTP basic authentication Artifactory, Nexus netrca netrc entry, for a PyPI index any index that takes a username and password On Airflow 3.2 and newer, the connection form has an Auth type field for it and no Extra field. On Airflow 3.1, the form has no Auth type field: put a JSON object in Extra instead, such as
{"auth_type": "conda_token"}. Outside the form, on every version,auth_typegoes into the extra, as in the examples below.
Schema and Port are not used.
Examples¶
A prefix.dev token, as an environment variable of the workers:
export AIRFLOW_CONN_PREFIX_DEV='{"conn_type": "pixi", "host": "repo.prefix.dev", "password": "pfx_..."}'
A username and password for Artifactory, with the CLI:
airflow connections add artifactory \
--conn-type pixi \
--conn-host artifactory.example.com \
--conn-login ci-user \
--conn-password "$ARTIFACTORY_PASSWORD"
An anaconda.org token:
airflow connections add anaconda \
--conn-type pixi \
--conn-host conda.anaconda.org \
--conn-password "$ANACONDA_TOKEN" \
--conn-extra '{"auth_type": "conda_token"}'
A private PyPI index. The index itself goes, without credentials, into the [pypi-options] table
of the project's pixi.toml, for example extra-index-urls = ["https://pypi.example.com/simple"],
and the task uses that project with pixi_project_path or pixi_toml_path:
airflow connections add private_pypi \
--conn-type pixi \
--conn-host pypi.example.com \
--conn-login ci-user \
--conn-password "$PYPI_PASSWORD" \
--conn-extra '{"auth_type": "netrc"}'
Using the connection¶
Pass one connection id, or a list with one connection per host:
PixiOperator(
task_id="train",
pixi_project_path="training-env",
lock_mode="locked",
python_callable="train:main",
pixi_conn_id=["prefix_dev", "private_pypi"],
)
pixi_conn_id works for PixiOperator, @task.pixi,
PixiBashOperator, @task.pixi_bash, PixiTaskOperator,
PixiSensor and @task.pixi_sensor, and can be set for every task through
default_args. Two connections for the same host fail the task.
How the credentials reach pixi¶
Pixi reads conda channel credentials from a JSON file and PyPI index credentials from a netrc file (pixi's authentication docs). For each run, the operator reads the connections, writes the credentials it needs to temporary files readable only by the worker's user, and points pixi at them:
RATTLER_AUTH_FILE, for every connection exceptnetrcones. While it is set, pixi reads no other credentials, so the file also holds the entries of the credentials file pixi would read otherwise: the oneRATTLER_AUTH_FILEnamed before, or~/.rattler/credentials.json. A connection replaces an entry for the same host. Credentials in the system keychain, such as those stored bypixi auth loginon a desktop, are not copied.NETRC, fornetrcconnections. The file starts with the connections' entries, followed by the netrc fileNETRCnamed before, or~/.netrc. Keep a host in one of the two, since netrc readers differ in which entry they use when a host appears twice.
Both files are removed when the run ends, also when it fails. The values never pass through templates.
Other credentials¶
For credentials that are not a channel's or an index's, such as a database password the callable
needs, use env_from_connections with a connection of any type; see
Environment variables.