The Complete Python Developer Guide

A reference-quality, deep-dive guide for professional Python developers — from core language internals to the modern AI agent stack.

🌱 Seedling·created: ·category:Python

Language Mastery, Best Practices, Design Patterns, Ecosystem & AI/Agentic Tooling

A reference-quality, deep-dive guide for professional Python developers — from core language internals to the modern AI agent stack.


Table of Contents

  1. Language Fundamentals & Internals
  2. Modern Python Features (3.10 → 3.13+)
  3. Typing System Deep Dive
  4. Best Practices & Code Quality
  5. Design Patterns in Python
  6. Concurrency & Parallelism
  7. Testing Ecosystem
  8. Packaging, Environments & Tooling
  9. Web Frameworks & APIs
  10. Data Engineering & Scientific Stack
  11. Databases & ORMs
  12. CLI, Logging, Observability
  13. DevOps, CI/CD & Deployment
  14. AI / Agentic Engineering Stack
  15. Recommended Project Structure
  16. Curated “Must-Know” Library Cheat Sheet

1. Language Fundamentals & Internals

1.1 The Data Model

Python’s “magic” (dunder) methods define how objects behave with built-in operations. Mastering the data model is what separates idiomatic Python from “Python written like Java/C++.”

class Vector:
    __slots__ = ("x", "y")  # memory-efficient, disables __dict__

    def __init__(self, x: float, y: float):
        self.x, self.y = x, y

    def __repr__(self) -> str:
        return f"Vector({self.x!r}, {self.y!r})"

    def __add__(self, other: "Vector") -> "Vector":
        return Vector(self.x + other.x, self.y + other.y)

    def __eq__(self, other: object) -> bool:
        return isinstance(other, Vector) and (self.x, self.y) == (other.x, other.y)

    def __hash__(self) -> int:
        return hash((self.x, self.y))

    def __iter__(self):
        yield self.x
        yield self.y

Key dunder groups to know:

  • Construction/representation: __init__, __new__, __repr__, __str__, __format__
  • Comparison: __eq__, __lt__, functools.total_ordering
  • Container protocol: __len__, __getitem__, __setitem__, __contains__, __iter__
  • Callable objects: __call__
  • Context managers: __enter__, __exit__ (and __aenter__/__aexit__ for async)
  • Descriptors: __get__, __set__, __delete__ (power behind property, ORMs, functools.cached_property)
  • Attribute access hooks: __getattr__, __getattribute__, __setattr__

1.2 Everything Is an Object, Names Are References

Variables are labels bound to objects, not containers. This explains mutable default argument bugs, shallow vs. deep copy semantics (copy.copy vs copy.deepcopy), and why is checks identity while == checks equality.

# Classic gotcha
def append_item(item, bucket=[]):   # BAD: mutable default shared across calls
    bucket.append(item)
    return bucket

def append_item_fixed(item, bucket=None):
    bucket = bucket if bucket is not None else []
    bucket.append(item)
    return bucket

1.3 Iterators, Generators & Coroutines

def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

# Generator expression — lazy, memory-efficient
squares = (x * x for x in range(1_000_000))

# yield from delegates to a sub-generator
def chain(*iterables):
    for it in iterables:
        yield from it

Generators underpin asyncio coroutines, itertools pipelines, and memory-safe streaming of large datasets.

1.4 Decorators & Closures

import functools
import time

def retry(times: int = 3, delay: float = 1.0):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            last_exc = None
            for attempt in range(times):
                try:
                    return func(*args, **kwargs)
                except Exception as exc:
                    last_exc = exc
                    time.sleep(delay)
            raise last_exc
        return wrapper
    return decorator

@retry(times=5, delay=0.5)
def flaky_call():
    ...

Always use functools.wraps to preserve __name__, __doc__, and signature introspection.

1.5 Context Managers

from contextlib import contextmanager

@contextmanager
def timer(label: str):
    start = time.perf_counter()
    try:
        yield
    finally:
        print(f"{label}: {time.perf_counter() - start:.4f}s")

with timer("db-query"):
    run_query()

1.6 Metaclasses & __init_subclass__

Metaclasses control class creation; __init_subclass__ is the lighter-weight modern alternative for plugin/registry patterns:

class PluginBase:
    registry: dict[str, type] = {}

    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        PluginBase.registry[cls.__name__] = cls

