Skip to content

Commit 7c2c719

Browse files
committed
docs(agents): add repository agent guide
1 parent 9f19d33 commit 7c2c719

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

AGENTS.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# AGENTS.md
2+
3+
This file guides automated coding agents working in this repository.
4+
Follow existing patterns and run the same tooling as humans.
5+
6+
## Project overview
7+
8+
- Language: Python 3.9+
9+
- Package: `fastapi_api_key` (src layout)
10+
- Async-first services and repositories
11+
- Optional extras for FastAPI, SQLAlchemy, Argon2, bcrypt, aiocache
12+
13+
## Tooling and environment
14+
15+
- Dependency manager: `uv`
16+
- Build backend: `hatchling`
17+
- Format/lint: Ruff
18+
- Type checks: Ty and Pyrefly
19+
- Security lint: Bandit
20+
- Tests: pytest + pytest-cov + pytest-asyncio
21+
22+
## Build, lint, and test commands
23+
24+
### Install (dev)
25+
26+
- `uv sync --extra all --group dev`
27+
- `source .venv/bin/activate` (or Windows `.venv\Scripts\Activate.ps1`)
28+
29+
### Lint and format
30+
31+
- `make lint`
32+
- Runs: `ruff format`, `ruff check --fix`, `ty check`, `pyrefly check`, `bandit`
33+
- Direct commands:
34+
- `uv run ruff format .`
35+
- `uv run ruff check --fix .`
36+
- `uv run ty check .`
37+
- `uv run pyrefly check .`
38+
- `uv run bandit -c pyproject.toml -r src examples -q`
39+
40+
### Tests
41+
42+
- Full test suite: `uv run pytest`
43+
- Single test file: `uv run pytest tests/unit/test_service.py`
44+
- Single test by node id:
45+
- `uv run pytest tests/unit/test_service.py::test_create_api_key`
46+
- Single test by keyword:
47+
- `uv run pytest -k "create_api_key"`
48+
- Run a test class: `uv run pytest tests/unit/test_service.py::TestApiKeyService`
49+
50+
### Coverage output
51+
52+
Pytest defaults include coverage reports (XML/HTML/terminal) via `pyproject.toml`.
53+
Artifacts: `coverage.xml`, `htmlcov/`, `junit.xml`.
54+
55+
## Code style and conventions
56+
57+
### Formatting
58+
59+
- Ruff handles formatting; follow it instead of manual styling.
60+
- Line length: 120 characters.
61+
- Indentation: 4 spaces.
62+
- Quotes: double quotes.
63+
64+
### Imports
65+
66+
- Standard library imports first, then third-party, then local.
67+
- Prefer explicit imports over wildcard.
68+
- Keep module-level imports; avoid local imports unless required to break cycles.
69+
- In optional dependency modules, guard imports with `try/except ModuleNotFoundError`.
70+
71+
### Typing
72+
73+
- Use Python 3.9+ type hints everywhere.
74+
- Prefer `Optional[T]` and `list[T]`/`dict[K, V]` style.
75+
- Return concrete types (`ApiKey`, `list[ApiKey]`, etc.) not `Any`.
76+
- Use `Annotated` for FastAPI params when needed.
77+
78+
### Naming
79+
80+
- Classes: `CamelCase` (e.g., `ApiKeyService`).
81+
- Functions/vars: `snake_case`.
82+
- Constants: `UPPER_SNAKE_CASE`.
83+
- Private helpers: prefix `_` (e.g., `_verify_entity`).
84+
- API key fields follow existing names (`key_id`, `key_secret`, `key_hash`).
85+
86+
### Dataclasses and models
87+
88+
- Use `@dataclass` for small data carriers (e.g., parsed key results).
89+
- Use Pydantic models for API request/response schemas.
90+
91+
### Error handling
92+
93+
- Domain exceptions live in `fastapi_api_key.domain.errors`.
94+
- Raise domain errors in services and repositories, translate to HTTP exceptions in API layer.
95+
- Preserve original errors with `raise ... from exc`.
96+
- Use specific exceptions (`KeyNotFound`, `InvalidKey`, `ConfigurationError`) rather than `ValueError` unless appropriate.
97+
- Validate inputs early; prefer guard clauses.
98+
99+
### Async and I/O
100+
101+
- Services and repositories are async; keep APIs async throughout.
102+
- Use `await` for repo calls and when composing service logic.
103+
- Avoid blocking I/O in async paths.
104+
105+
### Security-sensitive behavior
106+
107+
- Never log or return plaintext API keys after creation.
108+
- Enforce API key parsing/validation via `ParsedApiKey` and `_get_parts` patterns.
109+
- Use timing jitter on auth failures (`verify_key` behavior).
110+
- Treat secret pepper as external configuration; do not hardcode.
111+
112+
### API layer
113+
114+
- Use FastAPI dependency injection with `Depends`.
115+
- Map domain errors to `HTTPException` with correct status codes.
116+
- API responses use Pydantic models; keep output schemas stable.
117+
118+
### Tests
119+
120+
- Tests live in `tests/` with unit and integration subpackages.
121+
- Prefer clear arrange/act/assert structure.
122+
- Use fixtures from `tests/conftest.py` where available.
123+
124+
## Repository layout
125+
126+
- `src/fastapi_api_key/` core library
127+
- `tests/` unit/integration tests
128+
- `examples/` example applications (used in docs)
129+
130+
## Repo-specific notes
131+
132+
- `make lint` is the canonical lint entrypoint.
133+
- The project warns when the default pepper is used; tests expect that behavior.
134+
- Examples are used in docs; keep them runnable.
135+
136+
## Cursor and Copilot rules
137+
138+
- No `.cursor/rules/`, `.cursorrules`, or `.github/copilot-instructions.md` found in this repo.
139+
140+
## When editing
141+
142+
- Preserve public API behavior and exception types.
143+
- Keep docstrings consistent with existing style.
144+
- Match current error messages when possible (tests may assert them).
145+
- Avoid introducing extra dependencies without updating optional extras.

0 commit comments

Comments
 (0)