Python Development Workflow for Humans.
—
Core Project class for programmatic management of Pipfiles, lockfiles, and project metadata. The Project class serves as the central API for interacting with pipenv projects, handling file operations, package tracking, and project configuration.
Create and initialize Project instances for managing pipenv projects.
class Project:
def __init__(self, python_version=None, chdir=True):
"""
Initialize a Project instance.
Parameters:
python_version (str, optional): Specific Python version to use
chdir (bool): Whether to change to project directory
"""Usage examples:
from pipenv.project import Project
# Initialize project in current directory
project = Project()
# Initialize with specific Python version
project = Project(python_version="3.9")
# Initialize without changing directory
project = Project(chdir=False)Access project metadata and locations.
class Project:
# Project identification
name: str # Project name
project_directory: str # Project root directory
# File locations
pipfile_location: str # Path to Pipfile
lockfile_location: str # Path to Pipfile.lock
virtualenv_location: str # Path to virtual environment
# Parsed content
parsed_pipfile: dict # Parsed Pipfile content
lockfile_content: dict # Parsed lockfile content
# Package collections
packages: dict # Regular packages from Pipfile
dev_packages: dict # Development packages from Pipfile
sources: list # Package sources/indexes
# Environment access
environment: Environment # Project's Environment instanceUsage examples:
project = Project()
# Access project information
print(f"Project name: {project.name}")
print(f"Project directory: {project.project_directory}")
print(f"Pipfile location: {project.pipfile_location}")
print(f"Virtual environment: {project.virtualenv_location}")
# Check packages
print(f"Regular packages: {list(project.packages.keys())}")
print(f"Dev packages: {list(project.dev_packages.keys())}")
print(f"Package sources: {project.sources}")
# Access environment
env = project.environment
print(f"Python interpreter: {env.python}")Create, read, and modify Pipfile configurations.
class Project:
def create_pipfile(self, python=None):
"""
Create a new Pipfile.
Parameters:
python (str, optional): Python version specification
"""
def get_pipfile_section(self, section):
"""
Get a specific section from the Pipfile.
Parameters:
section (str): Section name ('packages', 'dev-packages', 'requires', 'scripts')
Returns:
dict: Section content
"""
def write_toml(self, data, path=None):
"""
Write TOML data to Pipfile.
Parameters:
data (dict): TOML data to write
path (str, optional): Custom path for Pipfile
"""Usage examples:
project = Project()
# Create new Pipfile
project.create_pipfile(python="3.9")
# Get Pipfile sections
packages = project.get_pipfile_section("packages")
dev_packages = project.get_pipfile_section("dev-packages")
scripts = project.get_pipfile_section("scripts")
# Write modified Pipfile
pipfile_data = {
"packages": {"requests": "*"},
"dev-packages": {"pytest": "*"},
"requires": {"python_version": "3.9"}
}
project.write_toml(pipfile_data)Add, remove, and modify packages in Pipfile.
class Project:
def add_package_to_pipfile(self, package, pip_line, dev=False, category=None):
"""
Add a package to Pipfile.
Parameters:
package (str): Package name
pip_line (str): Package specification (version, VCS URL, etc.)
dev (bool): Add as development dependency
category (str, optional): Package category
"""
def remove_package_from_pipfile(self, package_name, category):
"""
Remove a package from Pipfile.
Parameters:
package_name (str): Name of package to remove
category (str): Package category ('packages' or 'dev-packages')
"""
def add_packages_to_pipfile_batch(self, packages_data, dev=False, categories=None):
"""
Add multiple packages to Pipfile in batch operation.
Parameters:
packages_data (list): List of package specifications
dev (bool): Add as development dependencies
categories (list, optional): Package categories
"""Usage examples:
project = Project()
# Add single package
project.add_package_to_pipfile("requests", "requests>=2.25.0")
project.add_package_to_pipfile("pytest", "pytest>=6.0.0", dev=True)
# Add package from VCS
project.add_package_to_pipfile("mypackage", "git+https://github.com/user/repo.git")
# Remove package
project.remove_package_from_pipfile("requests", "packages")
project.remove_package_from_pipfile("pytest", "dev-packages")
# Batch add packages
packages_data = [
("requests", "requests>=2.25.0"),
("click", "click>=7.0.0")
]
project.add_packages_to_pipfile_batch(packages_data)Handle Pipfile.lock operations for deterministic builds.
class Project:
def load_lockfile(self, expand_env_vars=True):
"""
Load and parse Pipfile.lock.
Parameters:
expand_env_vars (bool): Expand environment variables in lockfile
Returns:
dict: Parsed lockfile content
"""
def write_lockfile(self, content):
"""
Write lockfile content to Pipfile.lock.
Parameters:
content (dict): Lockfile data to write
"""
def lockfile(self, categories=None):
"""
Get lockfile data for specific categories.
Parameters:
categories (list, optional): Specific categories to include
Returns:
dict: Lockfile data
"""Usage examples:
project = Project()
# Load existing lockfile
lockfile_data = project.load_lockfile()
print(f"Lockfile hash: {lockfile_data.get('_meta', {}).get('hash')}")
# Access locked packages
locked_packages = lockfile_data.get("default", {})
dev_locked = lockfile_data.get("develop", {})
# Write updated lockfile
new_lockfile = {
"_meta": {"hash": {"sha256": "..."}},
"default": {"requests": {"version": "==2.25.1"}},
"develop": {"pytest": {"version": "==6.2.2"}}
}
project.write_lockfile(new_lockfile)
# Get specific categories
production_lock = project.lockfile(categories=["default"])Manage package categories and organization.
class Project:
def get_package_categories(self, for_lockfile=False):
"""
Get available package categories.
Parameters:
for_lockfile (bool): Get categories for lockfile format
Returns:
list: Available package categories
"""Usage examples:
project = Project()
# Get Pipfile categories
pipfile_categories = project.get_package_categories(for_lockfile=False)
print(f"Pipfile categories: {pipfile_categories}") # ['packages', 'dev-packages']
# Get lockfile categories
lockfile_categories = project.get_package_categories(for_lockfile=True)
print(f"Lockfile categories: {lockfile_categories}") # ['default', 'develop']Handle path resolution and file operations.
class Project:
def path_to(self, p):
"""
Convert relative path to absolute path within project.
Parameters:
p (str): Relative path
Returns:
Path: Absolute path object
"""Usage examples:
from pathlib import Path
project = Project()
# Convert relative paths
abs_path = project.path_to("src/mymodule.py")
print(f"Absolute path: {abs_path}")
# Work with Path objects
config_path = project.path_to("config.ini")
if config_path.exists():
content = config_path.read_text()Access and manage the project's virtual environment.
class Project:
def get_environment(self, allow_global=False):
"""
Get the project's Environment instance.
Parameters:
allow_global (bool): Allow global Python environment
Returns:
Environment: Project's environment instance
"""Usage examples:
project = Project()
# Get project environment
env = project.get_environment()
print(f"Python executable: {env.python}")
print(f"Environment prefix: {env.prefix}")
# Check installed packages
installed = env.get_installed_packages()
for pkg in installed:
print(f"{pkg.project_name}: {pkg.version}")
# Use environment context
with env.activated():
# Operations within activated environment
import subprocess
result = subprocess.run(["python", "--version"], capture_output=True, text=True)
print(f"Active Python: {result.stdout.strip()}")Data structures used by the Project class.
# Type aliases from project.py
TSource = Dict[str, Union[str, bool]] # Package source definition
TPackageEntry = Dict[str, Union[bool, str, List[str]]] # Individual package entry
TPackage = Dict[str, TPackageEntry] # Package collection
TScripts = Dict[str, str] # Script definitions
TPipenv = Dict[str, bool] # Pipenv settings
TPipfile = Dict[str, Union[TPackage, TScripts, TPipenv, List[TSource]]] # Complete PipfileComplete examples showing Project class integration.
from pipenv.project import Project
from pathlib import Path
# Initialize project and check state
project = Project()
if not Path(project.pipfile_location).exists():
# Create new project
project.create_pipfile(python="3.9")
print(f"Created new project: {project.name}")
else:
print(f"Using existing project: {project.name}")
# Add dependencies
project.add_package_to_pipfile("requests", "requests>=2.25.0")
project.add_package_to_pipfile("click", "click>=8.0.0")
project.add_package_to_pipfile("pytest", "pytest>=6.0.0", dev=True)
# Check project state
print(f"Production packages: {list(project.packages.keys())}")
print(f"Development packages: {list(project.dev_packages.keys())}")
# Work with environment
env = project.get_environment()
with env.activated():
# Environment is now active
installed = env.get_installed_packages()
print(f"Installed packages: {len(installed)}")Install with Tessl CLI
npx tessl i tessl/pypi-pipenv