Question
How to Install Python Packages from requirements.txt Using pip and a Local Directory
Question
I have a requirements.txt file like this:
BeautifulSoup==3.2.0
Django==1.3
Fabric==1.2.0
Jinja2==2.5.5
PyYAML==3.09
Pygments==1.4
SQLAlchemy==0.7.1
South==0.7.3
amqplib==0.6.1
anyjson==0.3
I also have a local archive directory that contains these packages along with some others.
I created a new virtual environment with:
bin/virtualenv testing
After activating it, I tried to install the packages from requirements.txt using the local archive directory:
source bin/activate
pip install -r /path/to/requirements.txt -f file:///path/to/archive/
The output seemed to suggest that installation was working, for example:
Downloading/unpacking Fabric==1.2.0 (from -r ../testing/requirements.txt (line 3))
Running setup.py egg_info for package Fabric
warning: no previously-included files matching '*' found under directory 'docs/_build'
warning: no files found matching 'fabfile.py'
Downloading/unpacking South==0.7.3 (from -r ../testing/requirements.txt (line 8))
Running setup.py egg_info for package South
However, later I found that none of the packages were actually installed. I could not import them, and they did not appear in the virtual environment's site-packages directory.
What went wrong, and how should packages be installed correctly from a local directory using pip and requirements.txt?
Short Answer
By the end of this page, you will understand how pip install -r requirements.txt works with local package sources, what the -f option actually does, why package metadata output does not always mean installation succeeded, and how to correctly install and verify packages inside a Python virtual environment.
Concept
pip can install packages listed in a requirements.txt file, and it can also look in extra places for package files such as wheels or source archives. A common misunderstanding is thinking that -f means “install everything from this folder.” It does not.
The -f flag means find links. It tells pip to search a directory or page for candidate package files that match the requirements. pip still resolves each requirement individually and only installs packages if it finds valid distributions and successfully completes the installation.
In older versions of pip, the output could be misleading. Messages like:
Running setup.py egg_info for package ...
mean that pip is reading package metadata, not that the package has been fully installed.
For installation to actually succeed:
- the virtual environment must be activated correctly
pipmust be the one inside that virtual environment- the local directory must contain installable package files
- the package versions in
requirements.txtmust match available files - the install command must complete successfully, including dependencies if needed
This matters in real programming because many teams install dependencies from:
- offline package mirrors
- internal package repositories
- pre-downloaded wheel directories
- deployment bundles for restricted environments
Understanding the difference between discovering packages and installing packages helps you troubleshoot dependency issues quickly.
Mental Model
Think of requirements.txt as a shopping list and the local archive directory as a warehouse.
requirements.txtsays what you need.-f file:///path/to/archive/tellspipwhere to look for items.pipchecks the warehouse shelves for matching packages.- Reading
egg_infois like checking the label on a box. - Actual installation is like taking the item home and placing it in your cupboard.
So if pip only checks labels but never finishes the install, the package will not end up in site-packages.
The key idea: finding a package is not the same as installing it.
Syntax and Examples
The usual syntax is:
pip install -r requirements.txt
To tell pip to also search a local directory for packages:
pip install -r requirements.txt -f file:///absolute/path/to/archive/
If you want to avoid downloading from the internet and only use local files, a more explicit modern approach is:
pip install --no-index --find-links=file:///absolute/path/to/archive/ -r requirements.txt
Example
Suppose your local folder contains:
Django-1.3.tar.gzJinja2-2.5.5.tar.gzSouth-0.7.3.tar.gz
And your requirements.txt contains:
Django==1.3
Jinja2==2.5.5
South==0.7.3
Then install with:
source testing/bin/activate
python -m pip install --no-index --find-links=file:///absolute/path/to/archive/ -r requirements.txt
Why use python -m pip?
This makes sure you are using the pip that belongs to the currently selected Python interpreter. It avoids installing packages into the wrong environment.
Verify the result
python -m pip list
python -m pip show Django
python -c "import django; print(django.get_version())"
If these commands fail, the package was not installed into the active environment.
Step by Step Execution
Consider this command:
python -m pip install --no-index --find-links=file:///packages/ -r requirements.txt
And this requirements.txt:
Jinja2==2.5.5
Step-by-step
python -m piprunspipusing the current Python interpreter.-r requirements.txttellspipto read package names and versions from the file.--no-indextellspipnot to contact PyPI.--find-links=file:///packages/tellspipto search that local directory for matching package files.pipscans the directory for a package matchingJinja2==2.5.5.- If it finds a valid distribution file, it reads metadata first.
- If installation succeeds, files are copied into the virtual environment's
site-packages. - If installation fails, the package will not be importable.
Trace example
source testing/bin/activate
python -m pip install --no-index --find-links=file:///packages/ -r requirements.txt
python -m pip show Jinja2
python -c "import jinja2; print(jinja2.__version__)"
Expected outcome:
pip showprints package info- importing
jinja2works - the package appears in the virtual environment's
site-packages
If not, one of these likely happened:
- wrong
pipwas used - the package file did not match the requested version
- installation failed after metadata inspection
- dependencies were missing or incompatible
Real World Use Cases
Installing from a local directory is common in situations like these:
- Offline servers: production machines may not have internet access.
- Corporate environments: only approved internal packages may be allowed.
- CI/CD pipelines: build systems may use a cached package directory for speed.
- Reproducible deployments: teams may freeze exact package files and install only from those files.
- Air-gapped systems: security-sensitive environments often rely on local package mirrors.
Example scenarios
- A deployment script installs all dependencies from a shared network folder.
- A Docker image copies prebuilt wheels into
/wheelsand installs from there. - A test runner uses a local cache to avoid repeated downloads.
In all of these, developers usually combine requirements.txt with either --find-links or a proper package index mirror.
Real Codebase Usage
In real projects, developers usually make local installs more reliable with a few patterns.
1. Use python -m pip
Instead of:
pip install -r requirements.txt
prefer:
python -m pip install -r requirements.txt
This avoids using the wrong pip binary.
2. Use explicit offline mode
If the install must come only from local files:
python -m pip install --no-index --find-links=file:///wheels/ -r requirements.txt
3. Verify after installation
Teams often run checks such as:
python -m pip list
python -m pip check
4. Use guard checks in scripts
Deployment scripts may include early validation:
python -m pip --version
python -c "import sys; print(sys.executable)"
This confirms the active interpreter and environment.
5. Prefer wheel files when possible
Wheels install faster and more reliably than source archives because they do not need a build step.
6. Keep requirements and package files aligned
A common pattern is to store:
- exact versions in
requirements.txt - matching wheel or archive files in a
vendor/orwheels/directory
This reduces surprises during deployment.
Common Mistakes
Here are the most common beginner mistakes when installing from a local directory.
1. Assuming -f means “install everything in this folder”
It does not. It only adds an extra location where pip looks for packages.
Broken assumption:
pip install -r requirements.txt -f file:///packages/
This only works if the folder contains valid files matching the requested requirements.
2. Using the wrong pip
You may activate a virtual environment but still run a different pip from somewhere else.
Check with:
which python
which pip
python -m pip --version
Safer command:
python -m pip install -r requirements.txt
3. Thinking egg_info means installation completed
Output like this:
Running setup.py egg_info for package Fabric
only means package metadata is being read.
4. Local directory does not contain installable files
Your archive must contain actual package distributions such as:
.whl.tar.gz.zip
And they must match the names and versions in requirements.txt.
5. Not checking the final exit status
Sometimes users notice only the early output and miss the actual error later.
Always scroll to the end of the install output and verify success.
6. Expecting packages in the wrong environment
A package may be installed globally instead of in your virtual environment.
Check the active interpreter:
python -c "import sys; print(sys.prefix)"
7. Using relative or malformed file URLs
Use a proper absolute file URL:
--find-links=file:///absolute/path/to/archive/
not something ambiguous like:
-f file://path/to/archive
8. Ignoring dependencies
If your local folder does not contain dependency packages too, installation may fail or remain incomplete when offline.
Comparisons
| Option | What it does | Typical use | Notes |
|---|---|---|---|
-r requirements.txt | Installs packages listed in a file | Standard dependency install | Reads exact requirements |
-f PATH / --find-links=PATH | Adds extra places to search for package files | Local archives, wheel folders | Does not mean “install all files in folder” |
--no-index | Disables PyPI lookup | Offline or controlled installs | Often used with --find-links |
pip install package.whl | Installs one specific file directly | Manual local installation | Good for single package testing |
pip install . | Installs the current project directory | Local app/package development | Used when the current folder has setup.py or modern packaging config |
pip vs python -m pip
| Command | Advantage | Risk |
|---|---|---|
pip install ... | Shorter to type | May use the wrong interpreter or environment |
python -m pip install ... | Tied to the current Python interpreter | Slightly longer, but safer |
-f vs direct file install
| Approach | Best for | Example |
|---|---|---|
--find-links | Installing many packages from a directory | python -m pip install --find-links=file:///wheels -r requirements.txt |
| Direct file path | Installing one known package file | python -m pip install ./wheels/Django-1.3.tar.gz |
Cheat Sheet
# Activate virtual environment
source testing/bin/activate
# Safest way to run pip in the active environment
python -m pip --version
# Install from requirements file
python -m pip install -r requirements.txt
# Install using a local package directory
python -m pip install --find-links=file:///absolute/path/to/archive/ -r requirements.txt
# Install only from local files, not PyPI
python -m pip install --no-index --find-links=file:///absolute/path/to/archive/ -r requirements.txt
# Verify installed packages
python -m pip list
python -m pip show Django
python -c "import django; print(django.get_version())"
# Check interpreter location
python -c "import sys; print(sys.executable)"
Key rules
-rreads requirements from a file.-f/--find-linksadds a search location for package files.--no-indexprevents internet lookup.egg_infooutput is not proof of successful installation.- Prefer
python -m pipover plainpip. - Use absolute
file:///...paths for local directories. - Ensure versions in
requirements.txtmatch files in the archive.
FAQ
Why did pip show package activity but nothing appeared in site-packages?
Because pip may have only read package metadata such as egg_info, or the install may have failed before completion.
Does -f mean install all packages from a directory?
No. It only tells pip where to look for files that satisfy the requirements you requested.
How do I force pip to use only local files?
Use:
python -m pip install --no-index --find-links=file:///absolute/path/to/archive/ -r requirements.txt
How can I check whether I installed into the correct virtual environment?
Run:
python -m pip --version
python -c "import sys; print(sys.executable)"
These should point to your virtual environment.
What kinds of files should be in the local archive directory?
Usually installable package distributions such as .whl, .tar.gz, or .zip files.
Why is python -m pip recommended?
It ensures that pip runs with the exact Python interpreter you chose, which helps avoid environment confusion.
Can I install a single package directly from a local file?
Yes. Example:
python -m pip install ./archive/Jinja2-2.5.5.tar.gz
What should I do after installation to verify success?
Use pip list, pip show, and a simple import test in Python.
Mini Project
Description
Create a small offline dependency installation workflow for a Python project. You will simulate a real-world setup where package files are stored in a local directory and installed into a virtual environment using requirements.txt.
This demonstrates how local package discovery works, how to avoid installing into the wrong environment, and how to verify that packages were truly installed.
Goal
Set up a virtual environment, install packages from a local archive directory using requirements.txt, and verify that the installed modules can be imported successfully.
Requirements
- Create and activate a new virtual environment.
- Prepare a
requirements.txtfile with at least two pinned package versions. - Install the packages using only a local package directory.
- Verify installation with both
pipand Pythonimportcommands.
Keep learning
Related questions
@staticmethod vs @classmethod in Python Explained
Learn the difference between @staticmethod and @classmethod in Python with clear examples, use cases, mistakes, and a mini project.
Add Rows to a Pandas DataFrame in Python
Learn how to add rows to a Pandas DataFrame, why repeated row appends are slow, and when to use loc, concat, or record lists.
Call a Function by Name in a Python Module
Learn how to call a function by name in a Python module using strings, getattr, and safe patterns for dynamic function dispatch.