1.7 The GIL & Memory Model

  • CPython uses a Global Interpreter Lock — only one thread executes Python bytecode at a time.
  • Python 3.13 introduced an experimental free-threaded build (PEP 703, “no-GIL” CPython) — a major shift for true multi-core parallelism with threads.
  • CPython uses reference counting + a generational garbage collector for cycle detection (gc module).
  • Implication: CPU-bound work → multiprocessing or native extensions; I/O-bound work → threading or asyncio.

2. Modern Python Features (3.10 → 3.13+)

VersionLandmark Features
3.10Structural pattern matching (match/case), better error messages, X | Y union syntax
3.11Massive interpreter speedups (Faster CPython project), exception groups (except*), Self type, tomllib
3.12New type parameter syntax (class Stack[T]), f-string parser overhaul, buffer protocol improvements
3.13Free-threaded (no-GIL) experimental build, JIT (experimental), improved REPL, better error tracebacks

2.1 Structural Pattern Matching

def handle_event(event: dict):
    match event:
        case {"type": "click", "x": x, "y": y}:
            print(f"Click at ({x}, {y})")
        case {"type": "key", "key": ("Enter" | "Return")}:
            submit_form()
        case {"type": str() as t}:
            print(f"Unknown event type: {t}")
        case _:
            raise ValueError("Malformed event")

2.2 New Generic Syntax (3.12+)

class Stack[T]:
    def __init__(self) -> None:
        self._items: list[T] = []

    def push(self, item: T) -> None:
        self._items.append(item)

    def pop(self) -> T:
        return self._items.pop()

def first[T](items: list[T]) -> T:
    return items[0]

2.3 Exception Groups

try:
    async with asyncio.TaskGroup() as tg:
        tg.create_task(fetch("a"))
        tg.create_task(fetch("b"))
except* ValueError as eg:
    for e in eg.exceptions:
        log.error(e)

3. Typing System Deep Dive

Type hints are optional but essential in professional codebases — they enable IDE support, static analysis, and self-documenting APIs.

from typing import TypedDict, Protocol, Literal, overload
from collections.abc import Sequence, Callable

class UserDict(TypedDict):
    id: int
    name: str
    role: Literal["admin", "member", "guest"]

class Comparable(Protocol):
    def __lt__(self, other) -> bool: ...

def sort_items[T: Comparable](items: Sequence[T]) -> list[T]:
    return sorted(items)

@overload
def parse(value: str) -> int: ...
@overload
def parse(value: bytes) -> int: ...
def parse(value):
    return int(value)

Static type checkers: mypy (reference implementation), pyright/pylance (fast, used by VS Code), pyre (Meta). Use mypy --strict or pyright --strict in CI for maximum safety.

Runtime validation: Static types are erased at runtime — use Pydantic or typeguard/beartype when you need runtime enforcement (e.g., parsing untrusted input, API boundaries).


4. Best Practices & Code Quality

4.1 Style & Structure

  • Follow PEP 8 (style) and PEP 257 (docstrings). Use Google-style or NumPy-style docstrings consistently.
  • One tool now covers linting and formatting: Ruff (Rust-based, replaces Flake8 + isort + pyupgrade + and largely Black for formatting).
  • Keep functions small and single-purpose; prefer composition over deep inheritance.
  • Use pathlib.Path instead of raw string path manipulation.
  • Prefer f-strings over % or .format().

4.2 Error Handling

class DomainError(Exception):
    """Base class for all domain-specific errors."""

class InsufficientFundsError(DomainError):
    def __init__(self, balance: float, requested: float):
        self.balance = balance
        self.requested = requested
        super().__init__(f"Balance {balance} < requested {requested}")
  • Never use bare except:. Catch specific exceptions.
  • Use custom exception hierarchies per domain/module.
  • Fail fast; validate inputs at boundaries (API layer, CLI layer).

4.3 Configuration Management

  • pydantic-settings for typed, validated env-based config.
  • python-dotenv for .env loading in dev.
from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    database_url: str
    debug: bool = False
    model_config = {"env_file": ".env"}

4.4 Logging (never print in production code)

import logging
logger = logging.getLogger(__name__)
logger.info("Processing order %s", order_id)

Use structured logging (structlog) for JSON logs in production, correlation IDs, and log aggregation compatibility.

4.5 Security Practices

  • Never hardcode secrets — use env vars / secret managers (AWS Secrets Manager, Vault, Doppler).
  • Use bandit for static security scanning.
  • Pin dependencies with lockfiles; scan with pip-audit / safety.
  • Validate all external input (Pydantic models at every trust boundary).

