Skip to content

Commit 1ac0750

Browse files
authored
Merge branch 'main' into claude/issue-115-20251026-0511
2 parents ccabd02 + 70b307d commit 1ac0750

File tree

1 file changed

+232
-0
lines changed

1 file changed

+232
-0
lines changed

AGENTS.md

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# AGENTS.md
2+
3+
This file provides guidelines and context for AI coding agents working on the
4+
py-key-value project. For human developers, see [DEVELOPING.md](DEVELOPING.md).
5+
6+
## Development Workflow
7+
8+
### Required Pre-commit Checks
9+
10+
All three checks must pass before committing:
11+
12+
1. `make lint` - Runs Ruff formatting and linting (Python + Markdown)
13+
2. `make typecheck` - Runs Basedpyright type checking
14+
3. `make codegen` - Regenerates sync library from async
15+
16+
Or run all three together:
17+
18+
```bash
19+
make precommit
20+
```
21+
22+
### Testing Requirements
23+
24+
- All new features require tests in both async and sync packages
25+
- Run `make test` to execute all test suites
26+
- Run `make test-aio` for async package tests only
27+
- Run `make test-sync` for sync package tests only
28+
- Test coverage should be maintained
29+
30+
## Architecture
31+
32+
### Async-First Development
33+
34+
**This is a critical constraint**: Always modify the async package first.
35+
36+
- **Primary codebase**: `key-value/key-value-aio/` (async implementation)
37+
- **Generated codebase**: `key-value/key-value-sync/` (DO NOT EDIT DIRECTLY)
38+
- **Sync generation**: Run `make codegen` to generate sync from async
39+
40+
The sync library is automatically generated from the async library using
41+
`scripts/build_sync_library.py`. All changes must be made to the async
42+
package first, then regenerated into the sync package.
43+
44+
### Monorepo Structure
45+
46+
```text
47+
key-value/
48+
├── key-value-aio/ # Primary async library
49+
├── key-value-sync/ # Generated sync library (DO NOT EDIT)
50+
├── key-value-shared/ # Shared utilities and types
51+
└── key-value-shared-test/ # Shared test utilities
52+
scripts/
53+
├── build_sync_library.py # Codegen script for sync library
54+
└── bump_versions.py # Version management script
55+
```
56+
57+
## Code Style & Conventions
58+
59+
### Python
60+
61+
- **Formatter/Linter**: Ruff (configured in `pyproject.toml`)
62+
- **Line length**: 140 characters
63+
- **Type checker**: Basedpyright (strict mode)
64+
- **Runtime type checking**: Beartype (can be disabled via
65+
`PY_KEY_VALUE_DISABLE_BEARTYPE=true`)
66+
- **Python version**: 3.10+ (sync codegen targets 3.10)
67+
68+
### Markdown
69+
70+
- **Linter**: markdownlint (`.markdownlint.jsonc`)
71+
- **Line length**: 80 characters (excluding code blocks and tables)
72+
73+
## Common Pitfalls
74+
75+
### ManagedEntry Wrapper Objects
76+
77+
Raw values are **NEVER** stored directly in backends. The `ManagedEntry` wrapper
78+
(from `key_value/shared/utils/managed_entry.py`) wraps values with metadata
79+
like TTL and creation timestamp, typically serialized to/from JSON.
80+
81+
When implementing or debugging stores, remember that what's stored is not
82+
the raw value but a `ManagedEntry` containing:
83+
84+
- The actual value
85+
- Creation timestamp
86+
- TTL metadata
87+
88+
### Python Version Compatibility
89+
90+
The sync codegen targets Python 3.10. Running the codegen script with a
91+
different Python version may produce unexpected results or compatibility
92+
issues. Use Python 3.10 when running `make codegen`.
93+
94+
### Optional Backend Dependencies
95+
96+
Store implementations have optional dependencies. Install extras as needed:
97+
98+
```bash
99+
pip install py-key-value-aio[redis] # Redis support
100+
pip install py-key-value-aio[dynamodb] # DynamoDB support
101+
pip install py-key-value-aio[mongodb] # MongoDB support
102+
# etc. - see README.md for full list
103+
```
104+
105+
### Sync Package is Generated
106+
107+
**Never edit files in `key-value/key-value-sync/` directly**. Any changes
108+
will be overwritten when `make codegen` runs. Always make changes in the
109+
async package and regenerate.
110+
111+
## Make Commands Reference
112+
113+
| Command | Purpose |
114+
|---------|---------|
115+
| `make sync` | Install all dependencies |
116+
| `make install` | Alias for `make sync` |
117+
| `make lint` | Lint Python + Markdown |
118+
| `make typecheck` | Run Basedpyright type checking |
119+
| `make test` | Run all test suites |
120+
| `make test-aio` | Run async package tests |
121+
| `make test-sync` | Run sync package tests |
122+
| `make test-shared` | Run shared package tests |
123+
| `make codegen` | Generate sync library from async |
124+
| `make precommit` | Run lint + typecheck + codegen |
125+
| `make build` | Build all packages |
126+
127+
### Per-Project Commands
128+
129+
Add `PROJECT=<path>` to target a specific package:
130+
131+
```bash
132+
make lint PROJECT=key-value/key-value-aio
133+
make typecheck PROJECT=key-value/key-value-aio
134+
make test PROJECT=key-value/key-value-aio
135+
make build PROJECT=key-value/key-value-aio
136+
```
137+
138+
## Key Protocols and Interfaces
139+
140+
### AsyncKeyValue Protocol
141+
142+
The core async interface is `AsyncKeyValue` protocol from
143+
`key_value/aio/protocols/key_value.py`. All async stores implement this
144+
protocol, which defines:
145+
146+
- `get`, `get_many` - Retrieve values
147+
- `put`, `put_many` - Store values with optional TTL
148+
- `delete`, `delete_many` - Remove values
149+
- `ttl`, `ttl_many` - Get TTL information
150+
151+
### KeyValue Protocol (Sync)
152+
153+
The sync mirror is `KeyValue` from `key_value/sync/code_gen/protocols/key_value.py`,
154+
generated from the async protocol.
155+
156+
## Store Implementations
157+
158+
Stores are located in:
159+
160+
- Async: `key-value/key-value-aio/src/key_value/aio/stores/`
161+
- Sync: `key-value/key-value-sync/src/key_value/sync/code_gen/stores/`
162+
163+
Available backends include: DynamoDB, Elasticsearch, Memcached, Memory, Disk,
164+
MongoDB, Redis, RocksDB, Valkey, Vault, Windows Registry, Keyring, and more.
165+
166+
## Wrappers
167+
168+
Wrappers add functionality to stores and are located in:
169+
170+
- Async: `key-value/key-value-aio/src/key_value/aio/wrappers/`
171+
- Sync: `key-value/key-value-sync/src/key_value/sync/code_gen/wrappers/`
172+
173+
Wrappers include: Compression, Encryption, Logging, Statistics, Retry,
174+
Timeout, Cache, Prefix, TTL clamping, and more.
175+
176+
## Adapters
177+
178+
Adapters simplify store interactions but don't implement the protocol directly.
179+
Located in:
180+
181+
- Async: `key-value/key-value-aio/src/key_value/aio/adapters/`
182+
- Sync: `key-value/key-value-sync/src/key_value/sync/code_gen/adapters/`
183+
184+
Key adapters:
185+
186+
- `PydanticAdapter` - Type-safe Pydantic model storage
187+
- `RaiseOnMissingAdapter` - Raise exceptions for missing keys
188+
189+
## Development Environment
190+
191+
### Option 1: DevContainer (Recommended)
192+
193+
The repository includes a DevContainer configuration for consistent development
194+
environments. Open in VSCode and select "Reopen in Container" when prompted.
195+
196+
### Option 2: Local Development
197+
198+
Prerequisites:
199+
200+
- Python 3.10+
201+
- `uv` for dependency management
202+
- Node.js and npm for markdown linting
203+
204+
Setup:
205+
206+
```bash
207+
make sync
208+
```
209+
210+
## CI/CD
211+
212+
GitHub Actions workflows are in `.github/workflows/`:
213+
214+
- `test.yml` - Run tests across packages
215+
- `publish.yml` - Publish packages to PyPI
216+
- `claude-on-mention.yml` - Claude Code assistant (can make PRs)
217+
- `claude-on-open-label.yml` - Claude triage assistant (read-only analysis)
218+
219+
## Version Management
220+
221+
To bump versions across all packages:
222+
223+
```bash
224+
make bump-version VERSION=1.2.3 # Actual bump
225+
make bump-version-dry VERSION=1.2.3 # Dry run
226+
```
227+
228+
## Getting Help
229+
230+
- For human developer documentation, see [DEVELOPING.md](DEVELOPING.md)
231+
- For library usage documentation, see [README.md](README.md)
232+
- For package-specific information, see READMEs in each package directory

0 commit comments

Comments
 (0)