Practical Python
Build reliable Python projects with modern tooling, web APIs, databases, data libraries, and layered tests.
Practical Python
Knowing Python syntax is only the beginning. Production work also requires repeatable environments, clear package boundaries, automated checks, defensive network code, persistent data, and tests that give useful feedback. This section connects those concerns into one workflow.
What you will build
The examples progress from a small package to a capstone application with three interfaces:
- a reusable Python package containing domain logic;
- a command-line interface for local and scripted use;
- a typed FastAPI service backed by a relational database.
Along the way, you will use NumPy and Pandas when a problem is naturally tabular or numerical. They are tools for specific workloads, not automatic replacements for Python collections.
Recommended baseline
Use Python 3.12 or newer unless your deployment target requires an older supported version. Install uv for project and environment management:
# macOS and Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows PowerShell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"Confirm the tools:
python --version
uv --versionYou can complete most examples with pip and venv; the packaging chapter shows both paths.
A practical feedback loop
For each change:
- Express the behavior with a focused test.
- Implement the smallest coherent change.
- Format and lint with Ruff or Black plus Ruff.
- Type-check public boundaries with mypy.
- Run focused tests, then the complete suite.
- Check coverage trends and uncovered branches.
- Exercise the real integration boundary when risk justifies it.
A typical local command sequence is:
uv run ruff format --check .
uv run ruff check .
uv run mypy src
uv run pytest
uv run pytest --cov=your_package --cov-branch --cov-report=term-missingChoose tools by constraint
| Need | Good default | Reconsider when |
|---|---|---|
| Fast project setup and lockfiles | uv | A company standard mandates another resolver |
| Linting and formatting | Ruff | Existing Black behavior must remain byte-for-byte stable |
| Static typing | mypy | Your organization standardizes on another checker |
| Tests | pytest | A dependency requires unittest conventions |
| Synchronous HTTP | Requests | You need async concurrency or HTTP/2 |
| Async-capable HTTP | HTTPX | A mature Requests integration already meets the need |
| Small embedded database | sqlite3 | Multiple writers or remote access are required |
| Rich relational persistence | SQLAlchemy | Direct SQL is simpler and the schema is tiny |
| Numerical arrays | NumPy | Data is heterogeneous or label-oriented |
| Tabular analysis | Pandas | The workload exceeds memory or needs transactional guarantees |
How to use this section
Each page includes:
- setup commands that can be copied into a clean project;
- modern, typed examples with explicit error behavior;
- common pitfalls and decision points;
- practice tasks that force you to adapt, not only copy, the examples.
Read in order for a complete project workflow, or jump directly to the page matching your current task. The capstone combines every major topic into a staged roadmap.
Before you continue
Create a scratch project:
uv init practical-python
cd practical-python
uv python pin 3.12
uv add --dev pytest ruff mypyThe generated .venv should not be committed. Commit pyproject.toml and uv.lock so collaborators
resolve the same dependency graph.
Practice
- Write down the oldest Python version your project supports and why.
- Identify one external boundary in a current project: HTTP, filesystem, database, or clock.
- Decide which checks must run before every commit and which can wait for CI.
- Define one measurable outcome for the capstone, such as “import 10,000 rows and expose filtered results through both CLI and API.”
LEARNING RECORD
Finish this lesson
Mark it complete when you can explain the main decision without looking.
KNOWLEDGE CHECK