Lesson illustration

Managing Python Environments and Dependencies

Hello again. In the previous lesson, you created a small churn-demo project, navigated it from a Bash-compatible shell, and ran src/train.py with Python. That project directory is now the right place to make your Python setup reproducible.

This lesson introduces a habit that matters throughout applied data science and ML work: each project gets its own isolated Python environment. You will create and activate an environment, install a package into it, verify exactly which Python and package manager are being used, and save the installed dependency versions in a file that another developer can use to reconstruct the setup.


Why a project needs its own environment

A Python virtual environment is a project-local, isolated collection of:

  • a Python interpreter associated with the environment,
  • pip, the package installer,
  • third-party packages installed for that project.

Without environments, packages tend to accumulate in one machine-wide Python installation. That becomes fragile quickly. One project may need one version of a library while a newer project needs another; an installation or upgrade for one can silently break the other.

For example, your future churn model might depend on a particular version of pandas or scikit-learn. Its results, warnings, or even available functions can change across versions. An environment lets the project state its package requirements explicitly rather than relying on whatever happens to be installed on a laptop.

Isolation has an important boundary:

  • It does separate the project’s third-party packages from other projects.
  • It does not make code correct, save your data, or automatically make a run reproducible.
  • It applies only when you use that environment’s Python interpreter. A notebook, terminal, or editor using a different interpreter is still outside it.

A virtual environment is intentionally disposable. You do not put your own source files inside it, and you do not commit the environment folder to Git. You commit the small dependency record needed to rebuild it.


Watch the workflow once

{"type":"video","title":"Python Virtual Environments - Full Tutorial for Beginners","learning_duration":358,"video_id":"Y21OR1OPC9A","par_intro":"Watch “Python Virtual Environments - Full Tutorial for Beginners” from Tech With Tim for a visual walkthrough of the same create, activate, install, and freeze workflow you will perform below.","par_directions":"Watch <span data-type=\"resource_video_timerange\" data-resource-subitem-id=\"c0cfbd48\" data-range-start=\"0\" data-range-end=\"42\">the purpose</span> for the dependency-conflict problem environments solve. Then watch <span data-type=\"resource_video_timerange\" data-resource-subitem-id=\"d8244403\" data-range-start=\"42\" data-range-end=\"129\">creation and activation</span>, noting that the activation command differs by operating system. Continue with <span data-type=\"resource_video_timerange\" data-resource-subitem-id=\"1728b6f8\" data-range-start=\"198\" data-range-end=\"263\">package installation</span> and <span data-type=\"resource_video_timerange\" data-resource-subitem-id=\"0a7b1525\" data-range-start=\"263\" data-range-end=\"427\">dependency freezing</span>. Focus on the evidence of isolation: the active environment name in the prompt and the package list changing only within that environment.","isV2":true,"blockId":"ca2ae26f-1301-46ef-be66-22681f97cfb6","lessonId":"1cf96617-d3cf-4894-97e6-210b9f28eea9"}



The official Python documentation is worth using as your durable reference, especially when you later work on a machine with a different operating system or shell.

{"type":"reading","par_intro":"Read the relevant parts of the official Python tutorial to connect the commands to the underlying purpose of `venv` and `pip`.","par_directions":"In Section 12.2, “Creating Virtual Environments,” read <span data-type=\"resource_reading_textrange\" data-resource-subitem-id=\"336f2bd5\" data-range-start=\"The module used to create and manage virtual environments is called\" data-range-end=\"various supporting files.\">venv creation</span>. Notice that the Python command used to create an environment determines its Python version. Then, in Section 12.3, “Managing Packages with pip,” locate the paragraph beginning “You can install, upgrade, and remove packages” and read <span data-type=\"resource_reading_textrange\" data-resource-subitem-id=\"ac931a6e\" data-range-start=\"You can install, upgrade, and remove packages using a program called\" data-range-end=\"pip has a number of subcommands:\">the pip overview</span>. Finally, in that same section, find the paragraph beginning with `python -m pip freeze` and read <span data-type=\"resource_reading_textrange\" data-resource-subitem-id=\"271ae772\" data-range-start=\"will produce a similar list of the installed packages\" data-range-end=\"requirements.txt file:\">the freeze format</span>, focusing on why the output can be saved as `requirements.txt`.","learning_duration":"6 minutes","url":"https://docs.python.org/3/tutorial/venv.html","title":"12. Virtual Environments and Packages","isV2":true,"blockId":"af4d7914-a11d-4e4c-bd30-3ed7ad7b7583","lessonId":"1cf96617-d3cf-4894-97e6-210b9f28eea9"}




