Skip to content

Commit 910443d

Browse files
committed
agent direction
1 parent ef208ef commit 910443d

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

.agents/AGENTS.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# AGENTS.md
2+
3+
This repository contains **acai_aws**, a happy-path-first toolkit for AWS Lambda handlers. This guide distills the canonical documentation so another AI agent can navigate the codebase without digging through the docs.
4+
5+
## Philosophy & Environment
6+
- Validate early, execute later. Every handler or event processor should assume inputs are clean because requirements and middleware already filtered the bad paths.
7+
- Python 3.8+ is the baseline. Install dependencies via `pipenv install --dev` and use `pipenv run` to invoke tooling so the virtualenv stays consistent.
8+
- Preferred workflow for any meaningful change: `pipenv run lint`, `pipenv run test`, `pipenv run coverage`, and—when request/response contracts change—`pipenv run generate` to refresh the OpenAPI spec.
9+
10+
## API Gateway Architecture
11+
### Router Responsibilities
12+
- The router owns request dispatch, validation, middleware orchestration, optional auth, and error handling. Core options include:
13+
- `base_path` (required) to match the API Gateway stage.
14+
- `handlers` (required) pointing to the directory that mirrors routes.
15+
- `schema` plus `auto_validate`/`validate_response` to wire OpenAPI checks.
16+
- `cors` (default `True`), `timeout`, `output_error`, `verbose_logging`, `cache_mode` (`all`, `static-only`, `dynamic-only`), and `cache_size` (default `128`).
17+
- Middleware hooks: `before_all`, `after_all`, `with_auth`, `on_error`, `on_timeout`.
18+
- Always call `router.auto_load()` so directory traversal happens once during cold start. Dynamic imports are cached per the `cache_mode`/`cache_size` combination.
19+
20+
### File-System Routing Rules
21+
- Directory names become path segments; `__init__.py` represents the index route for that segment.
22+
- Files prefixed with `_` declare a path parameter: `_user_id.py` responds to `/users/{user_id}`. Keep the placeholder name identical to the suffix (`user_id`) so `request.path_params` stays intuitive.
23+
- All HTTP verbs map to functions with lowercase names (`get`, `post`, etc.). Unsupported verbs simply don’t exist in the handler module.
24+
25+
### Middleware Order
26+
1. `before_all`
27+
2. Route-level `before` hook
28+
3. Authentication via `with_auth` when `auth_required=True`
29+
4. Handler function
30+
5. Route-level `after` hook
31+
6. `after_all`
32+
7. Error/timeout hooks only if an exception bubbles up
33+
34+
Maintain this order whenever touching router internals; tests expect it.
35+
36+
## Handler Requirements & Validation
37+
- Use `@requirements(...)` from `acai_aws.apigateway.requirements` to describe what makes a request valid. Supported keys include:
38+
- `required_headers`, `available_headers`
39+
- `required_query`, `available_query`
40+
- `required_route` for dynamic segments (e.g., `grower/{grower_id}`)
41+
- `required_body` and `required_response` referencing OpenAPI components or inline JSON Schema dicts
42+
- `auth_required` to trigger `with_auth`
43+
- `request_class` to swap in a custom request wrapper
44+
- `before`/`after` functions scoped to a single endpoint
45+
- `timeout` overrides (seconds, handler runtime only)
46+
- `summary`, `deprecated`, and arbitrary custom fields for OpenAPI generation or middleware hints
47+
- All validation errors should flow through `response.set_error` so clients receive consistent payloads.
48+
49+
## Request & Response Contracts
50+
- **Request** objects expose normalized HTTP metadata: `method`, `headers`, `query_params`, `path_params`, `route`, `path`, `cookies`, and `authorizer`. Body helpers auto-detect based on `Content-Type`:
51+
- `request.json`, `request.form`, `request.xml`, `request.graphql`, and `request.body` (auto-converts but falls back to raw data).
52+
- `request.raw` retains the unmodified payload.
53+
- `request.context` is the only mutable property—middleware can stash data here for later steps.
54+
- **Response** objects provide:
55+
- `response.code` (default 200) and `response.headers` (tuples merged into a dict).
56+
- `response.body` with automatic JSON serialization.
57+
- `response.raw` to bypass serialization when `after`/`after_all` need to mutate the payload.
58+
- `response.compress` to gzip the final body.
59+
- `response.set_error(key, message)` and `response.has_error` for structured error responses.
60+
61+
## OpenAPI Generation
62+
- Run `python -m acai_aws.apigateway generate-openapi --handlers=<glob> --base=<base_path> --output=<dir> --format=json,yml --delete` when handler requirements change. This command scans decorated functions, syncs paths/methods, and optionally prunes stale routes (`--delete`). Keep handler metadata descriptive so the generated doc is meaningful.
63+
64+
## Event Processors (Non-HTTP)
65+
Every AWS event module follows the same shape: import `requirements` from the service package, decorate a handler, and iterate over normalized records.
66+
67+
| Service | Highlights |
68+
|---------|------------|
69+
| DynamoDB | Converts Dynamo JSON to native dicts, can filter by operations (`INSERT`, `MODIFY`, `REMOVE` or aliases), validates record bodies, supports `data_class` injection. |
70+
| S3 | Optional `get_object` fetches the object body. `data_type` controls parsing (`json`, `csv`, or raw). Operations filters focus on create/update/delete events. |
71+
| SQS/SNS | Normalizes message bodies to dicts, surfaces message attributes, and supports JSON Schema validation plus data classes. |
72+
| Kinesis/Firehose/MSK/MQ | Batch processors built on `BaseRecordsEvent`; can apply schema validation and data classes per record, keeping streaming semantics intact. |
73+
| DocumentDB | Tailored for change streams with access to `operationType`, full documents, and metadata. |
74+
| Generic | Simplifies console/CLI-triggered events with body parsing and schema validation. |
75+
76+
Tips when editing event modules:
77+
- Keep constructor signatures consistent so `event.records` always returns iterable record objects.
78+
- Honor `operations` filters; when they’re misconfigured the event should no-op unless `raise_operation_error=True`.
79+
- Data classes receive a `record` instance. Keep their API stable to avoid breaking user code.
80+
81+
## Logger & Observability
82+
- `acai_aws.common.logger` logs structured JSON by default. Switching `LOG_FORMAT=INLINE` helps during local dev while `LOG_FORMAT=JSON` keeps CloudWatch-friendly output. `LOG_LEVEL` gates log emission (`INFO`, `DEBUG`, `WARN`, `ERROR`).
83+
- The `@log` decorator wraps any function, optionally gating logs with a boolean `condition`. Maintain argument pass-through so debugging remains straightforward.
84+
- Error traces should include the stack plus the high-level message; tests assert the JSON keys stay consistent (`level`, `time`, `error_trace`, `log`).
85+
86+
## Agent Checklist
87+
1. **Understand the route or event** you’re touching—confirm how the filesystem maps to the API or which event module processes the payload.
88+
2. **Update requirements first**, letting validation guardrails enforce behavior instead of branching in business logic.
89+
3. **Keep Request/Response contracts untouched** unless there’s a strong reason; these are relied on by every handler.
90+
4. **Mirror changes across services** when working inside shared abstractions like `BaseRecordsEvent`.
91+
5. **Write or update tests** under `tests/acai_aws/...` that mirror the source layout.
92+
6. **Run lint/tests/coverage/generate** (noted above) and capture any failures or skipped steps in your summary so humans can follow up.
93+
7. **Document surprises**: if AWS quirks require deviations from the standard flow, leave concise comments or docstrings explaining the reason.
94+
95+
Following this guide keeps future agents aligned with Acai’s happy-path principles while minimizing regressions across API Gateway handlers and event processors alike.

0 commit comments

Comments
 (0)