- Complete FastAPI proxy server with all Rentcast API endpoints - Intelligent caching with SQLite backend and Redis support - Rate limiting and usage tracking per API key - CLI administration tools for key and cache management - Comprehensive models with SQLAlchemy for persistence - Health checks and metrics endpoints - Production-ready configuration management - Extensive test coverage with pytest and fixtures - Rich CLI interface with click and rich libraries - Soft delete caching strategy for analytics - TTL-based cache expiration with endpoint-specific durations - CORS, compression, and security middleware - Structured logging with JSON format - Cost tracking and estimation for API usage - Background task support architecture - Docker deployment ready - Comprehensive documentation and setup instructions
517 lines
12 KiB
Markdown
517 lines
12 KiB
Markdown
# RentCache API
|
|
|
|
🏠 **Sophisticated FastAPI proxy server for the Rentcast API with intelligent caching, rate limiting, and cost management.**
|
|
|
|
[](https://www.python.org/downloads/)
|
|
[](https://fastapi.tiangolo.com)
|
|
[](https://www.sqlalchemy.org)
|
|
[](https://opensource.org/licenses/MIT)
|
|
|
|
## ✨ Features
|
|
|
|
### 🚀 **Performance & Caching**
|
|
- **Intelligent Multi-Level Caching**: SQLite for persistence + optional Redis for speed
|
|
- **Configurable TTL**: Different cache durations for different endpoint types
|
|
- **Stale-While-Revalidate**: Serve cached data during upstream failures
|
|
- **Cache Warming**: Pre-populate cache for better performance
|
|
- **Soft Deletion**: Mark entries invalid instead of deleting for analytics
|
|
|
|
### 💰 **Cost Management**
|
|
- **Usage Tracking**: Monitor API costs and savings from cache hits
|
|
- **Rate Limiting**: Prevent expensive API overuse with per-endpoint limits
|
|
- **Cost Estimation**: Track estimated costs for each endpoint type
|
|
- **Budget Alerts**: Monitor spending against configured limits
|
|
|
|
### 🔐 **Security & Access Control**
|
|
- **API Key Management**: Create, update, and revoke access keys
|
|
- **Role-Based Access**: Different limits per API key
|
|
- **Rate Limiting**: Global and per-endpoint request limits
|
|
- **CORS Support**: Configurable cross-origin resource sharing
|
|
- **Request Validation**: Comprehensive input validation with Pydantic
|
|
|
|
### 📊 **Analytics & Monitoring**
|
|
- **Real-time Metrics**: Cache hit ratios, response times, error rates
|
|
- **Usage Statistics**: Track usage patterns and popular endpoints
|
|
- **Health Checks**: Monitor system and dependency health
|
|
- **Structured Logging**: JSON logs for easy parsing and analysis
|
|
|
|
### 🔧 **Developer Experience**
|
|
- **OpenAPI Docs**: Auto-generated API documentation
|
|
- **CLI Administration**: Command-line tools for management
|
|
- **Type Safety**: Full type annotations with Pydantic models
|
|
- **Comprehensive Tests**: Unit and integration test coverage
|
|
|
|
## 🚀 Quick Start
|
|
|
|
### Installation
|
|
|
|
```bash
|
|
# Clone the repository
|
|
git clone <repository-url>
|
|
cd rentcache
|
|
|
|
# Install with uv (recommended)
|
|
uv sync
|
|
|
|
# Or with pip
|
|
pip install -e .
|
|
```
|
|
|
|
### Basic Usage
|
|
|
|
1. **Start the server**:
|
|
```bash
|
|
# Using CLI
|
|
rentcache server
|
|
|
|
# Or directly
|
|
uvicorn rentcache.server:app --reload
|
|
```
|
|
|
|
2. **Create an API key**:
|
|
```bash
|
|
rentcache create-key my_app YOUR_RENTCAST_API_KEY
|
|
```
|
|
|
|
3. **Make API calls**:
|
|
```bash
|
|
curl -H "Authorization: Bearer YOUR_RENTCAST_API_KEY" \
|
|
"http://localhost:8000/api/v1/properties?city=Austin&state=TX"
|
|
```
|
|
|
|
4. **Check metrics**:
|
|
```bash
|
|
curl "http://localhost:8000/metrics"
|
|
```
|
|
|
|
## 📖 API Documentation
|
|
|
|
### Core Endpoints
|
|
|
|
All Rentcast API endpoints are proxied with intelligent caching:
|
|
|
|
#### 🏘️ **Property Records**
|
|
```http
|
|
GET /api/v1/properties
|
|
GET /api/v1/properties/{property_id}
|
|
```
|
|
**Cache TTL**: 24 hours (expensive endpoints)
|
|
|
|
#### 💲 **Value & Rent Estimates**
|
|
```http
|
|
GET /api/v1/estimates/value
|
|
GET /api/v1/estimates/rent
|
|
POST /api/v1/estimates/value/bulk
|
|
POST /api/v1/estimates/rent/bulk
|
|
```
|
|
**Cache TTL**: 1 hour (dynamic pricing)
|
|
|
|
#### 🏠 **Listings**
|
|
```http
|
|
GET /api/v1/listings/sale
|
|
GET /api/v1/listings/rental
|
|
GET /api/v1/listings/{listing_id}
|
|
```
|
|
**Cache TTL**: 30 minutes (frequently updated)
|
|
|
|
#### 📈 **Market Data**
|
|
```http
|
|
GET /api/v1/markets/stats
|
|
GET /api/v1/comparables
|
|
```
|
|
**Cache TTL**: 2 hours (market statistics)
|
|
|
|
### Cache Control Parameters
|
|
|
|
All endpoints support these parameters:
|
|
|
|
- `force_refresh=true`: Bypass cache and fetch fresh data
|
|
- `ttl_override=3600`: Override default TTL (in seconds)
|
|
|
|
### Response Headers
|
|
|
|
Every response includes cache information:
|
|
|
|
```http
|
|
X-Cache-Hit: true|false
|
|
X-Response-Time-MS: 45.2
|
|
X-Estimated-Cost: 2.0 (only on cache misses)
|
|
```
|
|
|
|
## 🛠️ Administration
|
|
|
|
### CLI Commands
|
|
|
|
```bash
|
|
# Server management
|
|
rentcache server --host 0.0.0.0 --port 8000 --reload
|
|
|
|
# API key management
|
|
rentcache create-key <name> <rentcast_key> [options]
|
|
rentcache list-keys
|
|
rentcache update-key <name> [options]
|
|
rentcache delete-key <name>
|
|
|
|
# Cache management
|
|
rentcache clear-cache [--endpoint=properties] [--older-than=24]
|
|
|
|
# Monitoring
|
|
rentcache stats [--endpoint=properties] [--days=7]
|
|
rentcache health
|
|
```
|
|
|
|
### API Key Management
|
|
|
|
```bash
|
|
# Create key with custom limits
|
|
rentcache create-key production_app YOUR_KEY \
|
|
--daily-limit 5000 \
|
|
--monthly-limit 100000 \
|
|
--expires 2024-12-31
|
|
|
|
# Update existing key
|
|
rentcache update-key production_app --daily-limit 10000 --active
|
|
|
|
# List all keys with usage stats
|
|
rentcache list-keys
|
|
```
|
|
|
|
### Cache Management
|
|
|
|
```bash
|
|
# Clear specific endpoint cache
|
|
rentcache clear-cache --endpoint properties
|
|
|
|
# Clear old cache entries
|
|
rentcache clear-cache --older-than 24
|
|
|
|
# Clear all cache (careful!)
|
|
rentcache clear-cache
|
|
```
|
|
|
|
### HTTP Admin Endpoints
|
|
|
|
```http
|
|
# API key management
|
|
POST /admin/api-keys # Create API key
|
|
GET /admin/api-keys # List API keys
|
|
PUT /admin/api-keys/{id} # Update API key
|
|
DELETE /admin/api-keys/{id} # Delete API key
|
|
|
|
# Cache management
|
|
POST /admin/cache/clear # Clear cache entries
|
|
GET /admin/cache/stats # Cache statistics
|
|
|
|
# System monitoring
|
|
GET /health # Health check
|
|
GET /metrics # System metrics
|
|
```
|
|
|
|
## ⚙️ Configuration
|
|
|
|
### Environment Variables
|
|
|
|
```bash
|
|
# Server
|
|
HOST=0.0.0.0
|
|
PORT=8000
|
|
DEBUG=false
|
|
|
|
# Database
|
|
DATABASE_URL=sqlite+aiosqlite:///./rentcache.db
|
|
DATABASE_ECHO=false
|
|
|
|
# Redis (optional)
|
|
REDIS_URL=redis://localhost:6379
|
|
REDIS_ENABLED=false
|
|
|
|
# Rentcast API
|
|
RENTCAST_BASE_URL=https://api.rentcast.io
|
|
RENTCAST_TIMEOUT=30
|
|
RENTCAST_MAX_RETRIES=3
|
|
|
|
# Cache settings
|
|
DEFAULT_CACHE_TTL=3600
|
|
EXPENSIVE_ENDPOINTS_TTL=86400
|
|
ENABLE_STALE_WHILE_REVALIDATE=true
|
|
|
|
# Rate limiting
|
|
ENABLE_RATE_LIMITING=true
|
|
GLOBAL_RATE_LIMIT=1000/hour
|
|
PER_ENDPOINT_RATE_LIMIT=100/minute
|
|
|
|
# Security
|
|
ALLOWED_HOSTS=*
|
|
CORS_ORIGINS=*
|
|
|
|
# Logging
|
|
LOG_LEVEL=INFO
|
|
LOG_FORMAT=json
|
|
```
|
|
|
|
### Configuration File
|
|
|
|
Create a `.env` file in your project root:
|
|
|
|
```env
|
|
# Basic configuration
|
|
DEBUG=true
|
|
LOG_LEVEL=DEBUG
|
|
|
|
# Database
|
|
DATABASE_URL=sqlite+aiosqlite:///./rentcache.db
|
|
|
|
# Optional Redis for better performance
|
|
# REDIS_URL=redis://localhost:6379
|
|
# REDIS_ENABLED=true
|
|
|
|
# Custom cache settings
|
|
DEFAULT_CACHE_TTL=3600
|
|
EXPENSIVE_ENDPOINTS_TTL=86400
|
|
|
|
# Rate limiting
|
|
GLOBAL_RATE_LIMIT=2000/hour
|
|
PER_ENDPOINT_RATE_LIMIT=200/minute
|
|
```
|
|
|
|
## 🏗️ Architecture
|
|
|
|
### System Components
|
|
|
|
```mermaid
|
|
graph TD
|
|
A[Client Applications] --> B[FastAPI Server]
|
|
B --> C[Authentication Layer]
|
|
C --> D[Rate Limiting]
|
|
D --> E[Cache Manager]
|
|
E --> F{Cache Hit?}
|
|
F -->|Yes| G[Return Cached Data]
|
|
F -->|No| H[Rentcast API]
|
|
H --> I[Store in Cache]
|
|
I --> G
|
|
|
|
E --> J[(SQLite/PostgreSQL)]
|
|
E --> K[(Redis - Optional)]
|
|
|
|
B --> L[Usage Analytics]
|
|
L --> J
|
|
|
|
B --> M[Health Monitoring]
|
|
B --> N[Metrics Collection]
|
|
```
|
|
|
|
### Cache Strategy
|
|
|
|
1. **L1 Cache (Redis)**: Fast in-memory cache for frequently accessed data
|
|
2. **L2 Cache (SQLite/PostgreSQL)**: Persistent cache with analytics and soft deletion
|
|
3. **Cache Keys**: MD5 hash of endpoint + method + parameters
|
|
4. **TTL Management**: Different expiration times based on data volatility
|
|
5. **Stale-While-Revalidate**: Serve expired data during upstream failures
|
|
|
|
### Rate Limiting Strategy
|
|
|
|
1. **Global Limits**: Per API key across all endpoints
|
|
2. **Per-Endpoint Limits**: Specific limits for expensive operations
|
|
3. **Exponential Backoff**: Automatically slow down aggressive clients
|
|
4. **Usage Tracking**: Monitor and alert on approaching limits
|
|
|
|
## 🧪 Testing
|
|
|
|
### Run Tests
|
|
|
|
```bash
|
|
# Run all tests with coverage
|
|
uv run pytest
|
|
|
|
# Run specific test categories
|
|
uv run pytest -m unit
|
|
uv run pytest -m integration
|
|
uv run pytest -m api
|
|
|
|
# Run with coverage report
|
|
uv run pytest --cov=src/rentcache --cov-report=html
|
|
```
|
|
|
|
### Test Structure
|
|
|
|
```
|
|
tests/
|
|
├── conftest.py # Test configuration
|
|
├── test_models.py # Model tests
|
|
├── test_cache.py # Cache system tests
|
|
├── test_server.py # API endpoint tests
|
|
├── test_cli.py # CLI command tests
|
|
└── test_integration.py # End-to-end tests
|
|
```
|
|
|
|
## 📊 Monitoring & Analytics
|
|
|
|
### Key Metrics
|
|
|
|
- **Cache Hit Ratio**: Percentage of requests served from cache
|
|
- **Response Times**: Average response time by endpoint
|
|
- **Error Rates**: 4xx/5xx error percentages
|
|
- **Cost Tracking**: Estimated Rentcast API costs and savings
|
|
- **Usage Patterns**: Popular endpoints and request volumes
|
|
|
|
### Health Checks
|
|
|
|
```http
|
|
GET /health
|
|
```
|
|
|
|
Response includes:
|
|
- Database connectivity
|
|
- Cache backend status
|
|
- Active API keys count
|
|
- Recent error rates
|
|
- System uptime
|
|
|
|
### Metrics Endpoint
|
|
|
|
```http
|
|
GET /metrics
|
|
```
|
|
|
|
Provides detailed system metrics including:
|
|
- Request volumes and cache performance
|
|
- Per-endpoint statistics
|
|
- Cost analysis and savings
|
|
- System resource utilization
|
|
|
|
## 🚢 Deployment
|
|
|
|
### Docker
|
|
|
|
```dockerfile
|
|
FROM python:3.13-slim
|
|
|
|
WORKDIR /app
|
|
|
|
# Install uv
|
|
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
|
|
|
# Copy dependency files
|
|
COPY pyproject.toml uv.lock ./
|
|
|
|
# Install dependencies
|
|
RUN uv sync --frozen --no-cache --no-dev
|
|
|
|
# Copy application
|
|
COPY src/ ./src/
|
|
|
|
EXPOSE 8000
|
|
|
|
CMD ["uv", "run", "uvicorn", "rentcache.server:app", "--host", "0.0.0.0", "--port", "8000"]
|
|
```
|
|
|
|
### Docker Compose
|
|
|
|
```yaml
|
|
services:
|
|
rentcache:
|
|
build: .
|
|
ports:
|
|
- "8000:8000"
|
|
environment:
|
|
- DATABASE_URL=postgresql://user:pass@db:5432/rentcache
|
|
- REDIS_URL=redis://redis:6379
|
|
- REDIS_ENABLED=true
|
|
depends_on:
|
|
- db
|
|
- redis
|
|
volumes:
|
|
- ./data:/app/data
|
|
|
|
db:
|
|
image: postgres:15
|
|
environment:
|
|
POSTGRES_DB: rentcache
|
|
POSTGRES_USER: user
|
|
POSTGRES_PASSWORD: pass
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
volumes:
|
|
- redis_data:/data
|
|
|
|
volumes:
|
|
postgres_data:
|
|
redis_data:
|
|
```
|
|
|
|
### Production Deployment
|
|
|
|
1. **Use PostgreSQL**: Replace SQLite with PostgreSQL for production
|
|
2. **Enable Redis**: Use Redis for better cache performance
|
|
3. **Configure Logging**: Use structured JSON logging
|
|
4. **Set Up Monitoring**: Monitor metrics and health endpoints
|
|
5. **Use Reverse Proxy**: Nginx or Traefik for SSL termination
|
|
6. **Environment Variables**: Never commit secrets to code
|
|
|
|
## 📈 Performance Tips
|
|
|
|
### Optimization Strategies
|
|
|
|
1. **Cache Warming**: Pre-populate cache for popular endpoints
|
|
2. **Bulk Operations**: Use bulk endpoints when available
|
|
3. **Connection Pooling**: Configure appropriate database connection pools
|
|
4. **Response Compression**: Enable gzip compression for large responses
|
|
5. **CDN Integration**: Use CDN for static content and common API responses
|
|
|
|
### Monitoring Performance
|
|
|
|
```bash
|
|
# Check cache hit ratios
|
|
rentcache stats --days 7
|
|
|
|
# Monitor response times
|
|
curl -s http://localhost:8000/metrics | jq '.avg_response_time_ms'
|
|
|
|
# Check system health
|
|
rentcache health
|
|
```
|
|
|
|
## 🤝 Contributing
|
|
|
|
1. Fork the repository
|
|
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
3. Make your changes
|
|
4. Add tests for new functionality
|
|
5. Ensure all tests pass (`uv run pytest`)
|
|
6. Run code formatting (`uv run black src tests`)
|
|
7. Submit a pull request
|
|
|
|
### Development Setup
|
|
|
|
```bash
|
|
# Install development dependencies
|
|
uv sync --all-extras
|
|
|
|
# Install pre-commit hooks
|
|
pre-commit install
|
|
|
|
# Run tests
|
|
uv run pytest
|
|
|
|
# Format code
|
|
uv run black src tests
|
|
uv run ruff check src tests --fix
|
|
```
|
|
|
|
## 📜 License
|
|
|
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
|
|
## 🙏 Acknowledgments
|
|
|
|
- [Rentcast](https://rentcast.io/) for providing the real estate data API
|
|
- [FastAPI](https://fastapi.tiangolo.com/) for the excellent web framework
|
|
- [SQLAlchemy](https://www.sqlalchemy.org/) for powerful ORM capabilities
|
|
- [Pydantic](https://pydantic.dev/) for data validation and serialization
|
|
|
|
---
|
|
|
|
**Built with ❤️ for the real estate technology community** |