4.6 Documentation

  • mkdocs + mkdocs-material or Sphinx for docs sites.
  • Docstrings + type hints = auto-generated API references.
  • Maintain a CHANGELOG.md (Keep a Changelog format) and semantic versioning.

5. Design Patterns in Python

Python’s dynamic nature makes many classic GoF patterns simpler or unnecessary — but the ideas remain valuable.

5.1 Creational

  • Factory Function — plain functions/callables instead of Factory classes.
  • Builder — fluent chained methods, or simply keyword-argument-rich dataclasses.
  • Singleton — module-level instance (modules are singletons naturally), or functools.lru_cache(maxsize=None) on a constructor function.
@functools.lru_cache(maxsize=None)
def get_settings() -> Settings:
    return Settings()

5.2 Structural

  • Adapter — wrap an incompatible interface.
  • Decorator (structural, not @decorator syntax) — wrap objects to add behavior.
  • Facade — a simplified API in front of a complex subsystem (common in SDK wrapper design).

5.3 Behavioral

  • Strategy — pass functions as first-class objects instead of Strategy classes.
def process(data: list[int], strategy: Callable[[list[int]], int]) -> int:
    return strategy(data)

process(data, strategy=sum)
process(data, strategy=max)
  • Observer — event systems, blinker library, or simple pub/sub with callback lists.
  • Command — encapsulate a request as an object (used heavily in task queues / undo systems).
  • State Machinetransitions or python-statemachine libraries for explicit FSMs.

5.4 Dependency Injection

Python rarely needs a DI framework thanks to duck typing, but for larger apps:

  • FastAPI’s Depends() system.
  • dependency-injector library for explicit containers in non-web apps.

5.5 Repository & Unit of Work (DDD-adjacent)

Common in service-layer architectures to decouple business logic from persistence (SQLAlchemy session scope as Unit of Work).


6. Concurrency & Parallelism

ModelUse CaseTooling
ThreadingI/O-bound, blocking librariesthreading, concurrent.futures.ThreadPoolExecutor
AsyncioI/O-bound, high concurrency (network, DB)asyncio, httpx, aiohttp, asyncpg
MultiprocessingCPU-boundmultiprocessing, concurrent.futures.ProcessPoolExecutor, joblib
DistributedCross-machine parallelismCelery, Dask, Ray
import asyncio

async def fetch_all(urls: list[str]):
    async with httpx.AsyncClient() as client:
        tasks = [client.get(url) for url in urls]
        return await asyncio.gather(*tasks)

# Structured concurrency (3.11+)
async def main():
    async with asyncio.TaskGroup() as tg:
        tg.create_task(fetch_all(urls_a))
        tg.create_task(fetch_all(urls_b))
  • Ray is increasingly the go-to for distributed compute in ML/AI pipelines (also underlies many agent-serving frameworks).
  • Dask mirrors pandas/numpy APIs for out-of-core / distributed dataframes.

7. Testing Ecosystem

  • pytest — the de facto standard; fixtures, parametrization, plugins.
  • pytest-asyncio — testing async code.
  • pytest-cov — coverage integration.
  • hypothesis — property-based testing (generates edge cases automatically).
  • tox / nox — test across multiple Python versions/environments.
  • factory_boy / faker — test data generation.
  • responses / respx — mocking HTTP calls.
  • testcontainers-python — spin up real Docker dependencies (Postgres, Redis) for integration tests.
import pytest

@pytest.fixture
def client():
    return TestClient(app)

@pytest.mark.parametrize("value,expected", [(1, 2), (2, 4), (3, 6)])
def test_double(value, expected):
    assert double(value) == expected

@pytest.mark.asyncio
async def test_fetch():
    result = await fetch_data()
    assert result is not None

8. Packaging, Environments & Tooling

8.1 Modern Toolchain (2025-2026 consensus)

  • uv (Astral) — the new standard: blazing-fast package installer, resolver, and project manager (replaces pip, pip-tools, virtualenv, and largely Poetry for many teams).
  • Ruff (Astral) — linter + formatter, replacing Flake8/isort/Black in most new projects.
  • Poetry — still widely used for dependency + packaging management with pyproject.toml.
  • pyenv — manage multiple Python interpreter versions.
  • pipx — install/run CLI tools in isolated environments.
# uv workflow
uv init my-project
uv add fastapi httpx
uv run pytest
uv lock

8.2 pyproject.toml (PEP 621) is the single source of truth

