Exporting Requirements & Bundling

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the Python Reference bibliography.

poetry.lock is read only by Poetry. When another tool has to install the locked set (pip in a container, a platform that expects requirements.txt, an auditing tool, a PEP 751 installer), export it; when the target is a ready-to-run environment, bundle it. This page uses Poetry 2.5.1, poetry-plugin-export 1.10.1 and poetry-plugin-bundle 1.8.0. The examples ran on 2026-10-22 on Linux with CPython 3.14.6 and pip 26.2.2, on the birdtally project (no main dependencies, a pretty extra pulling in rich, and test, lint, docs and dev groups). Hashes are shortened to their first eight characters (…).

Installing the export plugin

Poetry 1.2 to 1.8 depended on poetry-plugin-export, so poetry export was always there. Poetry 2.0 dropped that dependency:

poetry self add poetry-plugin-export

or declare it for the project, so that poetry install provides it to everyone working on it (see Plugins):

[tool.poetry.requires-plugins]
poetry-plugin-export = ">=1.10"

poetry export

Option Meaning

-f, --format

requirements.txt (default), constraints.txt or pylock.toml (plugin 1.10.0).

-o, --output

Write to a file instead of standard output.

--with, --only, --all-groups

Dependency groups, as for poetry install. By default only the main dependencies are exported; --only test exports a group without them.

-E, --extras, --all-extras

Extras to include.

--without-hashes

Leave out the --hash options.

--without-urls

Leave out the --extra-index-url/--trusted-host lines for the project’s sources.

--with-credentials

Write the sources' credentials into those lines.

--without, --dev

Deprecated. The README also lists a deprecated --default, which the 1.10.1 --help no longer shows.

Every line pins the locked version and carries the markers from poetry.lock, so one file serves every platform the lock covers. With no main dependencies there is nothing to export (the output is empty); with the extra:

poetry export -E pretty --without-hashes
poetry export --only test --without-hashes
markdown-it-py==4.2.0 ; python_version >= "3.10"
mdurl==0.1.2 ; python_version >= "3.10"
pygments==2.21.0 ; python_version >= "3.10"
rich==15.0.0 ; python_version >= "3.10"
colorama==0.4.6 ; python_version >= "3.10" and sys_platform == "win32"
exceptiongroup==1.3.1 ; python_version == "3.10"
iniconfig==2.3.1 ; python_version >= "3.10"
packaging==26.3 ; python_version >= "3.10"
pluggy==1.7.0 ; python_version >= "3.10"
pygments==2.21.0 ; python_version >= "3.10"
pytest==9.1.1 ; python_version >= "3.10"
tomli==2.5.0 ; python_version == "3.10"
typing-extensions==4.16.0 ; python_version == "3.10"

By default every file of every locked release is listed as a hash:

poetry export -E pretty -o requirements.txt
markdown-it-py==4.2.0 ; python_version >= "3.10" \
    --hash=sha256:04a21681… \
    --hash=sha256:9f7ebbcd…
mdurl==0.1.2 ; python_version >= "3.10" \
    --hash=sha256:84008a41… \
    --hash=sha256:bb413d29…
pygments==2.21.0 ; python_version >= "3.10" \
    --hash=sha256:2363c69b… \
    --hash=sha256:610ca751…
rich==15.0.0 ; python_version >= "3.10" \
    --hash=sha256:33bd4ef7… \
    --hash=sha256:edd07a48…

-f constraints.txt has the same lines, for use with pip install -c (see pip: Constraints & Build Constraints). -f pylock.toml writes a PEP 751 lock file; its content is shown on Lock Files & Reproducible Installs.

Installing an export with pip

Poetry has already resolved everything, so install with --no-deps: pip must not resolve again (and can fail to, for example with git dependencies exported at their commit). Hashes make pip check every file:

python -m venv .venv
.venv/bin/python -m pip install --no-deps --require-hashes -r requirements.txt
.venv/bin/python -m pip install --no-deps dist/birdtally-0.1.0-py3-none-any.whl
Installing collected packages: rich, pygments, mdurl, markdown-it-py

Successfully installed markdown-it-py-4.2.0 mdurl-0.1.2 pygments-2.21.0 rich-15.0.0
…
Successfully installed birdtally-0.1.0

The project itself is not in the export; install its wheel (or pip install --no-deps .) after the dependencies. This two-step install is the basis of the container recipes on CI Caching & Containers.

Private sources

The project’s sources become index options. For birdtally-report, which takes birdtally from the explicit, authenticated birdwatch source over plain HTTP:

poetry export --without-hashes
poetry export --without-hashes --with-credentials
--trusted-host 127.0.0.1:8082
--extra-index-url http://127.0.0.1:8082/simple

attrs==26.1.0 ; python_version >= "3.13"
birdtally==0.1.0 ; python_version >= "3.13"
--trusted-host birdwatch:<password>@127.0.0.1:8082
--extra-index-url http://birdwatch:<password>@127.0.0.1:8082/simple

attrs==26.1.0 ; python_version >= "3.13"
birdtally==0.1.0 ; python_version >= "3.13"

(the real password replaced by <password>). Three things to notice:

  • An explicit source becomes an --extra-index-url, and pip merges all indexes: the per-package source constraint is lost, so the exported file is exposed to dependency confusion that poetry.lock was not. Prefer --require-hashes (a look-alike release fails the hash check) or --without-urls with a single index set in pip’s configuration.

  • --with-credentials writes the password into the file in plain text, here even into the --trusted-host line. Do not commit such a file; pass credentials to pip through .netrc or keyring instead (see pip: Authentication, Proxies & Certificates).

  • --trusted-host appears because the source uses http://.

poetry bundle venv

poetry-plugin-bundle installs the project and its locked dependencies, not as editable, into a new virtual environment: an application ready to copy into a container image or onto a server with the same Python.

poetry self add poetry-plugin-bundle
poetry bundle venv --python=python3.14 --only=main /opt/birdtally
/opt/birdtally/bin/birdtally --help
  • Bundling birdtally (0.1.0) into /opt/birdtally
  • Bundling birdtally (0.1.0) into /opt/birdtally: Creating a virtual environment using Python …/python3.14
  • Bundling birdtally (0.1.0) into /opt/birdtally: Installing dependencies
  • Bundling birdtally (0.1.0) into /opt/birdtally: Installing birdtally (0.1.0)
  • Bundled birdtally (0.1.0) into /opt/birdtally
usage: birdtally [-h] [--by {species,site}] [--pretty] csv

(the target directory shown as /opt/birdtally; the run used a scratch directory). The bundled environment held only birdtally and pip. Options: --with, --without, --only for groups; -p/--python for the interpreter; --clear to empty an existing environment first (without it, a second run installs over existing file); --compile; and the experimental --platform to pick wheels for another platform. Version 1.8.0 has no option for extras.

Like the export plugin, it can be declared for a project instead of installed globally:

[tool.poetry.requires-plugins]
poetry-plugin-bundle = ">=1.8"

Compared with pip

pip has nothing to export: its lock formats are the inputs (requirements.txt with == and --hash, produced by pip-tools or pip freeze, and pylock.toml from the experimental pip lock). See pip: Repeatable & Secure Installs and pip: pip lock & pylock.toml.