Common Misconfigurations
- Using version ranges instead of exact versions
- Not using requirements.txt in production
- Missing version constraints in setup.py
- Not locking transitive dependencies
- Mixing pip and conda without constraints
Vulnerable Example
Secure Solution
Key Commands for Pinning
Here are the commands that power the secure workflows described above.1. Simple Pinning (pip freeze)
This command “freezes” the current virtual environment, capturing the exact versions of everything installed and saving it to a file.- Pro: Very simple.
- Con: Not reproducible. It captures all dependencies in your environment, not just the ones your project needs. It’s hard to update.
2. Modern Pinning (pip-tools)
This is the recommended approach. It usespip-compile to generate a locked requirements.txt from a simple requirements.in file.
Step 1: Install pip-tools
requirements.in
Create a file listing only your direct dependencies (e.g., django, requests).
Step 3: Compile the lock file
This command resolves all dependencies (direct and transitive) and pins them with hashes.
3. Installing Pinned Dependencies
This command installs only the exact versions specified in your lock file. It is the standard command for production and CI/CD.4. Syncing Your Environment
This command (frompip-tools) is even better. It makes your virtual environment exactly match the requirements.txt file, installing missing packages and uninstalling any that don’t belong.
Best Practices
- Use pip-tools or Poetry for dependency management.
- Generate
requirements.txtwith exact versions. - Include hash verification.
- Use separate files for dev and prod dependencies.
- Implement automated dependency updates with review.