[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["fastapi>=0.115", "pydantic>=2.0"]

[tool.ruff]
line-length = 100

[tool.mypy]
strict = true

8.3 Pre-commit Hooks

repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    hooks:
      - id: ruff
      - id: ruff-format

9. Web Frameworks & APIs

FrameworkBest For
FastAPIModern async APIs, auto OpenAPI docs, Pydantic-native — default choice for new services (and the backbone of most AI-serving APIs)
DjangoFull-stack batteries-included apps, admin panel, ORM, auth
Django REST FrameworkREST APIs on top of Django
FlaskLightweight, micro-services, simple apps
LitestarPerformance-focused FastAPI alternative with strong DI
StarletteASGI toolkit underlying FastAPI
from fastapi import FastAPI, Depends
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float

@app.post("/items")
async def create_item(item: Item):
    return {"id": 1, **item.model_dump()}

Serving: Uvicorn (ASGI server), Gunicorn (with Uvicorn workers) for production.


10. Data Engineering & Scientific Stack

  • NumPy — foundational n-dimensional array computing.
  • pandas — tabular data manipulation (industry default).
  • Polars — Rust-based, multi-threaded DataFrame library; dramatically faster than pandas for large data, increasingly the modern default.
  • PyArrow — columnar in-memory format, interop layer for pandas/Polars/Spark.
  • DuckDB — embedded analytical SQL engine, excellent for local analytics on Parquet/CSV.
  • Matplotlib / Seaborn / Plotly — visualization.
  • scikit-learn — classical ML.
  • PyTorch — deep learning (dominant framework for research and increasingly production).
  • JAX — high-performance numerical computing + autodiff, popular in research.
import polars as pl

df = pl.read_parquet("events.parquet")
result = (
    df.filter(pl.col("status") == "active")
      .group_by("country")
      .agg(pl.col("revenue").sum())
)

11. Databases & ORMs

  • SQLAlchemy 2.0 — the standard ORM/Core toolkit, fully async-capable with asyncpg/aiomysql.
  • SQLModel — SQLAlchemy + Pydantic combined, from the FastAPI author.
  • Alembic — schema migrations for SQLAlchemy.
  • Django ORM — tightly coupled to Django, very productive for CRUD-heavy apps.
  • Tortoise ORM — async-first, Django-ORM-like API.
  • asyncpg / psycopg3 — PostgreSQL drivers.
  • Redis-py — caching, pub/sub, queues.
  • MongoDB (PyMongo / Motor) — document store, async via Motor.
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import Mapped, mapped_column, DeclarativeBase

class Base(DeclarativeBase): pass

class User(Base):
    __tablename__ = "users"
    id: Mapped[int] = mapped_column(primary_key=True)
    email: Mapped[str]

12. CLI, Logging, Observability

  • Typer — modern CLI framework built on type hints (from the FastAPI author).
  • Click — mature, composable CLI framework (underlies Typer).
  • Rich — beautiful terminal output, tables, progress bars, tracebacks.
  • structlog — structured logging.
  • OpenTelemetry — distributed tracing/metrics standard, framework-agnostic.
  • Sentry — error tracking/monitoring.
  • Prometheus client — metrics exposition for scraping.
import typer
from rich import print

app = typer.Typer()

@app.command()
def greet(name: str, loud: bool = False):
    msg = f"Hello, {name}!"
    print(msg.upper() if loud else msg)

if __name__ == "__main__":
    app()

13. DevOps, CI/CD & Deployment

  • Docker — containerization; use multi-stage builds + uv/pip --no-cache-dir for slim images.
  • GitHub Actions / GitLab CI — standard CI/CD.
  • Kubernetes — orchestration for larger deployments.
  • Terraform — infra-as-code (often paired with Python via pulumi for Python-native IaC).
  • Pulumi — infra-as-code written in actual Python.
  • Makefile or just (command runner) for standardized dev commands.
FROM python:3.13-slim AS builder
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev

FROM python:3.13-slim
COPY --from=builder /app /app
CMD ["uv", "run", "uvicorn", "main:app", "--host", "0.0.0.0"]

14. AI / Agentic Engineering Stack

This section covers the libraries and patterns essential for building LLM-powered applications and autonomous agents in 2025-2026.

14.1 Core LLM SDKs

  • anthropic — official Claude SDK (Messages API, tool use/function calling, streaming, batch API, prompt caching).
  • openai — official OpenAI SDK (Chat Completions/Responses API, function calling, Assistants/Realtime API).
  • litellm — unified interface across 100+ LLM providers with a single OpenAI-compatible API — extremely popular for provider-agnostic apps.
import anthropic

client = anthropic.Anthropic()
response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    tools=[{
        "name": "get_weather",
        "description": "Get current weather for a location",
        "input_schema": {
            "type": "object",
            "properties": {"location": {"type": "string"}},
            "required": ["location"],
        },
    }],
    messages=[{"role": "user", "content": "What's the weather in Istanbul?"}],
)

