[Python Series 10] Clean Python Projects: Managing Environments and Dependencies

한국어 버전

With exception handling and logging in place, the next step is managing your environment so your code runs the same way for your teammates and servers. We'll walk the core loop of "create a virtualenv → declare dependencies in pyproject.toml → install via uv", then outline optional extensions such as CI and pre-commit.

Key terms

  1. pyproject.toml: The standard file for declaring package metadata and dependencies.
  2. uv.lock: The lockfile created by uv that pins exact dependency versions for reproducibility.
  3. Environment variable: A key-value supplied at runtime to store secrets such as API keys or file paths.

Core ideas

Study memo

  • Time: 50–60 minutes
  • Prereqs: Familiarity with virtualenv/uv setup and requests-based scripts
  • Goal: Control dependencies and env vars through pyproject.toml plus uv commands

Virtual environments isolate execution per project, while pyproject.toml gathers dependency declarations. Think of it as “keep everything in one folder” for your runtime.

Code examples

Why virtualenv matters (Core)

Installing libraries globally causes version clashes and makes parity between local and server environments painful. A virtualenv gives each project its own site-packages. If that feels abstract, treat it as "use a dedicated folder that only this project touches."

uv venv .venv
source .venv/bin/activate
python --version

On CI or servers, you can skip activation and run uv run python app.py to keep commands consistent.

Shape pyproject.toml (Core)

[project]
name = "mealbot"
version = "0.1.0"
description = "Meal notification bot"
requires-python = ">=3.12"

[project.dependencies]
requests = "^2.31.0"
python-dotenv = "^1.0.1"

[tool.uv]
dev-dependencies = ["pytest", "ruff"]

pyproject.toml centralizes metadata and dependencies. Start with name, version, and a couple of dependencies—simplicity beats perfection at this stage.

📦 What is pyproject.toml? A single configuration file that replaces scattered setup.py scripts by keeping build tools, metadata, and dependencies together.

Manage dependencies with uv (Core)

uv add requests typer
uv add --dev pytest
uv pip list

uv add updates both the pyproject and lockfile. Master uv add <package> and uv run python main.py first, then graduate to uv lock or uv sync --frozen for stricter reproducibility.

Handle environment variables (Core → Plus)

cp .env.example .env

Document keys in .env.example but leave values blank. At runtime, point uv to the file:

uv run --env-file .env python scripts/send_meal.py

This makes it trivial to swap between school accounts or personal accounts.

Suggested project layout (Optional)

mealbot/
├── pyproject.toml
├── uv.lock
├── src/mealbot/__init__.py
├── tests/
├── scripts/
└── README.md

Using a src layout helps catch incorrect imports before packaging. If that feels heavy, start by managing just pyproject.toml and uv.lock, then adopt the layout later.

CI and pre-commit hooks (Optional)

  • Reuse cached virtualenvs in GitHub Actions with uv setup-python.
  • Wire uv run ruff check and uv run pytest into pre-commit hooks for consistent local/CI behavior.

Treat these as add-ons for collaboration rather than requirements for solo study.

Why it matters

Project hygiene ensures "works on my machine" never becomes a blocker. Managing pyproject.toml and uv.lock prevents version drift, and .env files keep sensitive values safe while sharing structure.

Practice

  • Follow along: In a blank folder, run uv init, uv add requests, and uv add --dev pytest, then inspect pyproject.toml.
  • Extend: Create .env.example and capture logs from uv run --env-file to prove env vars load correctly.
  • Debug: Run uv sync --frozen, edit pyproject, trigger an error, then resolve it by updating the lockfile or reverting.
  • Done when: pyproject, uv.lock, and .env.example sit together and a single command reproduces the environment anywhere.

Wrap up

With virtualenvs and pyproject management in place, you eliminate package conflicts and "but it works locally" moments. Next we'll leverage this environment to automate testing and raise the confidence bar again.

💬 댓글

이 글에 대한 의견을 남겨주세요