Skilllibrary python
Guides Python project structure, tooling, and conventions: src layout vs flat, virtual environments (venv/poetry/uv), type hints with mypy/pyright, dependency management (pyproject.toml, poetry, uv), pytest testing, ruff/black linting, structured logging, async patterns, dataclasses/Pydantic, and packaging.
install
source · Clone the upstream repo
git clone https://github.com/merceralex397-collab/skilllibrary
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/merceralex397-collab/skilllibrary "$T" && mkdir -p ~/.claude/skills && cp -r "$T/09-backend-api-and-data/python" ~/.claude/skills/merceralex397-collab-skilllibrary-python && rm -rf "$T"
manifest:
09-backend-api-and-data/python/SKILL.mdsource content
Purpose
Guides the structure, tooling, and conventions of Python projects—from virtual environment setup and dependency management through type annotations, testing with pytest, linting with ruff/black, structured logging, async patterns, and packaging for distribution. This skill covers the language-level foundations that framework-specific skills (Flask, FastAPI) build upon.
When to use this skill
Use this skill when:
- setting up a new Python project (directory layout, pyproject.toml, virtual environment)
- configuring type checking with mypy or pyright
- writing or improving pytest tests (fixtures, parametrize, coverage)
- setting up linting/formatting with ruff, black, or isort
- managing dependencies with poetry, uv, pip, or pip-tools
- working with dataclasses or Pydantic models for data structures
- implementing async code with asyncio
- configuring structured logging (stdlib logging or structlog)
- packaging a Python library or application for distribution
- managing Python versions with pyenv
Do not use this skill when
- the task is Flask-specific (routing, blueprints, extensions)—prefer
skillflask - the task is FastAPI-specific (path operations, dependency injection)—prefer
skillfastapi - the task is purely about database queries or ORM patterns—prefer
orm-patterns - the task involves no Python code at all
Operating procedure
- Assess project layout. Determine if the project uses
layout or flat layout. For new projects, prefersrc/
layout for proper import isolation. Check forsrc/
,pyproject.toml
, orsetup.py
.setup.cfg - Set up virtual environment. Use
for simple projects,python -m venv .venv
for Poetry-managed projects, orpoetry install
for uv-managed projects. Verify the venv is activated.uv venv && uv pip install -e . - Configure dependencies. Define dependencies in
(preferred) orpyproject.toml
. Pin direct dependencies with version constraints. Use lock files (requirements.txt
,poetry.lock
) for reproducible builds.uv.lock - Add type annotations. Annotate function signatures, class attributes, and return types. Configure mypy or pyright in
. Run type checking:pyproject.toml
ormypy src/
.pyright - Write tests. Use pytest with fixtures for test setup,
for data-driven tests, and@pytest.mark.parametrize
for shared fixtures. Run withconftest.py
.pytest tests/ -v --cov=src - Configure linting. Set up ruff for linting and formatting (replaces flake8 + isort + black). Configure in
underpyproject.toml
. Run with[tool.ruff]
andruff check .
.ruff format . - Set up logging. Use
or structlog for structured logging. Never uselogging.config.dictConfig()
for operational output. Configure log levels per environment.print() - Verify the full pipeline. Run type check → lint → format → test → build in sequence:
.mypy src/ && ruff check . && pytest tests/ -v
Decision rules
- Use
as the single source of project metadata and tool configuration—avoidpyproject.toml
,setup.py
,setup.cfg
, and scattered config files where possible.tox.ini - Prefer
layout for libraries and packages (prevents accidental import of uninstalled code). Use flat layout only for simple scripts or single-module projects.src/ - Always use virtual environments. Never install project dependencies into the system Python.
- Type-annotate all public function signatures. Use
for forward references (Python 3.7–3.9).from __future__ import annotations - Use
for simple data containers. Use Pydanticdataclasses.dataclass
when you need validation, serialization, or schema generation.BaseModel - Prefer
over separate flake8 + isort + black tools—it's faster and combines all three.ruff - Use
overpytest
—it has less boilerplate, better fixtures, and richer plugin ecosystem.unittest - For async code, use
at the entry point. Useasyncio.run()
/async def
consistently through the call chain—don't mix sync and async withoutawait
.asyncio.to_thread() - Pin direct dependencies with version ranges (
). Let the lock file pin transitives.>=1.0,<2.0 - Use
for per-module loggers. Never use the root logger directly.logging.getLogger(__name__)
Output requirements
— layout, pyproject.toml, virtual environment setupProject Structure
— code with type annotations, data structuresImplementation
— pytest tests, fixtures, parametrize, coverage commandTesting
— mypy/ruff configuration, linting resultsQuality
— full pipeline command sequenceVerification
References
Read these only when relevant:
— project layout, config, typing, logging, async patternsreferences/implementation-patterns.md
— pre-merge quality gates and checksreferences/validation-checklist.md
— common Python development pitfalls and their fixesreferences/failure-modes.md
Related skills
— Flask web application developmentflask
— FastAPI web application developmentfastapi
— SQLAlchemy and database patternsorm-patterns
— advanced logging and observabilityobservability-logging
— Celery, RQ, and async task processingbackground-jobs-queues
Anti-patterns
- No virtual environment. Installing packages into the system Python, causing dependency conflicts across projects and non-reproducible builds.
carpet-bombing. Addingtype: ignore
to silence all type errors instead of fixing them. Undermines the value of type checking entirely.# type: ignore- Mutable default arguments. Using
—the list is shared across all calls. Usedef f(items=[]):
.def f(items=None): items = items or [] - Bare
. Writingexcept
orexcept:
that catches and swallows all errors, includingexcept Exception:
andKeyboardInterrupt
.SystemExit - Circular imports. Module A imports from module B at the top level, and module B imports from module A. Restructure or use late imports.
- Star imports. Using
which pollutes the namespace and makes it impossible to trace where names come from.from module import * - Print debugging in production. Using
instead ofprint()
. Print goes to stdout with no level, timestamp, or structured fields.logging - Pinning transitive dependencies. Manually pinning versions of transitive dependencies in
instead of using a lock file, causing maintenance burden and conflicts.requirements.txt - Missing
. Forgetting__init__.py
in package directories (required for regular packages; namespace packages are a deliberate advanced pattern).__init__.py - Exception swallowing.
—catching an exception and doing nothing, hiding bugs.try: ... except SomeError: pass
Failure handling
- If imports fail with
, verify the virtual environment is activated and the package is installed (ModuleNotFoundError
).pip list | grep package - If circular imports occur, move shared types to a separate module or use
conditional imports for type-only references.TYPE_CHECKING - If mypy reports errors on third-party libraries, check for
marker or install type stubs (py.typed
).pip install types-requests - If pytest can't find tests, verify test files are named
and thetest_*.py
directory has antests/
(or configure__init__.py
in pytest config).pythonpath - If
andruff
conflict on formatting, switch toblack
which is black-compatible and eliminates the conflict.ruff format - If async code deadlocks, check for
called inside an already-running event loop, or blocking sync calls insideasyncio.run()
functions.async def