Skip to content

Commit 6b94cb8

Browse files
Add async example projects with comprehensive tests
Added three example projects demonstrating py-key-value usage: 1. chat_app: Simple chat message storage - PydanticAdapter for type-safe message storage - StatisticsWrapper for operation metrics - TTLClampWrapper for automatic message expiration - LoggingWrapper for debugging 2. trading_data: Trading data cache with compression - PydanticAdapter for type-safe price data - PassthroughCacheWrapper for multi-tier caching (memory + disk) - CompressionWrapper for efficient storage - RetryWrapper for transient failure handling - StatisticsWrapper for cache hit/miss metrics 3. web_scraper_cache: Web scraper cache with encryption - PydanticAdapter for type-safe scraped data - FernetEncryptionWrapper for encrypted storage - LimitSizeWrapper to prevent huge pages (5MB limit) - TTLClampWrapper for controlled cache duration - FallbackWrapper for resilience (memory fallback) Each example includes: - Comprehensive test suite using pytest-asyncio - Detailed README with usage examples and production guidance - pyproject.toml and requirements.txt for dependencies - Async-only implementation as requested Fixes #105 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: William Easton <strawgate@users.noreply.github.com>
1 parent e6eccbb commit 6b94cb8

19 files changed

+2261
-0
lines changed

