docs/best_practices.md
This document outlines recommended best practices for using Pipenv effectively in your Python projects. Following these guidelines will help you maintain a clean, reproducible, and secure development environment.
Organize your project with a clear directory structure:
my_project/
├── .env # Environment variables (not in version control)
├── .gitignore # Git ignore file
├── Pipfile # Dependency declarations
├── Pipfile.lock # Locked dependencies with hashes
├── README.md # Project documentation
├── src/ # Source code
│ └── my_package/ # Your package
│ ├── __init__.py
│ └── ...
├── tests/ # Test files
│ ├── __init__.py
│ └── ...
└── docs/ # Documentation
└── ...
Consider storing the virtual environment in your project directory for easier management:
export PIPENV_VENV_IN_PROJECT=1
This creates a .venv directory in your project, making it easier to find and manage.
Always specify the Python version in your Pipfile to ensure consistency across environments:
[requires]
python_version = "3.10"
Use appropriate version constraints based on your needs:
For applications:
==) or compatible releases (~=) for stabilityrequests = "==2.28.1" or requests = "~=2.28.0"For libraries:
>=) to allow compatibilityrequests = ">=2.28.0"Avoid using * (any version) in production code, as it can lead to unpredictable behavior
Keep development dependencies separate from production dependencies:
# Install production dependencies
$ pipenv install flask sqlalchemy
# Install development dependencies
$ pipenv install pytest black mypy --dev
For complex projects, use custom package categories to organize dependencies:
[packages]
flask = "*"
sqlalchemy = "*"
[dev-packages]
pytest = "*"
black = "*"
[docs]
sphinx = "*"
sphinx-rtd-theme = "*"
[tests]
pytest-cov = "*"
pytest-mock = "*"
Install specific categories:
$ pipenv install --categories="docs,tests"
Pipfile and Pipfile.lock to version controlpipenv lock after changing dependencies to update the lock filepipenv install --deploy in CI/CD and production to ensure the lock file is up-to-dateRegularly check for and update dependencies to get security fixes:
# Check for outdated packages
$ pipenv update --outdated
# Update all packages
$ pipenv update
For production systems, test updates thoroughly before deployment.
Regularly scan for security vulnerabilities:
$ pipenv scan
Consider integrating this into your CI/CD pipeline.
Pipenv automatically adds hashes to Pipfile.lock. Use these for secure installations:
$ pipenv install --deploy
For private packages, use secure URLs and authentication:
[[source]]
name = "private"
url = "https://private-repo.example.com/simple"
verify_ssl = true
Use environment variables for credentials:
export PIP_INDEX_URL=https://${USERNAME}:${PASSWORD}@private-repo.example.com/simple
# Pull latest changes
$ git pull
# Install dependencies
$ pipenv install --dev
# Activate environment
$ pipenv shell
# Work on code...
# Run tests
$ pytest
# Deactivate when done
$ exit # or Ctrl+D
For one-off commands, use pipenv run instead of activating the shell:
$ pipenv run pytest
$ pipenv run python -m my_package
Use .env files for local configuration:
# .env
DEBUG=True
DATABASE_URL=sqlite:///dev.db
Pipenv automatically loads these when you use pipenv shell or pipenv run.
Important: Never commit sensitive information in .env files to version control. Add .env to your .gitignore.
For production deployments:
# Install only production dependencies
$ pipenv install --deploy
# Or for systems without virtualenv support
$ pipenv install --system --deploy
In your CI/CD pipeline:
# Example GitHub Actions workflow
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install pipenv
run: pip install pipenv
- name: Verify Pipfile.lock
run: pipenv verify
- name: Install dependencies
run: pipenv install --dev
- name: Run tests
run: pipenv run pytest
- name: Check for security vulnerabilities
run: pipenv scan
For containerized applications:
FROM python:3.10-slim
WORKDIR /app
# Copy dependency files
COPY Pipfile Pipfile.lock ./
# Install pipenv and dependencies
RUN pip install pipenv && \
pipenv install --system --deploy
# Copy application code
COPY . .
# Run the application
CMD ["python", "-m", "my_package"]
Make it easy for new developers to set up the project:
# Clone the repository
$ git clone https://github.com/example/project.git
$ cd project
# Install dependencies
$ pipenv install --dev
# Activate the environment
$ pipenv shell
Include these instructions in your README.md.
If you encounter dependency conflicts:
pipenv lock --clearpipenv graph to visualize dependencies and identify conflictsIf migrating from a project using requirements.txt:
$ pipenv install -r requirements.txt
Then review the generated Pipfile and adjust as needed.
Pipenv maintains a cache to speed up installations. If you encounter issues:
# Clear the cache
$ pipenv lock --clear
# Or set a custom cache location
$ export PIPENV_CACHE_DIR=/path/to/custom/cache
For faster development iterations:
# Skip lock file generation during development
$ export PIPENV_SKIP_LOCK=1
$ pipenv install some-package
Note: Only use this during development, not in production.
For projects with many dependencies:
# Increase the maximum depth for dependency resolution
$ export PIPENV_MAX_DEPTH=20
$ pipenv lock
Pipfile.lock out of date, update it with "pipenv lock" or "pipenv update".
Solution: Run pipenv lock to update the lock file.
Could not find a version that matches package==version
Solutions:
pipenv lock --clear to clear the cacheFailed to create virtual environment.
Solutions:
PIPENV_VENV_IN_PROJECT=1 to create the virtualenv in the project directoryIf you encounter issues:
# Get detailed environment information
$ pipenv --support
Include this output when asking for help in issues or forums.
Define custom scripts in your Pipfile for common tasks:
[scripts]
start = "python -m my_package"
test = "pytest"
lint = "flake8 src tests"
format = "black src tests"
Run them with:
$ pipenv run start
$ pipenv run test
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: tests
name: run tests
entry: pipenv run pytest
language: system
pass_filenames: false
# tox.ini
[tox]
envlist = py38, py39, py310
[testenv]
deps = pipenv
commands =
pipenv install --dev
pipenv run pytest
For projects that support multiple Python versions:
# Test with Python 3.8
$ pipenv --python 3.8 install --dev
$ pipenv run pytest
# Test with Python 3.9
$ pipenv --rm # Remove the current virtualenv
$ pipenv --python 3.9 install --dev
$ pipenv run pytest
Following these best practices will help you maintain a clean, reproducible, and secure Python development environment with Pipenv. Adapt these recommendations to your specific project needs and team workflows.
Remember that the key benefits of Pipenv are:
By leveraging these features effectively, you can focus more on development and less on environment management.