Poetry plugin to export the dependencies to various formats
npx @tessl/cli install tessl/pypi-poetry-plugin-export@1.9.0A Poetry plugin that extends Poetry's functionality by providing an export command to convert locked dependencies from poetry.lock files into various standardized formats like requirements.txt and constraints.txt. The plugin serves as a bridge between Poetry's modern dependency management system and traditional pip-based workflows.
poetry self add poetry-plugin-export or via pipx: pipx inject poetry poetry-plugin-exportfrom poetry_plugin_export.exporter import Exporter
from poetry_plugin_export.command import ExportCommand
from poetry_plugin_export.plugins import ExportApplicationPluginFor version information:
from poetry_plugin_export import __version__For walker utilities:
from poetry_plugin_export.walker import get_project_dependency_packages, get_project_dependency_packages2The plugin is primarily used through Poetry's CLI command interface:
# Export to requirements.txt
poetry export -f requirements.txt --output requirements.txt
# Export to constraints.txt
poetry export -f constraints.txt --output constraints.txt
# Export with extras and specific dependency groups
poetry export -f requirements.txt -E web -E dev --with test --output requirements.txtFor programmatic usage:
from poetry_plugin_export.exporter import Exporter
from cleo.io.buffered_io import BufferedIO
from poetry.factory import Factory
# Load Poetry project
poetry = Factory().create_poetry("path/to/project")
io = BufferedIO()
# Create and configure exporter
exporter = Exporter(poetry, io)
exporter.with_extras(["web", "dev"])
exporter.only_groups(["main", "test"])
exporter.with_hashes(True)
# Export to file
from pathlib import Path
exporter.export("requirements.txt", Path.cwd(), "requirements.txt")The plugin integrates with Poetry through the plugin system and provides:
Poetry plugin system integration providing the export command to Poetry installations.
class ExportApplicationPlugin(ApplicationPlugin):
"""Main plugin class for Poetry integration."""
@property
def commands(self) -> list[type[Command]]:
"""Returns list containing ExportCommand."""
def activate(self, application: Application) -> None:
"""Activates plugin and registers export command."""CLI command interface for exporting dependencies with comprehensive option support.
class ExportCommand(GroupCommand):
"""CLI command for exporting dependencies to various formats."""
name: str = "export"
description: str = "Exports the lock file to alternative formats."
@property
def default_groups(self) -> set[str]:
"""Returns default dependency groups to include."""
def handle(self) -> int:
"""Main command execution logic."""The export command supports extensive configuration through command-line options:
--format (-f): Export format (requirements.txt, constraints.txt)--output (-o): Output file path--without-hashes: Exclude package hashes--without-urls: Exclude repository URLs--with-credentials: Include credentials for private repositories--extras (-E): Include specific extra dependency sets--all-extras: Include all extra dependencies--with: Include specific dependency groups--only: Include only specified dependency groups--all-groups: Include all dependency groups--dev: Include development dependencies (deprecated)--without: Exclude dependency groups (deprecated)Main export functionality with fluent configuration API supporting multiple output formats.
class Exporter:
"""Core exporter class for converting lock files to different formats."""
FORMAT_CONSTRAINTS_TXT: str = "constraints.txt"
FORMAT_REQUIREMENTS_TXT: str = "requirements.txt"
ALLOWED_HASH_ALGORITHMS: tuple = ("sha256", "sha384", "sha512")
def __init__(self, poetry: Poetry, io: IO) -> None:
"""Initialize exporter with Poetry instance and IO handler."""
@classmethod
def is_format_supported(cls, fmt: str) -> bool:
"""Check if the specified format is supported for export."""
def with_extras(self, extras: Collection[NormalizedName]) -> Exporter:
"""Configure exporter to include specified extra dependency sets."""
def only_groups(self, groups: Iterable[str]) -> Exporter:
"""Configure exporter to include only specified dependency groups."""
def with_urls(self, with_urls: bool = True) -> Exporter:
"""Configure whether to include repository URLs in output."""
def with_hashes(self, with_hashes: bool = True) -> Exporter:
"""Configure whether to include package hashes in output."""
def with_credentials(self, with_credentials: bool = True) -> Exporter:
"""Configure whether to include repository credentials in output."""
def export(self, fmt: str, cwd: Path, output: IO | str) -> None:
"""Export dependencies to specified format and output destination."""Utilities for walking and resolving dependencies from Poetry lock files.
def get_project_dependency_packages(
locker: Locker,
project_requires: list[Dependency],
root_package_name: NormalizedName,
project_python_marker: BaseMarker | None = None,
extras: Collection[NormalizedName] = ()
) -> Iterator[DependencyPackage]:
"""Get dependency packages for a project (legacy method)."""
def get_project_dependency_packages2(
locker: Locker,
project_python_marker: BaseMarker | None = None,
groups: Collection[str] = (),
extras: Collection[NormalizedName] = ()
) -> Iterator[DependencyPackage]:
"""Get dependency packages for a project (modern method for locked groups/markers)."""
def get_project_dependencies(
project_requires: list[Dependency],
locked_packages: list[Package],
root_package_name: NormalizedName
) -> Iterable[tuple[Package, Dependency]]:
"""Get project dependencies as package/dependency tuples."""
def walk_dependencies(
dependencies: list[Dependency],
packages_by_name: dict[str, list[Package]],
root_package_name: NormalizedName
) -> dict[Package, Dependency]:
"""Walk dependency tree to resolve all nested dependencies."""Additional utility functions for dependency resolution.
def get_locked_package(
dependency: Dependency,
packages_by_name: dict[str, list[Package]],
decided: dict[Package, Dependency] | None = None
) -> Package | None:
"""Find locked package matching dependency constraints."""
def get_python_version_region_markers(packages: list[Package]) -> list[BaseMarker]:
"""Generate markers for Python version regions from packages."""from typing import Collection, Iterable, Iterator
from pathlib import Path
from packaging.utils import NormalizedName
from poetry.poetry import Poetry
from poetry.packages import Locker
from poetry.core.packages.dependency import Dependency
from poetry.core.packages.package import Package
from poetry.core.version.markers import BaseMarker
from poetry.packages import DependencyPackage
from cleo.io.io import IO
# Module-level attributes
__version__: str # Package version
class DependencyWalkerError(Exception):
"""Exception raised when dependency walking fails."""The plugin handles various error conditions:
ValueError if unsupported format is specifiedpoetry lock if lock file doesn't existDependencyWalkerError for unresolvable dependenciesCommon error scenarios:
# Check format support before export
if not Exporter.is_format_supported("invalid-format"):
raise ValueError("Invalid export format: invalid-format")
# Handle dependency walker errors
try:
packages = list(get_project_dependency_packages(...))
except DependencyWalkerError as e:
print(f"Dependency resolution failed: {e}")