14.2 Structured Output & Validation

  • Pydantic v2 — the backbone of nearly every agent framework; defines tool schemas, validates LLM output, powers FastAPI request/response models.
  • instructor — patches LLM clients to return validated Pydantic objects directly from completions (huge for reliable structured extraction).
  • outlines — constrained/guided generation (grammars, regex, JSON schema enforcement) at the token level for open-weight models.
import instructor
from pydantic import BaseModel

class Person(BaseModel):
    name: str
    age: int

client = instructor.from_anthropic(anthropic.Anthropic())
person = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    response_model=Person,
    messages=[{"role": "user", "content": "Extract: John is 30 years old"}],
)

14.3 Agent Orchestration Frameworks

FrameworkPhilosophy
LangGraphGraph-based, low-level, explicit state machines for agents — the current favorite for production-grade, controllable agent workflows; built by the LangChain team
LangChainBroad ecosystem of chains, retrievers, memory, integrations — good for rapid prototyping, RAG pipelines
CrewAIRole-based multi-agent orchestration (agents as “crew members” with roles/goals/tasks)
AutoGen (AG2) / Microsoft Agent FrameworkConversation-driven multi-agent systems, strong in research/enterprise settings
LlamaIndexData framework specialized in RAG — indexing, retrieval, query engines over documents
Semantic KernelMicrosoft’s SDK, plugin/skill-based orchestration, strong .NET/Python parity
OpenAI Agents SDKLightweight official agent/handoff/guardrail primitives from OpenAI
Pydantic AIType-safe, Pydantic-native agent framework — minimal, testable, dependency-injection style
smolagents (Hugging Face)Minimalist, code-writing agents (agents that write & execute Python to act)
# LangGraph-style explicit agent state machine (conceptual)
from langgraph.graph import StateGraph, END

class AgentState(TypedDict):
    messages: list
    next_step: str

graph = StateGraph(AgentState)
graph.add_node("plan", plan_node)
graph.add_node("act", act_node)
graph.add_node("reflect", reflect_node)
graph.add_conditional_edges("reflect", should_continue, {"continue": "plan", "done": END})
graph.set_entry_point("plan")
app = graph.compile()

14.4 The Model Context Protocol (MCP)

MCP (introduced by Anthropic, now widely adopted across the industry) is an open standard for connecting LLM applications to external tools, data sources, and services — think “USB-C for AI applications.” Key building blocks:

  • mcp Python SDK — build MCP servers/clients.
  • Servers expose tools, resources, and prompts over a standard JSON-RPC-based transport (stdio, HTTP/SSE).
  • Rapidly becoming the standard way agent frameworks (Claude, LangGraph, CrewAI, custom agents) discover and call external tools, replacing bespoke tool-calling glue code.
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("weather-server")

@mcp.tool()
def get_forecast(city: str) -> str:
    """Get weather forecast for a city."""
    return fetch_weather(city)

if __name__ == "__main__":
    mcp.run()

14.5 Vector Databases & Retrieval (RAG)

  • Chroma — simple, embedded, popular for local/dev RAG.
  • Qdrant — high-performance, Rust-based, strong filtering support.
  • Weaviate — hybrid search (vector + keyword), schema-based.
  • Pinecone — fully managed, serverless vector DB.
  • pgvector — vector search as a Postgres extension (great when you already run Postgres).
  • FAISS (Meta) — in-process similarity search library, foundational/low-level.
import chromadb

client = chromadb.PersistentClient(path="./db")
collection = client.get_or_create_collection("docs")
collection.add(documents=[...], ids=[...], embeddings=[...])
results = collection.query(query_texts=["What is RAG?"], n_results=5)

14.6 Embeddings & Reranking

  • sentence-transformers — open-source embedding/reranking models.
  • OpenAI / Voyage AI / Cohere embedding APIs — hosted, high-quality embeddings.
  • Cohere Rerank / cross-encoder rerankers — improve retrieval precision post-vector-search.

