Poetry PEP 517 Build Backend for building Python packages with lightweight, compliant, self-contained build system
—
The factory and core Poetry modules provide central orchestration for creating and managing Poetry project instances. The Factory class serves as the main entry point for creating Poetry objects from project configurations.
from poetry.core.factory import Factory
from poetry.core.poetry import Poetry
from poetry.core.packages.project_package import ProjectPackage
from poetry.core.pyproject.toml import PyProjectTOML
``` { .api }
## Factory Class
The Factory class provides static and instance methods for creating Poetry projects and validating configurations.
### Factory.__init__
```python
class Factory:
"""Factory class to create various elements needed by Poetry."""
def __init__(self) -> None:
"""Initialize Factory instance."""
``` { .api }
### create_poetry
```python
def create_poetry(
self,
cwd: Path | None = None,
with_groups: bool = True
) -> Poetry:
"""
Create a Poetry instance from pyproject.toml configuration.
Args:
cwd: Working directory to search for pyproject.toml. If None, uses current directory.
with_groups: Whether to load dependency groups. Set False for build operations.
Returns:
Poetry instance representing the project
Raises:
RuntimeError: If Poetry configuration is invalid
PyProjectError: If pyproject.toml is missing or malformed
ValidationError: If project schema validation fails
Example:
>>> factory = Factory()
>>> poetry = factory.create_poetry()
>>> print(f"Project: {poetry.package.name}")
Project: my-package
>>> # Create from specific directory
>>> poetry = factory.create_poetry(Path("/path/to/project"))
>>> # Skip dependency groups for faster loading
>>> poetry = factory.create_poetry(with_groups=False)
"""
``` { .api }
### get_package (Class Method)
```python
@classmethod
def get_package(cls, name: str, version: str) -> ProjectPackage:
"""
Create a ProjectPackage instance with given name and version.
Args:
name: Package name
version: Package version string
Returns:
ProjectPackage instance
Example:
>>> package = Factory.get_package("my-package", "1.0.0")
>>> print(f"{package.name} v{package.version}")
my-package v1.0.0
"""
``` { .api }
### configure_package (Class Method)
```python
@classmethod
def configure_package(
cls,
package: ProjectPackage,
pyproject: PyProjectTOML,
root: Path,
with_groups: bool = True
) -> None:
"""
Configure package metadata, dependencies, and Poetry-specific settings.
Args:
package: ProjectPackage instance to configure
pyproject: PyProject TOML configuration
root: Project root directory path
with_groups: Whether to configure dependency groups
Raises:
ValidationError: If configuration is invalid
Note:
This method modifies the package in-place, setting:
- Basic metadata (description, authors, etc.)
- Dependencies and dependency groups
- Build configuration
- Entry points and scripts
- Package includes/excludes
"""
``` { .api }
### create_dependency (Class Method)
```python
@classmethod
def create_dependency(
cls,
name: str,
constraint: DependencyConstraint,
groups: list[str] | None = None,
root_dir: Path | None = None
) -> Dependency:
"""
Create various types of dependencies from constraint specifications.
Args:
name: Dependency name
constraint: Version constraint or dependency specification
groups: Dependency groups (e.g., ["dev", "test"])
root_dir: Root directory for resolving relative paths
Returns:
Appropriate Dependency subclass instance:
- Dependency: Regular version-based dependency
- VCSDependency: Git/VCS dependency
- FileDependency: Local file dependency
- DirectoryDependency: Local directory dependency
- URLDependency: URL-based dependency
Example:
>>> # Version constraint
>>> dep = Factory.create_dependency("requests", "^2.25.0")
>>> # Git dependency
>>> dep = Factory.create_dependency("mypackage", {
... "git": "https://github.com/user/repo.git",
... "branch": "main"
... })
>>> # Local path dependency
>>> dep = Factory.create_dependency("local-pkg", {"path": "./libs/local"})
"""
``` { .api }
### validate (Class Method)
```python
@classmethod
def validate(
cls,
toml_data: dict[str, Any],
strict: bool = False
) -> dict[str, list[str]]:
"""
Validate Poetry configuration against JSON schemas.
Args:
toml_data: Raw TOML data from pyproject.toml
strict: Whether to treat warnings as errors
Returns:
Dictionary containing validation results:
{
"errors": ["List of error messages"],
"warnings": ["List of warning messages"]
}
Example:
>>> from poetry.core.pyproject.toml import PyProjectTOML
>>> pyproject = PyProjectTOML(Path("pyproject.toml"))
>>> result = Factory.validate(pyproject.data)
>>> if result["errors"]:
... print("Configuration errors:", result["errors"])
>>> if result["warnings"]:
... print("Configuration warnings:", result["warnings"])
"""
``` { .api }
### locate (Class Method)
```python
@classmethod
def locate(cls, cwd: Path | None = None) -> Path:
"""
Locate pyproject.toml file in current or parent directories.
Args:
cwd: Directory to start search from. If None, uses current directory.
Returns:
Path to the pyproject.toml file
Raises:
RuntimeError: If pyproject.toml cannot be found
Example:
>>> pyproject_path = Factory.locate()
>>> print(f"Found: {pyproject_path}")
Found: /path/to/project/pyproject.toml
>>> # Search from specific directory
>>> pyproject_path = Factory.locate(Path("/some/subdirectory"))
"""
``` { .api }
## Poetry Class
The Poetry class represents a complete Poetry project context with configuration, package information, and build dependencies.
### Poetry.__init__
```python
class Poetry:
def __init__(
self,
file: Path,
local_config: dict[str, Any],
package: ProjectPackage,
pyproject_type: type[PyProjectTOML] = PyProjectTOML,
) -> None:
"""
Initialize Poetry instance.
Args:
file: Path to pyproject.toml file
local_config: Poetry configuration from [tool.poetry] section
package: ProjectPackage instance
pyproject_type: PyProjectTOML class (for testing/customization)
"""
``` { .api }
### Properties
#### pyproject
```python
@property
def pyproject(self) -> PyProjectTOML:
"""
PyProject TOML configuration object.
Returns:
PyProjectTOML instance with full project configuration
Example:
>>> poetry = Factory().create_poetry()
>>> config = poetry.pyproject
>>> print(f"Build system: {config.build_system.build_backend}")
"""
``` { .api }
#### pyproject_path
```python
@property
def pyproject_path(self) -> Path:
"""
Path to the pyproject.toml file.
Returns:
Absolute path to pyproject.toml
Example:
>>> poetry = Factory().create_poetry()
>>> print(f"Config file: {poetry.pyproject_path}")
Config file: /path/to/project/pyproject.toml
"""
``` { .api }
#### package
```python
@property
def package(self) -> ProjectPackage:
"""
Project package instance containing metadata and dependencies.
Returns:
ProjectPackage with all package information
Example:
>>> poetry = Factory().create_poetry()
>>> pkg = poetry.package
>>> print(f"{pkg.name} v{pkg.version}")
>>> print(f"Dependencies: {len(pkg.requires)}")
"""
``` { .api }
#### is_package_mode
```python
@property
def is_package_mode(self) -> bool:
"""
Whether the project is in package mode.
Returns:
True if in package mode (builds installable package),
False if in application mode (no package building)
Example:
>>> poetry = Factory().create_poetry()
>>> if poetry.is_package_mode:
... print("This project builds a package")
... else:
... print("This is an application project")
"""
``` { .api }
#### local_config
```python
@property
def local_config(self) -> dict[str, Any]:
"""
Local Poetry configuration dictionary.
Returns:
Dictionary containing [tool.poetry] section configuration
Example:
>>> poetry = Factory().create_poetry()
>>> config = poetry.local_config
>>> print(f"Name: {config.get('name')}")
>>> print(f"Version: {config.get('version')}")
"""
``` { .api }
#### build_system_dependencies
```python
@property
def build_system_dependencies(self) -> list[Dependency]:
"""
Build system dependencies from [build-system] section.
Returns:
List of Dependency objects required for building
Example:
>>> poetry = Factory().create_poetry()
>>> build_deps = poetry.build_system_dependencies
>>> for dep in build_deps:
... print(f"Build requires: {dep.name} {dep.constraint}")
"""
``` { .api }
### Methods
#### get_project_config
```python
def get_project_config(self, config: str, default: Any = None) -> Any:
"""
Get project-specific configuration value.
Args:
config: Configuration key to retrieve
default: Default value if key not found
Returns:
Configuration value or default
Example:
>>> poetry = Factory().create_poetry()
>>> cache_dir = poetry.get_project_config("cache-dir", "~/.cache")
>>> print(f"Cache directory: {cache_dir}")
"""
``` { .api }
## Type Definitions
```python
from typing import Any, Mapping, Union
from pathlib import Path
from poetry.core.packages.dependency import Dependency
# Dependency constraint types
DependencyConstraint = Union[str, Mapping[str, Any]]
DependencyConfig = Mapping[
str, Union[list[DependencyConstraint], DependencyConstraint]
]
# Configuration types
LocalConfig = dict[str, Any]
ValidationResult = dict[str, list[str]]
``` { .api }
## Complete Usage Examples
### Creating and Inspecting a Poetry Project
```python
from pathlib import Path
from poetry.core.factory import Factory
def analyze_project(project_path: Path) -> None:
"""Analyze a Poetry project and print key information."""
factory = Factory()
try:
# Create Poetry instance
poetry = factory.create_poetry(project_path)
# Project information
pkg = poetry.package
print(f"Project: {pkg.name}")
print(f"Version: {pkg.version}")
print(f"Description: {pkg.description}")
print(f"Package mode: {poetry.is_package_mode}")
# Dependencies
print(f"\nDependencies ({len(pkg.requires)}):")
for dep in pkg.requires:
print(f" {dep.name}: {dep.constraint}")
# Development dependencies
if pkg.has_dependency_group("dev"):
dev_deps = pkg.dependency_group("dev").dependencies
print(f"\nDev Dependencies ({len(dev_deps)}):")
for dep in dev_deps:
print(f" {dep.name}: {dep.constraint}")
# Build system
build_deps = poetry.build_system_dependencies
print(f"\nBuild Dependencies ({len(build_deps)}):")
for dep in build_deps:
print(f" {dep.name}: {dep.constraint}")
except Exception as e:
print(f"Error analyzing project: {e}")
# Usage
analyze_project(Path("./my-poetry-project"))
``` { .api }
### Configuration Validation
```python
from pathlib import Path
from poetry.core.factory import Factory
from poetry.core.pyproject.toml import PyProjectTOML
def validate_project_config(project_path: Path, strict: bool = False) -> bool:
"""Validate Poetry project configuration."""
try:
# Load pyproject.toml
pyproject_path = Factory.locate(project_path)
pyproject = PyProjectTOML(pyproject_path)
# Validate configuration
result = Factory.validate(pyproject.data, strict=strict)
# Report results
if result["errors"]:
print("Configuration Errors:")
for error in result["errors"]:
print(f" ❌ {error}")
if result["warnings"]:
print("Configuration Warnings:")
for warning in result["warnings"]:
print(f" ⚠️ {warning}")
# Return validation status
is_valid = not result["errors"]
if strict:
is_valid = is_valid and not result["warnings"]
print(f"\nConfiguration is {'valid' if is_valid else 'invalid'}")
return is_valid
except Exception as e:
print(f"Validation failed: {e}")
return False
# Usage
is_valid = validate_project_config(Path("./my-project"), strict=True)
``` { .api }
### Creating Dependencies Programmatically
```python
from poetry.core.factory import Factory
from pathlib import Path
def create_various_dependencies():
"""Demonstrate creating different types of dependencies."""
# Regular version dependencies
requests_dep = Factory.create_dependency("requests", "^2.25.0")
print(f"Regular: {requests_dep.name} {requests_dep.constraint}")
# Git dependency
git_dep = Factory.create_dependency("mypackage", {
"git": "https://github.com/user/repo.git",
"branch": "main",
"extras": ["dev"]
})
print(f"Git: {git_dep.name} from {git_dep.source_url}")
# Local path dependency
path_dep = Factory.create_dependency("local-lib", {
"path": "../shared-lib",
"develop": True
})
print(f"Path: {path_dep.name} from {path_dep.source_url}")
# URL dependency
url_dep = Factory.create_dependency("archive-pkg", {
"url": "https://example.com/package-1.0.0.tar.gz"
})
print(f"URL: {url_dep.name} from {url_dep.source_url}")
# Development dependency
dev_dep = Factory.create_dependency(
"pytest",
"^6.0.0",
groups=["dev", "test"]
)
print(f"Dev: {dev_dep.name} in groups {dev_dep.groups}")
create_various_dependencies()
``` { .api }
### Custom Project Creation
```python
from pathlib import Path
from poetry.core.factory import Factory
from poetry.core.packages.project_package import ProjectPackage
def create_custom_project() -> None:
"""Create a custom Poetry project programmatically."""
factory = Factory()
# Create base package
package = factory.get_package("my-custom-app", "0.1.0")
# Set metadata
package.description = "A custom application"
package.authors = ["Developer <dev@example.com>"]
package.homepage = "https://github.com/user/my-custom-app"
# Add dependencies
requests_dep = factory.create_dependency("requests", "^2.25.0")
click_dep = factory.create_dependency("click", ">=7.0")
package.add_dependency(requests_dep)
package.add_dependency(click_dep)
# Add development dependencies
pytest_dep = factory.create_dependency("pytest", "^6.0.0", groups=["dev"])
package.add_dependency(pytest_dep)
print(f"Created project: {package.name}")
print(f"Dependencies: {[d.name for d in package.requires]}")
print(f"Dev dependencies: {[d.name for d in package.dev_requires]}")
create_custom_project()
``` { .api }Install with Tessl CLI
npx tessl i tessl/pypi-poetry-core