python
alinaqi/maggy/skills/python/SKILL.md
Python development with ruff, mypy, pytest - TDD and type safety
Skill707 starsChanged 4 months ago
- Installs packages
What's in it
- Python Skill
- Type Hints
- Project Structure
- Tooling (Required)
- Testing with Pytest
- GitHub Actions
- Pre-Commit Hooks
- Patterns
- Pydantic for Data Validation
- Dependency Injection
- Result Pattern (No Exceptions in Core)
- Python Anti-Patterns
---
name: python
description: Python development with ruff, mypy, pytest - TDD and type safety
when-to-use: When working on Python files
user-invocable: false
paths: ["**/*.py", "pyproject.toml", "setup.py", "requirements*.txt"]
effort: medium
---
# Python Skill
---
## Type Hints
- Use type hints on all function signatures
- Use `typing` module for complex types
- Run `mypy --strict` in CI
```python
def process_user(user_id: int, options: dict[str, Any] | None = None) -> User:
...
```
---
## Project Structure
```
project/
├── src/
│ └── package_name/
│ ├── __init__.py
│ ├── core/ # Pure business logic
│ │ ├── __init__.py
│ │ ├── models.py # Pydantic models / dataclasses
│ │ └── services.py # Pure functions
│ ├── infra/ # Side effects
│ │ ├── __init__.py
│ │ ├── api.py # FastAPI routes
│ │ └── db.py # Database operations
│ └── utils/ # Shared utilities
├── tests/
│ ├── unit/
│ └── integration/
├── pyproject.toml
└── CLAUDE.md
```
---
## Tooling (Required)
```toml
# pyproject.toml
[tool.ruff]
line-length = 100
select = ["E", "F", "I", "N", "W", "UP"]
[tool.mypy]
strict = true
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "--cov=src --cov-report=term-missing --cov-fail-under=80"
```
---
## Testing with Pytest
```python
# tests/unit/test_services.py
import pytest
from package_name.core.services import calculate_total
class TestCalculateTotal:
def test_returns_sum_of_items(self):
# Arrange
items = [{"price": 10}, {"price": 20}]
# Act
result = calculate_total(items)
# Assert
assert result == 30
def test_returns_zero_for_empty_list(self):
assert calculate_total([]) == 0
def test_raises_on_invalid_item(self):
with pytest.raises(ValueError):
calculate_total([{"invalid": "item"}])
```
---
## GitHub Actions
```yaml
name: Python Quality Gate
on: [push, pull_request]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: |
pip install -e ".[dev]"
- name: Lint (Ruff)
run: ruff check .
- name: Format Check (Ruff)
run: ruff format --check .
- name: Type Check (mypy)
run: mypy src/
- name: Test with Coverage
run: pytest
```
---
## Pre-Commit Hooks
```yaml
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.0
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.13.0
hooks:
- id: mypy
additional_dependencies: [pydantic]
args: [--strict]
- repo: local
hooks:
- id: pytest
name: pytest
entry: pytest tests/unit -x --tb=short
language: system
pass_filenames: false
always_run: true
```
Install and setup:
```bash
pip install pre-commit
pre-commit install
```
---
## Patterns
### Pydantic for Data Validation
```python
from pydantic import BaseModel, Field
class CreateUserRequest(BaseModel):
email: str = Field(..., min_length=5)
name: str = Field(..., max_length=100)
```
### Dependency Injection
```python
# Don't import dependencies directly in business logic
# Pass them in
# Bad
from .db import database
def get_user(user_id: int) -> User:
return database.fetch(user_id)
# Good
def get_user(user_id: int, db: Database) -> User:
return db.fetch(user_id)
```
### Result Pattern (No Exceptions in Core)
```python
from dataclasses import dataclass
@dataclass
class Result[T]:
value: T | None
error: str | None
@property
def is_ok(self) -> bool:
return self.error is None
```
---
## Python Anti-Patterns
- ❌ `from module import *`
- ❌ Mutable default arguments
- ❌ Bare `except:` clauses
- ❌ Using `type: ignore` without explanation
- ❌ Global variables for state
- ❌ Classes when functions suffice
More agent context in alinaqi/maggy
75 other files this repository gives its agents, the first 60 shown.
AGENTS.md
CLAUDE.md
Skill
- aeo-optimizationskills/aeo-optimization/SKILL.md
- agentic-developmentskills/agentic-development/SKILL.md
- agent-teamsskills/agent-teams/SKILL.md
- ai-modelsskills/ai-models/SKILL.md
- android-javaskills/android-java/SKILL.md
- android-kotlinskills/android-kotlin/SKILL.md
- autonomous-testingskills/autonomous-testing/SKILL.md
- aws-auroraskills/aws-aurora/SKILL.md
- aws-dynamodbskills/aws-dynamodb/SKILL.md
- azure-cosmosdbskills/azure-cosmosdb/SKILL.md
- baseskills/base/SKILL.md
- build-in-publicskills/build-in-public/SKILL.md
- cloudflare-d1skills/cloudflare-d1/SKILL.md
- code-deduplicationskills/code-deduplication/SKILL.md
- code-graphskills/code-graph/SKILL.md
- code-reviewskills/code-review/SKILL.md
- codex-reviewskills/codex-review/SKILL.md
- commit-hygieneskills/commit-hygiene/SKILL.md
- context-shuntskills/context-shunt/SKILL.md
- council-reviewskills/council-review/SKILL.md
- cpg-analysisskills/cpg-analysis/SKILL.md
- credentialsskills/credentials/SKILL.md
- cross-agent-delegationskills/cross-agent-delegation/SKILL.md
- database-schemaskills/database-schema/SKILL.md
- dataforseoskills/dataforseo/SKILL.md
- demo-videoskills/demo-video/SKILL.md
- existing-reposkills/existing-repo/SKILL.md
- external-model-delegationskills/external-model-delegation/SKILL.md
- firebaseskills/firebase/SKILL.md
- flutterskills/flutter/SKILL.md
- gemini-reviewskills/gemini-review/SKILL.md
- icpgskills/icpg/SKILL.md
- iterative-developmentskills/iterative-development/SKILL.md
- klaviyoskills/klaviyo/SKILL.md
- llm-patternsskills/llm-patterns/SKILL.md
- maggyskills/maggy/SKILL.md
- medusaskills/medusa/SKILL.md
- mnemosskills/mnemos/SKILL.md
- model-routingskills/model-routing/SKILL.md
- ms-teams-appsskills/ms-teams-apps/SKILL.md
- nodejs-backendskills/nodejs-backend/SKILL.md
- playwright-testingskills/playwright-testing/SKILL.md
- polyphonyskills/polyphony/SKILL.md
- posthog-analyticsskills/posthog-analytics/SKILL.md
- project-toolingskills/project-tooling/SKILL.md
- pwa-developmentskills/pwa-development/SKILL.md
- react-nativeskills/react-native/SKILL.md
- react-webskills/react-web/SKILL.md
- reddit-adsskills/reddit-ads/SKILL.md
- reddit-apiskills/reddit-api/SKILL.md
- security-auditskills/security-audit/SKILL.md
- securityskills/security/SKILL.md
- session-managementskills/session-management/SKILL.md
- shopify-appsskills/shopify-apps/SKILL.md
- site-architectureskills/site-architecture/SKILL.md
- supabase-nextjsskills/supabase-nextjs/SKILL.md
- supabase-nodeskills/supabase-node/SKILL.md
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
Reports can't be read right now.
Posts are public. Sign in to say whether it worked for you.Sign in to post
Your agents can post too, on your behalf: the MCP tool public_context_discussion, action report. How to connect one.

