Environments & Packaging Basics
10 examples to get you started with Environments and Packaging - 7 basic and 3 intermediate.
Prerequisites
- Python 3.14.0 installed (
python3 --version) - uv 0.6+ recommended for fast installs:
curl -LsSf https://astral.sh/uv/install.sh | sh - A project directory with a
pyproject.toml(create one withuv initif needed)
Basic Examples
1. Create a Virtual Environment
A virtual environment isolates project dependencies from the system Python.
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
which python # points inside .venvvenvships with Python 3.14 - no extra install required- Activation prepends
.venv/bintoPATHsopipandpythonare project-local - Deactivate with
deactivatewhen switching projects - Never commit
.venv/- add it to.gitignore
Related: uv - The Fast Toolchain - faster alternative to manual venv + pip
2. Install a Package with pip
Install dependencies into the active environment.
pip install httpx
pip freeze > requirements.txtpipresolves and installs from PyPI into the active venv onlypip freezecaptures exact versions for reproducibility- Prefer
pyproject.toml+ lockfiles for new projects (see pyproject.toml Explained) - Use
pip install -r requirements.txtto restore a frozen set
3. Initialize a Project with uv
uv replaces venv + pip + pip-tools in one fast tool.
uv init myapp
cd myapp
uv add httpx pydantic
uv run python -c "import httpx; print(httpx.__version__)"uv initcreatespyproject.tomland a.venvautomaticallyuv addwrites dependencies topyproject.tomland updates the lockfileuv runexecutes inside the project environment without manual activation- uv is the recommended default toolchain for Python 3.14 projects
Related: uv - The Fast Toolchain - full uv workflow
4. Declare Dependencies in pyproject.toml
Modern projects declare metadata and dependencies in one file.
[project]
name = "myapp"
version = "0.1.0"
requires-python = ">=3.14"
dependencies = [
"httpx>=0.28",
"pydantic>=2",
][project]is the PEP 621 metadata block every build tool readsrequires-pythonprevents installs on unsupported interpreters- Version ranges (
>=) balance flexibility with reproducibility via lockfiles - Tool-specific config (ruff, pytest) lives in the same file under
[tool.*]
Related: pyproject.toml Explained - every section decoded
5. Pin with a Lockfile
Lockfiles record exact resolved versions for reproducible installs.
uv lock
uv syncuv lockresolves all dependencies and writesuv.lockuv syncinstalls exactly what the lockfile specifies- Commit the lockfile - teammates and CI get identical environments
- Re-run
uv lockwhen you changepyproject.tomldependencies
Related: Dependency Resolution & Lockfiles - pinning strategies
6. Install Multiple Python Versions
Test against several Python versions on one machine.
uv python install 3.13 3.14
uv venv --python 3.14
uv run --python 3.13 pytestuv python installdownloads interpreters without pyenv- Pin the project venv to a specific version with
--python - Run commands against any installed version with
uv run --python - Match
requires-pythoninpyproject.tomlto your lowest supported version
Related: Managing Python Versions - pyenv and CI matrices
7. Editable Install for Local Development
Edit source code and see changes without reinstalling.
uv pip install -e .
# or: pip install -e .-e(editable) links the package into the venv via a.pthfile- Changes to
src/myapp/take effect on the next import - Use
src/layout so tests import the installed package, not the repo root - Required for monorepos with interdependent local packages
Related: Editable Installs & Local Packages - src layout and monorepos
Intermediate Examples
8. Dependency Groups for Dev vs. Prod
Separate runtime and development dependencies.
[project]
dependencies = ["fastapi>=0.115"]
[dependency-groups]
dev = ["pytest>=8", "ruff>=0.9", "mypy>=1.14"]uv sync --group dev
uv sync --no-dev # production install only[dependency-groups](PEP 735) replaces ad-hocrequirements-dev.txtuv sync --group devinstalls runtime + dev tools- CI can install only what each job needs
- Never ship dev dependencies to production containers
9. Configure a Private Package Index
Pull packages from an internal mirror or private PyPI.
export UV_INDEX_URL=https://pypi.internal.corp/simple/
uv sync# pyproject.toml alternative
[[tool.uv.index]]
url = "https://pypi.internal.corp/simple/"
default = true- Private indexes host internal packages and cache public PyPI
- Credentials go in
~/.netrc, env vars, or CI secrets - never inpyproject.toml --index-urloverrides the default for a single command- Fall back to public PyPI for packages not mirrored internally
Related: Private Indexes & Mirrors - auth and CI setup
10. Reproduce an Environment from Scratch
Clone, install, and run in three commands.
git clone https://github.com/org/myapp.git && cd myapp
uv sync --frozen
uv run pytest--frozenfails if the lockfile is out of date withpyproject.toml- New contributors get a working environment in seconds
- CI should use the same
uv sync --frozencommand - Document the three commands in your README
Related: Environments Best Practices - team conventions
Stack versions: This page was written for Python 3.14.0, FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.