The reliable command pattern: python -m pip

You will see both of these commands online:

pip install requests
python -m pip install requests

For this course, prefer the second form:

python -m pip install package_name

It means: run the pip module attached to this exact python command.

That detail prevents a common and confusing failure:

  1. You activate an environment.
  2. You run a standalone pip command that actually belongs to another Python installation.
  3. You try to import the package with the environment’s Python.
  4. Python reports ModuleNotFoundError.

Using python -m pip keeps the interpreter and installer paired. It is a small discipline with a large payoff when you work across notebooks, scripts, Databricks, local machines, and eventually containers.

{
  "type": "exercise",
  "id": "1e8ab363-14ca-46a6-856f-cd0f280db7d5"
}

Guided build: make an environment for churn-demo

Type these commands yourself rather than pasting a large block. Before each command, predict which files it will create or which executable it should use. Then inspect the result.

1. Return to the project root

From the previous lesson, your practice project should be at ~/projects/churn-demo.

cd ~/projects/churn-demo
pwd
ls -la

Your pwd output should end in projects/churn-demo. The detailed listing should show directories such as src, data, and tests. It should not yet contain .venv unless you have already created one.

2. Choose the base Python command

First, check whether python3 is available:

python3 --version

If it reports a Python 3 version, use python3 for the next command. If it is not found, try:

python --version

If that reports Python 3, use python instead.

Do not run both environment-creation commands. Choose the one that works on your machine:

python3 -m venv .venv

or:

python -m venv .venv

The final .venv is the directory name you are asking Python to create. A leading period makes it hidden in many directory listings, while the name still clearly describes its role.

Confirm that it exists:

ls -la

You should now see .venv. It will contain platform-specific support files. Do not open it to place scripts or data there; your project code remains in src/, notebooks remain in notebooks/, and so on.

3. Activate the environment

Activation changes the current shell session so its python command resolves to the interpreter inside .venv.

Use the command that matches your shell and operating system:

Shell or operating systemActivation command
macOS, Linux, or WSL Bashsource .venv/bin/activate
Git Bash on Windowssource .venv/Scripts/activate
Windows PowerShell.\.venv\Scripts\Activate.ps1
Windows Command Prompt.venv\Scripts\activate.bat

Because the previous lesson uses a Bash-compatible shell, use one of the first two commands. For macOS, Linux, or WSL:

source .venv/bin/activate

After activation, most prompts display something like (.venv) at the beginning. That is helpful visual feedback, but verify with the interpreter path rather than trusting the prompt alone:

command -v python
python --version
python -m pip --version

The first and third outputs should include a path containing churn-demo/.venv/. On macOS/Linux/WSL, it normally includes .venv/bin/; on Windows Git Bash, it normally includes .venv/Scripts/.

At this point, notice the deliberate change in command usage:

  • Before activation, you may have needed python3.
  • After activation, use python. Activation has put the environment’s python first on your shell’s search path.

4. Inspect the clean environment

Run:

python -m pip list

The exact initial list differs by Python version, but it should be short. This is evidence that you are not looking at every package ever installed on your computer.

Now install one small, commonly used package: requests. It is a Python library for making HTTP requests, which will be useful when you begin working with APIs later in the course.

python -m pip install requests

pip may install several packages, not only requests. Those extra packages are dependencies: packages requests needs in order to work.

Verify the specific installation:

python -m pip show requests

Look for:

  • Name: requests
  • Version: ...
  • a Location: path containing .venv

You can also view the full environment again:

python -m pip list

The important conclusion is not the exact number of rows. It is that requests and its dependencies are located in the active project environment.


Verify with a small script

Installing successfully is useful evidence, but importing the package with the intended interpreter is stronger evidence.

Create src/check_requests.py in your editor with this code:

import requests

print(f"requests version: {requests.__version__}")

From the project root, while (.venv) is still visible in the prompt, run:

python src/check_requests.py

You should see a version number. This confirms all three pieces are aligned:

  1. The shell’s active python points to .venv.
  2. requests was installed for that Python.
  3. Your script can import the installed package.

If you deactivate the environment and run the same script, it might still work if requests happens to be installed globally. It also might fail. That uncertainty is exactly why the project environment is valuable: when active, it makes the source of packages explicit.

{
  "type": "exercise",
  "id": "ae99b719-9fd3-4f6a-a52a-491777bb7dc8"
}

Record package versions in requirements.txt

