Skip to content

ይህ ትምህርት ገና ወደ አማርኛ አልተተረጎመም፤ ስለዚህ በእንግሊዝኛ ቀርቧል። የእንግሊዝኛውን ገጽ ክፈቱ

Packages and virtual environments

5 min read

Most of what Python can do lives in code other people share: tools for the web, for data, for AI. By the end of this lesson you'll know where it comes from, why every project gets its own copy, and how to set up a project with uv.

Packages and PyPI

A is code someone has published for others to use: one or more modules with a name and a version number. Most live on , the Python Package Index at pypi.org. Python usually comes with pip, the basic tool that downloads a package and installs it. Read this one, don't run it yet; the next section shows where packages should go:

python -m pip install httpx
Output
Collecting httpx
...
Installing collected packages: typing_extensions, idna, h11, certifi, httpcore, anyio, httpx
Successfully installed anyio-4.15.1 certifi-2026.7.22 h11-0.16.0 httpcore-1.0.9 httpx-0.28.1 idna-3.20 typing_extensions-4.16.0

You asked for one package and got seven: httpx (for talking to websites) is built on other packages, and pip installs them all. Then import httpx works like import json. Check a package's name before installing: fake packages with names one letter off exist.

Why every project needs its own

A story first. Dawit has two projects. His school project from last year uses version 0.27 of a package, and he tested it carefully. This year's project needs a feature from 0.28, so he runs pip install for version 0.28. He doesn't touch the school project.

ጥያቄ

What happens to Dawit's school project?

There's only one copy of each package for that Python, so installing 0.28 replaced 0.27, and the school project, which Dawit never changed, can stop working. That's why one project's update can break another.

A fixes this. It's a folder, usually named .venv, inside the project, that holds that project's own packages. Each project has its own, so each can have its own versions, and changing one never touches another.

So don't install your projects' packages into the main Python (some systems refuse with error: externally-managed-environment), and never commit .venv or send it to someone: it's large and works only on the computer that made it. Share the list of packages instead.

Projects with uv

makes the project, its environment, and its list of packages for you. The course's codespace has it; on your own computer, install it once from a terminal (commands from uv's documentation):

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Open a new terminal so it finds uv, then make a project:

uv init --no-package birr-tools
cd birr-tools
Output
Initialized project `birr-tools` at `/home/hana/birr-tools`

--no-package makes the simplest kind of project: a main.py to run, which is what you want for now. (Without it, uv sets the project up to be installed as a package of its own, with its code in a src folder.) The folder now has main.py, a README.md, .python-version (the Python version, 3.14), a .gitignore that already leaves out .venv, a .git folder if Git is installed, and pyproject.toml, the project's description:

pyproject.toml
[project]
name = "birr-tools"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.14"
dependencies = []

Run it with uv run. The first time, uv makes the environment:

uv run main.py
Output
Using CPython 3.14.7 interpreter at: /usr/bin/python3.14
Creating virtual environment at: .venv
Hello from birr-tools!

Now add a package. uv add installs it into this project's .venv and writes it in pyproject.toml:

uv add httpx
Output
Resolved 8 packages in 2.54s
Prepared 7 packages in 1.33s
Installed 7 packages in 7ms
 + anyio==4.15.1
 + certifi==2026.7.22
 + h11==0.16.0
 + httpcore==1.0.9
 + httpx==0.28.1
 + idna==3.20
 + typing-extensions==4.16.0

pyproject.toml now lists "httpx>=0.28.1" under dependencies, and a new file, uv.lock, records the exact version of every package installed. Share those two, and uv run main.py builds the same environment anywhere. Edit main.py to use the package:

main.py
import httpx
 
 
def main():
    print("httpx", httpx.__version__)
 
 
if __name__ == "__main__":
    main()
uv run main.py
Output
httpx 0.28.1

uv run always uses the project's environment. (Your paths, timings, and versions will differ.) Run the file the usual way, and the main Python can't find the package:

Codespaces, if you don't have a computer

A is a computer run by GitHub that you use through VS Code in your browser. The exercises repo's codespace has Python 3.14 and uv ready; you need a free GitHub account and a steady connection.

A free account gets 120 core hours and 15 GB of storage a month. The smallest codespace has 2 cores, so an hour of work uses 2 core hours: about 60 hours a month. To stay inside that:

  • Stop it when you're done (press F1, then Codespaces: Stop Current Codespace). A running codespace uses hours until it times out.
  • Delete the ones you don't need at github.com/codespaces. A stopped codespace keeps your files, and its storage counts until it's deleted. Commit and push your work first, or it's deleted with the codespace.

When the free amount runs out, codespaces stop until next month; without a payment method, you're never charged.

መልመጃ

Your first uv project

On a computer or in a codespace: make a project with uv init --no-package, add httpx with uv add, and make main.py print its version. Run it with uv run main.py, then find httpx in pyproject.toml.

መፍትሄውን አሳይ

This is one way to solve it, not the only one. If yours prints the same thing, it works.

# In a terminal:
#   uv init --no-package birr-tools
#   cd birr-tools
#   uv add httpx
#   uv run main.py
import httpx


def main():
    print("httpx", httpx.__version__)


if __name__ == "__main__":
    main()

ዋና ዋና ነጥቦች

  • A package is shared code with a name and a version; PyPI is where packages are published, and pip or uv installs them.
  • A virtual environment (.venv) gives each project its own packages, so updating one project can't break another.
  • Never commit .venv; share pyproject.toml and uv.lock, and the environment can be rebuilt anywhere.
  • uv init --no-package name makes a project, uv add httpx installs a package into it, uv run main.py runs it in its environment.