14.7 Observability & Evaluation for LLM Apps

  • LangSmith — tracing, evaluation, dataset management (LangChain ecosystem).
  • Langfuse — open-source LLM observability, tracing, prompt management, evals.
  • Helicone — proxy-based LLM logging/observability/cost tracking.
  • Ragas — RAG-specific evaluation metrics (faithfulness, context precision/recall).
  • promptfoo — prompt testing/regression framework, CI-friendly.
  • DeepEval — pytest-style unit testing framework for LLM outputs.
from ragas import evaluate
from ragas.metrics import faithfulness, context_precision

results = evaluate(dataset, metrics=[faithfulness, context_precision])

14.8 Prompt Engineering & Templates

  • Jinja2 — templating engine widely used for dynamic prompt construction.
  • anthropic/openai prompt caching — reduce cost/latency for repeated large system prompts/context.
  • Version prompts like code: store in files/DB, review via PRs, evaluate with promptfoo/Langfuse before deploying.

14.9 Local & Open-Weight Model Serving

  • Ollama — simplest way to run open-weight models locally.
  • vLLM — high-throughput inference server (PagedAttention), the production standard for self-hosted LLM serving.
  • Hugging Face transformers / accelerate — model loading, fine-tuning, inference.
  • LoRA / PEFT / peft library — efficient fine-tuning of large models.
  • llama.cpp / GGUF — CPU-friendly quantized model inference.

14.10 Multi-Agent Communication & Guardrails

  • Guardrails AI — validation/guardrail framework for LLM inputs/outputs (PII detection, toxicity, schema enforcement).
  • NeMo Guardrails (NVIDIA) — programmable rails for conversational safety/topic control.
  • A2A (Agent2Agent) protocol — emerging standard (Google-led) for agent-to-agent interoperability, complementing MCP’s tool-access focus.

14.11 A Minimal but Realistic Agentic Stack (2026)

LLM: Anthropic Claude / OpenAI GPT (via `anthropic`/`openai`/`litellm`)
Orchestration: LangGraph or Pydantic AI
Tools: MCP servers (custom + community)
Structured I/O: Pydantic v2 + `instructor`
Retrieval: Qdrant/pgvector + sentence-transformers + Cohere Rerank
Observability: Langfuse
Evaluation: Ragas + promptfoo (CI gate)
Serving: FastAPI + Uvicorn, Docker, behind an API gateway

my-project/
├── pyproject.toml
├── uv.lock
├── README.md
├── .pre-commit-config.yaml
├── .github/workflows/ci.yml
├── src/
│   └── my_project/
│       ├── __init__.py
│       ├── api/            # FastAPI routers
│       ├── core/           # config, logging, security
│       ├── domain/         # business models, exceptions
│       ├── services/       # business logic
│       ├── repositories/   # data access
│       ├── agents/         # agent graphs, tools, prompts
│       └── schemas/        # Pydantic models
└── tests/
    ├── unit/
    ├── integration/
    └── conftest.py

16. Curated “Must-Know” Library Cheat Sheet

CategoryLibraries
Package/env managementuv, poetry, pyenv, pipx
Lint/format/type-checkruff, mypy, pyright
Testingpytest, hypothesis, tox, nox, testcontainers
Web frameworksfastapi, django, flask, litestar
Data validationpydantic
Data/Scientificnumpy, pandas, polars, pyarrow, duckdb
ML/DLscikit-learn, pytorch, jax, transformers
DB/ORMsqlalchemy, sqlmodel, alembic, asyncpg
Async HTTPhttpx, aiohttp
CLItyper, click, rich
Logging/Observabilitystructlog, opentelemetry, sentry-sdk
AI/Agentic — LLM SDKsanthropic, openai, litellm
AI/Agentic — orchestrationlanggraph, langchain, crewai, autogen, pydantic-ai, llama-index
AI/Agentic — structured outputinstructor, outlines
AI/Agentic — tools/protocolmcp
AI/Agentic — vector DBchromadb, qdrant-client, weaviate-client, pinecone
AI/Agentic — evaluationragas, deepeval, promptfoo
AI/Agentic — observabilitylangfuse, langsmith
AI/Agentic — servingvllm, ollama, llama-cpp-python

Final Notes

  • Prioritize readability and explicitness over cleverness — “Simple is better than complex” (The Zen of Python).
  • Keep your toolchain lean: uv + ruff + pytest + mypy/pyright covers 90% of professional needs.
  • In the agentic space specifically, favor explicit, inspectable state machines (LangGraph, Pydantic AI) over “magic” autonomous loops for anything production-critical — controllability and observability matter more than raw autonomy.

This note is part of the Digital Garden — a collection of connected, evolving thoughts.