examples/README.md

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# py-key-value Examples
2+
3+
This directory contains example projects demonstrating real-world use cases of
4+
py-key-value with the PydanticAdapter and various wrappers.
5+
6+
All examples are **async-only** and include comprehensive test suites.
7+
8+
## Available Examples
9+
10+
| Example | Description | Key Features |
11+
|---------|-------------|--------------|
12+
| [chat_app](chat_app/) | Simple chat message storage | PydanticAdapter, StatisticsWrapper, TTLClampWrapper, LoggingWrapper |
13+
| [trading_data](trading_data/) | Trading data cache with compression | PydanticAdapter, CompressionWrapper, PassthroughCacheWrapper, RetryWrapper |
14+
| [web_scraper_cache](web_scraper_cache/) | Web scraper cache with encryption | PydanticAdapter, FernetEncryptionWrapper, LimitSizeWrapper, FallbackWrapper |
15+
16+
## Quick Start
17+
18+
Each example is a self-contained project with its own dependencies and tests.
19+
20+
### Installation
21+
22+
```bash
23+
# Navigate to an example directory
24+
cd chat_app
25+
26+
# Install dependencies
27+
pip install -r requirements.txt
28+
29+
# Or using uv
30+
uv pip install -e .
31+
```
32+
33+
### Running Examples
34+
35+
```bash
36+
# Run the example application
37+
python chat_app.py # or trading_app.py, scraper.py
38+
39+
# Run tests
40+
pytest test_chat_app.py -v
41+
```
42+
43+
## Example Overview
44+
45+
### 1. Chat App
46+
47+
**Use Case**: Simple chat message storage with automatic expiration
48+
49+
**Demonstrates**:
50+
- Type-safe message storage with PydanticAdapter
51+
- Automatic message expiration using TTLClampWrapper
52+
- Operation statistics tracking with StatisticsWrapper
53+
- Debug logging with LoggingWrapper
54+
55+
**Complexity**: Simple (50-75 lines)
56+
57+
**Best for**: Learning the basics of py-key-value and wrapper composition
58+
59+
[View Example →](chat_app/)
60+
61+
---
62+
63+
### 2. Trading Data Cache
64+
65+
**Use Case**: Cache stock/crypto price data with compression and multi-tier
66+
caching
67+
68+
**Demonstrates**:
69+
- Multi-tier caching (memory + disk) with PassthroughCacheWrapper
70+
- Data compression with CompressionWrapper
71+
- Automatic retry with RetryWrapper
72+
- Cache hit/miss metrics with StatisticsWrapper
73+
74+
**Complexity**: Medium (100-125 lines)
75+
76+
**Best for**: Understanding advanced caching patterns and performance
77+
optimization
78+
79+
[View Example →](trading_data/)
80+
81+
---
82+
83+
### 3. Web Scraper Cache
84+
85+
**Use Case**: Cache scraped web pages with encryption and size limits
86+
87+
**Demonstrates**:
88+
- Encrypted storage with FernetEncryptionWrapper
89+
- Size limits with LimitSizeWrapper (reject pages >5MB)
90+
- TTL enforcement with TTLClampWrapper
91+
- Fallback resilience with FallbackWrapper
92+
93+
**Complexity**: Medium (100-125 lines)
94+
95+
**Best for**: Learning security patterns and resilience strategies
96+
97+
[View Example →](web_scraper_cache/)
98+
99+
## Common Patterns
100+
101+
### PydanticAdapter
102+
103+
All examples use PydanticAdapter for type-safe storage:
104+
105+
```python
106+
from pydantic import BaseModel
107+
from key_value.aio.adapters.pydantic import PydanticAdapter
108+
109+
class MyModel(BaseModel):
110+
field1: str
111+
field2: int
112+
113+
adapter = PydanticAdapter[MyModel](
114+
key_value=store,
115+
pydantic_model=MyModel,
116+
)
117+
118+
# Type-safe operations
119+
await adapter.put(collection="my_collection", key="key1", value=MyModel(...))
120+
model = await adapter.get(collection="my_collection", key="key1") # Returns MyModel | None
121+
```
122+
123+
### Wrapper Composition
124+
125+
Wrappers are composed inside-out, creating a processing pipeline:
126+
127+
```python
128+
# Wrappers are applied from inside-out
129+
wrapped_store = OuterWrapper(
130+
key_value=MiddleWrapper(
131+
key_value=InnerWrapper(
132+
key_value=BaseStore()
133+
)
134+
)
135+
)
136+
137+
# Request flow: Outer → Middle → Inner → Base
138+
```
139+
140+
### Collection-based Storage
141+
142+
Collections provide namespace isolation:
143+
144+
```python
145+
# Different collections, same key - no collision
146+
await adapter.put(collection="users", key="123", value=user)
147+
await adapter.put(collection="orders", key="123", value=order)
148+
```
149+
150+
## Testing
151+
152+
All examples include comprehensive test suites using pytest and pytest-asyncio.
153+
154+
### Running Tests
155+
156+
```bash
157+
# Run tests for a specific example
158+
cd chat_app
159+
pytest test_chat_app.py -v
160+
161+
# Run all tests
162+
pytest examples/*/test_*.py -v
163+
164+
# Run with coverage
165+
pytest examples/*/test_*.py --cov
166+
```
167+
168+
### Test Fixtures
169+
170+
Examples use pytest fixtures for setup and teardown:
171+
172+
```python
173+
@pytest.fixture
174+
async def cache(self, tmp_path) -> MyCache:
175+
"""Create a cache instance for testing."""
176+
cache = MyCache(cache_dir=str(tmp_path / "test_cache"))
177+
yield cache
178+
await cache.cleanup()
179+
```
180+
181+
## Requirements
182+
183+
- Python 3.10 or newer
184+
- py-key-value-aio
185+
- pydantic
186+
187+
Additional dependencies per example:
188+
- **trading_data**: None (uses built-in stores)
189+
- **web_scraper_cache**: cryptography (for encryption)
190+
191+
## Development
192+
193+
### Project Structure
194+
195+
Each example follows this structure:
196+
197+
```
198+
example_name/
199+
├── README.md # Detailed documentation
200+
├── pyproject.toml # Project metadata and dependencies
201+
├── requirements.txt # Pip-compatible dependencies
202+
├── __init__.py # Package initialization
203+
├── example_name.py # Main example code
204+
└── test_example.py # Comprehensive test suite
205+
```
206+
207+
### Adding New Examples
208+
209+
To add a new example:
210+
211+
1. Create a new directory under `examples/`
212+
2. Follow the structure above
213+
3. Include comprehensive README with:
214+
- Overview and use case
215+
- Features demonstrated
216+
- Installation and usage instructions
217+
- Key concepts explained
218+
- Next steps for production
219+
4. Write tests covering all functionality
220+
5. Update this README with your example
221+
222+
## Resources
223+
224+
- [Main Documentation](../README.md)
225+
- [Development Guide](../DEVELOPING.md)
226+
- [PydanticAdapter API](../key-value/key-value-aio/src/key_value/aio/adapters/pydantic/)
227+
- [Available Wrappers](../key-value/key-value-aio/src/key_value/aio/wrappers/)
228+
- [Available Stores](../key-value/key-value-aio/src/key_value/aio/stores/)
229+
230+
## Support
231+
232+
For issues, questions, or contributions:
233+
234+
- [GitHub Issues](https://github.com/strawgate/py-key-value/issues)
235+
- [GitHub Discussions](https://github.com/strawgate/py-key-value/discussions)
236+
237+
## License
238+
239+
All examples are licensed under Apache-2.0, same as the main project.

0 commit comments

Comments
 (0)