.config/opencode/skills/python-dev-guidelines/SKILL.md
Python conventions, patterns, and workflows. Use when writing code, reviewing PRs, or setting up new Python projects.
npx skillsauth add alexismanuel/dotfiles python-dev-guidelinesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Strong preferences, pragmatic adaptation.
| Tool | Purpose | |------|---------| | uv | Package management, virtual environments | | ruff | Linting + formatting (replaces flake8, isort, black) | | mypy | Type checking (standard mode) | | alembic | Database migrations (if existing in project) | | pytest | Testing framework | | pytest-asyncio | Async test support |
| Category | Standard | |----------|----------| | Line length | 119 characters | | Import order | isort-style (project first, then third-party) | | Type annotations | Full coverage ideal, gradual pragmatically | | Naming | PEP8 (ClassNames, snake_case_functions) | | Docstrings | Google-style on all public functions | | Complexity | Max 12, extract ruthlessly into small functions |
# Project imports first
from app.api.v1.users.repository import UserRepository
from app.api.v1.users.exceptions import UserNotFoundError
from app.database import get_session
# Third-party imports
import structlog
from fastapi import HTTPException
from pydantic import BaseModel
Vertical slices mirroring API routes:
app/
├── api/
│ └── v1/
│ ├── users/
│ │ ├── __init__.py
│ │ ├── router.py # API routes
│ │ ├── service.py # Business logic
│ │ ├── repository.py # Data access
│ │ ├── models.py # SQLAlchemy/Pydantic models
│ │ └── exceptions.py # Domain exceptions
│ └── orders/
│ └── ... # Same structure
├── database.py # Cross-cutting: DB connection
├── config.py # Cross-cutting: Settings
├── logging.py # Cross-cutting: Logging setup
└── main.py
For new projects: Error as Value pattern - functions return (result, error) tuples.
For existing projects: Respect existing try/except patterns.
Flat hierarchy in dedicated exceptions.py:
class UserNotFoundError(Exception):
"""Raised when user lookup returns no results."""
pass
class ValidationError(Exception):
"""Raised when input validation fails."""
pass
class DatabaseConnectionError(Exception):
"""Raised when database connection fails."""
pass
from app.api.v1.users.exceptions import DatabaseConnectionError, DatabaseQueryError
async def get_by_id(
session: AsyncSession,
user_id: str,
) -> tuple[User | None, DatabaseConnectionError | DatabaseQueryError | None]:
try:
result = await session.execute(select(User).where(User.id == user_id))
return result.scalar_one_or_none(), None
except OperationalError as e:
return None, DatabaseConnectionError(f"Connection failed: {e}")
except SQLAlchemyError as e:
return None, DatabaseQueryError(f"Query failed: {e}")
async def get_user(
session: AsyncSession,
user_id: str,
) -> tuple[User | None, ServiceError | None]:
user, error = await repository.get_by_id(session, user_id)
match error:
case DatabaseConnectionError() | DatabaseQueryError():
return None, ServiceError(f"Failed to fetch user {user_id}: {error}")
case None if user is None:
return None, ServiceError(f"User {user_id} not found")
case None:
return user, None
@router.get("/users/{user_id}")
async def get_user(user_id: str, session: AsyncSession = Depends(get_session)):
user, error = await service.get_user(session, user_id)
match error:
case ServiceError() if "not found" in str(error):
raise HTTPException(status_code=404, detail=str(error))
case ServiceError():
raise HTTPException(status_code=500, detail=str(error))
case None:
return user
See python-testing-guidelines skill for full details.
Key principles:
Mock, MagicMock, AsyncMock, or patch()app/api/v1/users/ → tests/api/v1/users/New projects: Pydantic Settings
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
database_url: str
api_key: str
debug: bool = False
class Config:
env_file = ".env"
settings = Settings()
Existing projects: Adapt to existing pattern.
| Context | Approach |
|---------|----------|
| Services, APIs | Structured logging (structlog) |
| Scripts, tools | print() or basic logging |
| Context | Approach |
|---------|----------|
| Services, APIs | async/await |
| Scripts, CLI tools | Sync |
Prefer explicit injection:
# Good - explicit
async def get_user(user_id: str, repository: UserRepository):
return await repository.get_by_id(user_id)
# Acceptable - module singleton for breaking circular deps
_session_factory = None
def get_session_factory():
global _session_factory
if _session_factory is None:
_session_factory = create_session_factory()
return _session_factory
development
Generate GitLab merge request descriptions from git commits with automatic categorization and Jira integration.
development
This skill should be used when validating that an implementation plan was correctly executed. It verifies success criteria, runs tests, identifies deviations, and presents structured completion options including MR creation or discard.
development
This skill should be used when reviewing code changes in a branch against main/master/develop. It analyzes commits, integrates JIRA ticket and MR context when available, and produces a structured code review using Conventional Comments format.
development
This skill should be used when conducting comprehensive codebase research to answer questions, understand architecture, or prepare context for implementation planning. It spawns parallel sub-agents and synthesizes findings into a structured research document.