A project needs a shareable description of its dependencies, not a copy of your entire .venv directory.

Run this command while the environment is still active:

python -m pip freeze > requirements.txt

The > symbol is shell output redirection. It takes the text produced by the command on the left and writes it to the file on the right. If requirements.txt already exists, this command replaces its contents, so use it intentionally when you want to update the recorded snapshot.

Inspect the created file:

cat requirements.txt

You should see lines resembling:

certifi==...
charset-normalizer==...
idna==...
requests==...
urllib3==...

The version numbers on your machine will differ. requests appears alongside its dependencies because your code needs the whole compatible set, not just the top-level package name.

A requirements.txt generated with pip freeze answers this operational question:

“Which package versions were installed in the environment where this project ran?”

Someone rebuilding the project can create a new environment, activate it, and install the recorded versions with:

python -m pip install -r requirements.txt

Here, -r tells pip to read package requirements from the named file.

Keep the right files, ignore the right directory

Create or open a .gitignore file at the project root and add:

.venv/

Later, Git will use this instruction to avoid tracking the environment folder. The usual project policy is:

ItemTrack in Git?Why
src/YesYour source code is the project.
tests/YesTests document and verify expected behavior.
requirements.txtYesOthers need it to rebuild packages.
.gitignoreYesThe repository needs shared ignore rules.
.venv/NoIt is machine-specific and rebuildable.

For this small environment, pip freeze is an appropriate way to create the dependency record. In larger production projects, teams often distinguish direct dependencies from transitive dependencies and may use more specialized dependency tools. For now, understand the dependable baseline: create a clean environment, install intentionally, and record the resulting versions.

{
  "type": "exercise",
  "id": "5ffd9dbd-969d-4083-a344-f8925708fbe8"
}

Deactivate, reactivate, and diagnose problems

When you have finished this session, deactivate the environment:

deactivate

The (.venv) prompt prefix should disappear. This does not delete .venv; it only returns the current terminal session to its normal Python resolution.

The next time you open a terminal and want to work on churn-demo, use this short routine:

cd ~/projects/churn-demo
source .venv/bin/activate
python --version
python -m pip list

On Windows Git Bash, substitute the Scripts/activate path as described earlier.

Common failures and focused checks

SymptomLikely causeFirst response
python3: command not foundYour system calls the interpreter python instead.Run python --version; use the command that reports Python 3.
No module named venvThe installed Python does not include the venv component.Check python3 --version or python --version; consult your organization’s Python setup guidance rather than installing unrelated packages.
source: ... activate: No such file or directoryYou are in the wrong directory, .venv was not created, or you used the wrong platform path.Run pwd and ls -la; confirm .venv exists and choose bin/activate or Scripts/activate correctly.
ModuleNotFoundError: No module named 'requests'The environment is inactive, or the package was installed with a different pip.Activate .venv, then run command -v python and python -m pip show requests.
pip installs somewhere unexpectedA standalone pip belongs to another Python installation.Use python -m pip ... consistently.
Your editor or notebook cannot import an installed packageThe editor or notebook kernel uses a different interpreter from the terminal.Select the project’s .venv interpreter in that tool, then verify its interpreter path.

When working independently, avoid treating an activation prompt as proof. Verify the actual executable:

command -v python
python -m pip --version

That is the environment equivalent of checking pwd before using a relative path.


Completion evidence

Before moving on, ensure your project root contains:

churn-demo/
├── .gitignore
├── .venv/
├── requirements.txt
└── src/
    ├── train.py
    └── check_requests.py

You should be able to demonstrate the complete workflow from memory:

  1. Navigate to the project root.
  2. Create .venv with the working Python 3 command.
  3. Activate it with the command for your shell.
  4. Verify that python and pip resolve inside .venv.
  5. Install a package using python -m pip install.
  6. Confirm it with python -m pip show and an import in a script.
  7. Save installed versions with python -m pip freeze > requirements.txt.
  8. Deactivate when finished.

Key takeaways

A virtual environment keeps one project’s Python packages separate from other projects and from your system-wide installation. Create it in the project as .venv, activate it whenever you work on the project, and use python -m pip so package installation always targets the same interpreter that runs your code.

requirements.txt records the installed package versions required to reconstruct the environment. Commit that file and .gitignore, but not the .venv/ directory itself.

Next, you will work with project data directly: reading and writing CSV and JSON files using context managers and portable paths. The environment you created today will become the controlled place where later data and ML packages are installed.

Can't find a good explanation? Sign up and we'll make it for you