Compare commits

..

No commits in common. "main" and "v0.1.0" have entirely different histories.
main ... v0.1.0

9 changed files with 238 additions and 2160 deletions

View File

@ -1,68 +0,0 @@
# Multi-stage Dockerfile for RentCache
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS base
# Set working directory
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y \
curl \
&& rm -rf /var/lib/apt/lists/*
# Copy dependency files
COPY pyproject.toml uv.lock ./
# Install dependencies
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-install-project --no-dev
# Copy source code
COPY src/ ./src/
COPY README.md LICENSE ./
# Install the project
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-editable
# Development stage
FROM base AS development
# Install development dependencies
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-editable
# Create non-root user
RUN groupadd -r rentcache && useradd -r -g rentcache rentcache
RUN chown -R rentcache:rentcache /app
USER rentcache
# Create data directories
RUN mkdir -p /app/data /app/logs
EXPOSE 8000
# Development command with hot reload
CMD ["uv", "run", "rentcache", "server", "--host", "0.0.0.0", "--port", "8000", "--reload"]
# Production stage
FROM base AS production
# Create non-root user
RUN groupadd -r rentcache && useradd -r -g rentcache rentcache
RUN chown -R rentcache:rentcache /app
USER rentcache
# Create data directories
RUN mkdir -p /app/data /app/logs
# Compile bytecode for better performance
ENV UV_COMPILE_BYTECODE=1
EXPOSE 8000
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1
# Production command
CMD ["uv", "run", "rentcache", "server", "--host", "0.0.0.0", "--port", "8000"]

236
Makefile
View File

@ -1,118 +1,176 @@
# RentCache Makefile # RentCache Makefile
.PHONY: help dev prod build up down logs shell test clean
.PHONY: help install dev test lint format clean server docs
# Default target # Default target
help: ## Show this help message help:
@echo "RentCache - Intelligent Rentcast API caching proxy" @echo "RentCache Development Commands"
@echo "=============================="
@echo "" @echo ""
@echo "Available targets:" @echo "Setup:"
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) @echo " install Install dependencies"
@echo " dev Install dev dependencies"
@echo ""
@echo "Development:"
@echo " server Start development server"
@echo " test Run tests"
@echo " test-cov Run tests with coverage"
@echo " lint Run linting"
@echo " format Format code"
@echo ""
@echo "Database:"
@echo " db-init Initialize database"
@echo " db-reset Reset database"
@echo ""
@echo "Utilities:"
@echo " clean Clean temporary files"
@echo " docs Generate documentation"
@echo " check Run all checks (lint, test, format)"
# Development # Installation
dev: ## Start development environment with hot reload install:
@echo "🚀 Starting RentCache in development mode..." uv sync
@docker compose --profile redis up --build -d
@echo "✅ RentCache available at: https://rentcache.l.supported.systems"
@echo "📚 API docs: https://rentcache.l.supported.systems/docs"
@echo "❤️ Health: https://rentcache.l.supported.systems/health"
prod: ## Start production environment dev:
@echo "🏭 Starting RentCache in production mode..." uv sync --all-extras
@MODE=production DEBUG=false docker compose up --build -d
@echo "✅ RentCache running in production mode"
# Docker management # Development server
build: ## Build Docker images server:
@docker compose build uv run rentcache server --reload
up: ## Start services # Testing
@docker compose up -d test:
uv run pytest -v
down: ## Stop services test-cov:
@docker compose down uv run pytest --cov=src/rentcache --cov-report=html --cov-report=term
logs: ## View logs test-watch:
@docker compose logs -f rentcache uv run pytest-watch --runner "uv run pytest"
shell: ## Open shell in running container # Code quality
@docker compose exec rentcache /bin/bash lint:
uv run ruff check src tests
uv run mypy src
# Testing and development format:
test: ## Run tests uv run black src tests
@echo "🧪 Running tests..." uv run ruff check src tests --fix
@uv run pytest tests/ -v
test-cov: ## Run tests with coverage check: lint test
@echo "🧪 Running tests with coverage..." @echo "✅ All checks passed!"
@uv run pytest tests/ --cov=src/rentcache --cov-report=html
lint: ## Run linting # Database management
@echo "🔍 Running linting..." db-init:
@uv run ruff check src/ tests/ uv run python -c "import asyncio; from rentcache.models import Base; from sqlalchemy.ext.asyncio import create_async_engine; asyncio.run(create_async_engine('sqlite+aiosqlite:///./rentcache.db').begin().__aenter__().run_sync(Base.metadata.create_all))"
@uv run mypy src/
format: ## Format code db-reset:
@echo "✨ Formatting code..." rm -f rentcache.db
@uv run black src/ tests/ $(MAKE) db-init
@uv run ruff --fix src/ tests/
# Database and cache # CLI shortcuts
db-shell: ## Open database shell create-key:
@echo "🗄️ Opening database shell..." @read -p "Key name: " name; \
@docker compose exec rentcache uv run python -c "from rentcache.database import engine; import sqlite3; sqlite3.connect('data/rentcache.db').execute('.tables')" read -p "Rentcast API key: " key; \
uv run rentcache create-key "$$name" "$$key"
cache-clear: ## Clear all cache list-keys:
@echo "🧹 Clearing cache..." uv run rentcache list-keys
@docker compose exec rentcache uv run rentcache clear-cache --all
health: ## Check system health stats:
@echo "❤️ Checking health..." uv run rentcache stats
@docker compose exec rentcache uv run rentcache health
stats: ## Show usage statistics health:
@echo "📊 Usage statistics..." uv run rentcache health
@docker compose exec rentcache uv run rentcache stats
# Cleanup # Cleanup
clean: ## Clean up containers, volumes, and images clean:
@echo "🧹 Cleaning up..." find . -type d -name __pycache__ -delete
@docker compose down -v --remove-orphans find . -type f -name "*.pyc" -delete
@docker system prune -f find . -type d -name "*.egg-info" -exec rm -rf {} +
rm -rf .coverage
rm -rf htmlcov/
rm -rf reports/
rm -rf build/
rm -rf dist/
clean-all: clean ## Clean everything including images # Documentation
@docker compose down -v --rmi all --remove-orphans docs:
@docker system prune -af @echo "📚 API documentation available at:"
@echo " http://localhost:8000/docs (when server is running)"
@echo " http://localhost:8000/redoc (alternative docs)"
# API key management # Docker commands
create-key: ## Create API key (usage: make create-key NAME=myapp KEY=your_key) docker-build:
@docker compose exec rentcache uv run rentcache create-key $(NAME) $(KEY) --daily-limit 1000 docker build -t rentcache .
list-keys: ## List all API keys docker-run:
@docker compose exec rentcache uv run rentcache list-keys docker run -p 8000:8000 --env-file .env rentcache
# Install local development docker-dev:
install: ## Install for local development docker-compose up -d
@echo "📦 Installing dependencies..."
@uv sync
@echo "✅ Ready for development"
local-dev: install ## Run locally for development docker-logs:
@echo "🖥️ Starting local development server..." docker-compose logs -f rentcache
@uv run rentcache server --reload
# URL helpers docker-stop:
url: ## Show the service URL docker-compose down
@echo "🌐 RentCache URL: https://rentcache.l.supported.systems"
docs: ## Open API documentation # Production deployment helpers
@echo "📚 API Documentation: https://rentcache.l.supported.systems/docs" deploy-check:
@echo "🚀 Pre-deployment checklist:"
@echo " - [ ] Tests passing"
@echo " - [ ] Environment variables configured"
@echo " - [ ] Database migrations ready"
@echo " - [ ] SSL certificates configured"
@echo " - [ ] Monitoring setup"
@echo " - [ ] Backup strategy in place"
# Quick setup # Performance testing
setup: ## Complete setup (build, create network if needed, start) perf-test:
@echo "🚀 Setting up RentCache..." @echo "⚡ Running performance tests..."
@docker network create caddy 2>/dev/null || true uv run python -m pytest tests/ -m performance -v
@make build
@make dev benchmark:
@echo "" @echo "📊 Running benchmarks..."
@echo "🎉 RentCache is ready!" # Add your benchmark commands here
@make url
# Development environment
env-copy:
cp .env.example .env
@echo "📝 .env file created from example. Please edit with your settings."
setup: install env-copy db-init
@echo "🎉 Setup complete! Run 'make server' to start development."
# Release helpers
version:
@echo "Current version: $$(grep version pyproject.toml | head -1 | cut -d'"' -f2)"
bump-version:
@read -p "New version: " version; \
sed -i "s/version = .*/version = \"$$version\"/" pyproject.toml; \
echo "Version bumped to $$version"
build:
uv build
publish:
uv publish
# Monitoring and debugging
logs:
tail -f rentcache.log
monitor:
watch -n 1 "curl -s http://localhost:8000/metrics | jq '.'"
debug-server:
uv run python -m debugpy --listen 5678 --wait-for-client -m rentcache.server
# Quick shortcuts for common operations
s: server
t: test
f: format
l: lint
c: clean

View File

@ -1,235 +0,0 @@
# RentCache Project Summary
## 🎯 Project Overview
**RentCache** is an intelligent caching proxy for the Rentcast API that reduces API costs by 70-90% through smart caching, rate limiting, and usage management.
- **Repository**: https://git.supported.systems/MCP/rentcache
- **Production URL**: https://rentcache.l.supported.systems
- **API Documentation**: https://rentcache.l.supported.systems/docs
- **Version**: 0.1.0
## 🏗️ Architecture
### System Components
1. **FastAPI Proxy Server** - Handles all API requests
2. **Multi-Level Cache** - Redis (L1) + SQLite/PostgreSQL (L2)
3. **Rate Limiter** - Token bucket algorithm
4. **CLI Tools** - Administration and monitoring
5. **Docker Deployment** - Production-ready containers
6. **Caddy Reverse Proxy** - Automatic HTTPS
### Key Features
- ✅ **Complete Rentcast API Coverage** - All endpoints proxied
- ✅ **Intelligent Caching** - Soft delete, serve stale, TTL management
- ✅ **Cost Management** - 70-90% reduction in API costs
- ✅ **Rate Limiting** - Per-API key and endpoint limits
- ✅ **Usage Analytics** - Detailed metrics and reporting
- ✅ **Production Ready** - Docker, health checks, monitoring
- ✅ **Rich CLI** - Beautiful administration tools
## 📁 Project Structure
```
rentcache/
├── src/rentcache/
│ ├── __init__.py # Package initialization
│ ├── server.py # FastAPI application
│ ├── models.py # SQLAlchemy models
│ ├── cache.py # Caching logic
│ ├── cli.py # CLI commands
│ └── config.py # Configuration
├── docs/
│ ├── API.md # API reference
│ ├── ARCHITECTURE.md # System design
│ ├── DEPLOYMENT.md # Deployment guide
│ ├── INSTALLATION.md # Installation guide
│ ├── QUICKSTART.md # 5-minute setup
│ └── USAGE.md # Usage examples
├── tests/ # Test suite
├── docker-compose.yml # Docker orchestration
├── Dockerfile # Multi-stage build
├── Makefile # Development commands
├── pyproject.toml # Python package config
└── README.md # Main documentation
```
## 🚀 Quick Start
### 1. Clone and Setup
```bash
git clone https://git.supported.systems/MCP/rentcache.git
cd rentcache
make setup
```
### 2. Configure API Key
```bash
# Your Rentcast API key
API_KEY="47b3c2e7c40849f296bb7d5de9d526c4"
# Create key in system
make create-key NAME=production KEY=$API_KEY
```
### 3. Test the API
```bash
# Property search
curl -H "Authorization: Bearer $API_KEY" \
"https://rentcache.l.supported.systems/api/v1/properties?city=Austin&state=TX&limit=1"
# Health check
curl https://rentcache.l.supported.systems/health
# View metrics
curl https://rentcache.l.supported.systems/metrics
```
## 💰 Cost Savings Examples
| Endpoint | Direct Cost | With Cache | Savings |
|----------|------------|------------|---------|
| Property Records | $1.00 | $0.10 | 90% |
| Value Estimates | $2.00 | $0.20 | 90% |
| Rent Estimates | $1.50 | $0.15 | 90% |
| Market Statistics | $5.00 | $0.50 | 90% |
| **Monthly (10K requests)** | **$1,000** | **$100** | **$900** |
## 🛠️ Key Commands
### Docker Management
```bash
make dev # Start development mode
make prod # Start production mode
make logs # View logs
make down # Stop services
make shell # Container shell
```
### API Key Management
```bash
make create-key NAME=app KEY=key # Create key
make list-keys # List keys
docker compose exec rentcache uv run rentcache delete-key app
```
### Cache Management
```bash
make cache-clear # Clear all cache
make stats # View statistics
make health # Health check
```
### Development
```bash
make test # Run tests
make test-cov # Coverage report
make lint # Run linting
make format # Format code
```
## 📊 API Endpoints
### Rentcast Proxy Endpoints
- `GET /api/v1/properties` - Search properties
- `GET /api/v1/properties/{id}` - Get property by ID
- `GET /api/v1/estimates/value` - Property value estimates
- `GET /api/v1/estimates/rent` - Rent estimates
- `GET /api/v1/listings/sale` - Sale listings
- `GET /api/v1/listings/rental` - Rental listings
- `GET /api/v1/markets/stats` - Market statistics
- `GET /api/v1/comparables` - Comparable properties
### System Endpoints
- `GET /health` - Health check
- `GET /metrics` - Usage metrics
- `GET /docs` - OpenAPI documentation
- `GET /redoc` - ReDoc documentation
## 🔒 Security
- **API Key Authentication** - Bearer token required
- **HTTPS Only** - Caddy automatic TLS
- **Rate Limiting** - Prevent abuse
- **CORS Configuration** - Controlled access
- **Non-root Container** - Security hardening
- **Environment Variables** - Secure configuration
## 📈 Monitoring
### Health Check
```bash
curl https://rentcache.l.supported.systems/health
```
### Metrics
```bash
curl https://rentcache.l.supported.systems/metrics
```
### Logs
```bash
make logs
```
### CLI Stats
```bash
docker compose exec rentcache uv run rentcache stats
```
## 🏭 Production Deployment
### Prerequisites
- Docker and Docker Compose
- External Caddy network
- Domain pointing to server
### Deployment Steps
1. Clone repository
2. Configure `.env` with production settings
3. Run `make setup`
4. Create API keys
5. Monitor with `make logs`
### Environment Variables
```env
DOMAIN=rentcache.l.supported.systems
COMPOSE_PROJECT=rentcache
MODE=production
DEBUG=false
LOG_LEVEL=INFO
DATABASE_URL=postgresql://user:pass@db/rentcache
REDIS_URL=redis://redis:6379
```
## 📝 Documentation
- **[README.md](README.md)** - Project overview
- **[QUICKSTART.md](docs/QUICKSTART.md)** - 5-minute setup
- **[INSTALLATION.md](docs/INSTALLATION.md)** - Detailed installation
- **[USAGE.md](docs/USAGE.md)** - Usage examples
- **[API.md](docs/API.md)** - API reference
- **[ARCHITECTURE.md](docs/ARCHITECTURE.md)** - System design
- **[DEPLOYMENT.md](docs/DEPLOYMENT.md)** - Production deployment
## 🤝 Support
- **Repository**: https://git.supported.systems/MCP/rentcache
- **Issues**: https://git.supported.systems/MCP/rentcache/issues
- **Documentation**: https://git.supported.systems/MCP/rentcache#readme
## 📄 License
MIT License - See [LICENSE](LICENSE) file for details.
## 🎉 Summary
RentCache is a production-ready intelligent caching proxy that:
- **Saves 70-90%** on Rentcast API costs
- **Improves performance** with sub-100ms cached responses
- **Increases reliability** with stale-while-revalidate
- **Provides insights** with usage analytics
- **Scales horizontally** with Redis backend
- **Deploys easily** with Docker and Make commands
The system is now fully operational at https://rentcache.l.supported.systems and ready to dramatically reduce your Rentcast API costs while providing better performance and reliability!

151
README.md
View File

@ -2,9 +2,7 @@
🏠 **Reduce your Rentcast API costs by 70-90% with intelligent caching, rate limiting, and usage management.** 🏠 **Reduce your Rentcast API costs by 70-90% with intelligent caching, rate limiting, and usage management.**
**RentCache** is a production-ready FastAPI proxy server that sits between your applications and the Rentcast API, providing intelligent caching, cost optimization, and usage analytics. Perfect for real estate applications that need frequent property data access without breaking the budget. **RentCache** is a sophisticated FastAPI proxy server that sits between your applications and the Rentcast API, providing intelligent caching, cost optimization, and usage analytics. Perfect for real estate applications that need frequent property data access without breaking the budget.
**🌐 Live Demo**: [https://rentcache.l.supported.systems](https://rentcache.l.supported.systems)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/) [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![FastAPI](https://img.shields.io/badge/FastAPI-0.115+-00a393.svg)](https://fastapi.tiangolo.com) [![FastAPI](https://img.shields.io/badge/FastAPI-0.115+-00a393.svg)](https://fastapi.tiangolo.com)
@ -59,72 +57,49 @@
## 🚀 Quick Start ## 🚀 Quick Start
### Docker Deployment (Recommended) ### Installation
```bash ```bash
# Clone the repository # Clone the repository
git clone https://git.supported.systems/MCP/rentcache.git git clone https://git.supported.systems/MCP/rentcache.git
cd rentcache cd rentcache
# Start with Docker (includes reverse proxy) # Install with uv (recommended)
make setup
# Or manually:
docker network create caddy 2>/dev/null || true
docker compose up --build -d
```
**✅ Ready!** RentCache is now available at: **https://rentcache.l.supported.systems**
### Local Development
```bash
# Install dependencies
uv sync uv sync
# Start development server # Or with pip
make local-dev pip install -e .
# Or manually:
uv run rentcache server --reload
``` ```
### Basic Usage ### Basic Usage
1. **Create an API key**: 1. **Start the server**:
```bash ```bash
# Using Docker # Using CLI
make create-key NAME=my_app KEY=your_rentcast_api_key rentcache server
# Or locally # Or directly
uv run rentcache create-key my_app your_rentcast_api_key uvicorn rentcache.server:app --reload
``` ```
2. **Make API calls**: 2. **Create an API key**:
```bash ```bash
# Production endpoint rentcache create-key my_app YOUR_RENTCAST_API_KEY
curl -H "Authorization: Bearer your_rentcast_api_key" \ ```
"https://rentcache.l.supported.systems/api/v1/properties?city=Austin&state=TX"
# Local development 3. **Make API calls**:
curl -H "Authorization: Bearer your_rentcast_api_key" \ ```bash
curl -H "Authorization: Bearer YOUR_RENTCAST_API_KEY" \
"http://localhost:8000/api/v1/properties?city=Austin&state=TX" "http://localhost:8000/api/v1/properties?city=Austin&state=TX"
``` ```
3. **Monitor performance**: 4. **Check metrics**:
```bash ```bash
# View metrics curl "http://localhost:8000/metrics"
curl "https://rentcache.l.supported.systems/metrics"
# Health check
curl "https://rentcache.l.supported.systems/health"
``` ```
## 📚 Documentation ## 📚 Documentation
- **[Deployment Guide](docs/DEPLOYMENT.md)** - Docker & production deployment
- **[Architecture Overview](docs/ARCHITECTURE.md)** - System design & caching strategy
- **[Quick Start Guide](docs/QUICKSTART.md)** - 5-minute setup walkthrough
- **[Installation Guide](docs/INSTALLATION.md)** - Detailed setup instructions - **[Installation Guide](docs/INSTALLATION.md)** - Detailed setup instructions
- **[Usage Guide](docs/USAGE.md)** - Comprehensive usage examples - **[Usage Guide](docs/USAGE.md)** - Comprehensive usage examples
- **[API Reference](docs/API.md)** - Complete endpoint documentation - **[API Reference](docs/API.md)** - Complete endpoint documentation
@ -425,57 +400,77 @@ Provides detailed system metrics including:
- Cost analysis and savings - Cost analysis and savings
- System resource utilization - System resource utilization
## 🐳 Docker Deployment ## 🚢 Deployment
### Quick Start with Make ### Docker
```bash ```dockerfile
# Complete setup with reverse proxy FROM python:3.13-slim
make setup
# Development mode with hot reload WORKDIR /app
make dev
# Production mode # Install uv
make prod COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
# View logs # Copy dependency files
make logs COPY pyproject.toml uv.lock ./
# Health check # Install dependencies
make health RUN uv sync --frozen --no-cache --no-dev
# Management commands # Copy application
make create-key NAME=my_app KEY=your_rentcast_key COPY src/ ./src/
make list-keys
make stats EXPOSE 8000
CMD ["uv", "run", "uvicorn", "rentcache.server:app", "--host", "0.0.0.0", "--port", "8000"]
``` ```
### Manual Docker Compose ### Docker Compose
```bash ```yaml
# Create external network (if not exists) services:
docker network create caddy 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
# Development with hot reload db:
docker compose up --build -d image: postgres:15
environment:
POSTGRES_DB: rentcache
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volumes:
- postgres_data:/var/lib/postgresql/data
# Production mode redis:
MODE=production DEBUG=false docker compose up --build -d image: redis:7-alpine
volumes:
- redis_data:/data
# With Redis for better performance volumes:
docker compose --profile redis up --build -d postgres_data:
redis_data:
``` ```
### Production Features ### Production Deployment
- **🔄 Multi-stage Docker builds** for optimized images 1. **Use PostgreSQL**: Replace SQLite with PostgreSQL for production
- **🌐 Caddy reverse proxy** with automatic HTTPS 2. **Enable Redis**: Use Redis for better cache performance
- **📊 Health checks** and graceful shutdown 3. **Configure Logging**: Use structured JSON logging
- **🔒 Non-root user** for security 4. **Set Up Monitoring**: Monitor metrics and health endpoints
- **📦 Efficient caching** with multi-layer cache mounts 5. **Use Reverse Proxy**: Nginx or Traefik for SSL termination
- **🚀 Hot reload** in development mode 6. **Environment Variables**: Never commit secrets to code
- **📈 Production monitoring** with metrics and logging
## 📈 Performance Tips ## 📈 Performance Tips

View File

@ -1,53 +0,0 @@
services:
rentcache:
build:
context: .
dockerfile: Dockerfile
target: ${MODE:-production}
environment:
- HOST=0.0.0.0
- PORT=8000
- DATABASE_URL=sqlite+aiosqlite:///./data/rentcache.db
- DEBUG=${DEBUG:-false}
- LOG_LEVEL=${LOG_LEVEL:-INFO}
volumes:
- ./data:/app/data
- ./logs:/app/logs
# Development hot-reload
- ./src:/app/src:ro
networks:
- caddy
expose:
- "8000"
labels:
caddy: ${DOMAIN:-rentcache.l.supported.systems}
caddy.reverse_proxy: "{{upstreams}}"
caddy.header.X-Forwarded-Proto: https
caddy.header.X-Real-IP: "{remote_host}"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
restart: unless-stopped
# Optional Redis for caching
redis:
image: redis:7-alpine
networks:
- caddy
volumes:
- redis_data:/data
command: redis-server --appendonly yes
profiles:
- redis
restart: unless-stopped
networks:
caddy:
external: true
volumes:
redis_data:
driver: local

View File

@ -1,641 +0,0 @@
# Architecture Overview
This document provides a comprehensive overview of RentCache's system architecture, design decisions, and technical implementation details.
## 🏗️ System Architecture
### High-Level Architecture
```mermaid
graph TB
Client[Client Applications] --> LB[Load Balancer/Caddy]
LB --> App[RentCache FastAPI]
App --> Auth[Authentication Layer]
Auth --> Rate[Rate Limiting]
Rate --> Cache[Cache Manager]
Cache --> L1[L1 Cache<br/>Redis]
Cache --> L2[L2 Cache<br/>SQLite/PostgreSQL]
Cache --> API[Rentcast API]
App --> Analytics[Usage Analytics]
Analytics --> DB[(Database)]
App --> Monitor[Health Monitoring]
App --> Metrics[Metrics Collection]
subgraph "Data Layer"
L1
L2
DB
end
subgraph "External Services"
API
end
```
### Component Responsibilities
#### **FastAPI Application Server**
- **Primary Role**: HTTP request handling and API routing
- **Key Features**:
- Async/await architecture for high concurrency
- OpenAPI documentation generation
- Request/response validation with Pydantic
- Middleware stack for cross-cutting concerns
#### **Authentication & Authorization**
- **Method**: Bearer token authentication using SHA-256 hashed API keys
- **Storage**: Secure key storage with expiration and usage limits
- **Features**: Per-key rate limiting and usage tracking
#### **Multi-Level Caching System**
- **L1 Cache (Redis)**: In-memory cache for ultra-fast access
- **L2 Cache (Database)**: Persistent cache with analytics
- **Strategy**: Write-through with intelligent TTL management
#### **Rate Limiting Engine**
- **Implementation**: Token bucket algorithm with sliding windows
- **Granularity**: Global and per-endpoint limits
- **Backend**: Redis-based distributed rate limiting
#### **Usage Analytics**
- **Tracking**: Request patterns, costs, and performance metrics
- **Storage**: Time-series data in relational database
- **Reporting**: Real-time dashboards and historical analysis
## 🔄 Request Flow Architecture
### 1. Request Processing Pipeline
```mermaid
sequenceDiagram
participant C as Client
participant A as Auth Layer
participant R as Rate Limiter
participant CM as Cache Manager
participant RC as Redis Cache
participant DB as Database
participant RA as Rentcast API
C->>A: HTTP Request + API Key
A->>A: Validate & Hash Key
alt Valid API Key
A->>R: Check Rate Limits
alt Within Limits
R->>CM: Cache Lookup
CM->>RC: Check L1 Cache
alt Cache Hit (L1)
RC-->>CM: Return Cached Data
CM-->>C: Response + Cache Headers
else Cache Miss (L1)
CM->>DB: Check L2 Cache
alt Cache Hit (L2)
DB-->>CM: Return Cached Data
CM->>RC: Populate L1
CM-->>C: Response + Cache Headers
else Cache Miss (L2)
CM->>RA: Upstream API Call
RA-->>CM: API Response
CM->>DB: Store in L2
CM->>RC: Store in L1
CM-->>C: Response + Cost Headers
end
end
else Rate Limited
R-->>C: 429 Rate Limit Exceeded
end
else Invalid API Key
A-->>C: 401 Unauthorized
end
```
### 2. Cache Key Generation
**Cache Key Strategy**: MD5 hash of request signature
```python
cache_key = md5(json.dumps({
"endpoint": "properties",
"method": "GET",
"path_params": {"property_id": "123"},
"query_params": {"city": "Austin", "state": "TX"},
"body": {}
}, sort_keys=True)).hexdigest()
```
**Benefits**:
- Deterministic cache keys
- Collision resistance
- Parameter order independence
- Efficient storage and lookup
## 💾 Caching Strategy
### Multi-Level Cache Architecture
#### **Level 1: Redis Cache (Hot Data)**
- **Purpose**: Ultra-fast access to frequently requested data
- **TTL**: 30 minutes to 2 hours
- **Eviction**: LRU (Least Recently Used)
- **Size**: Memory-limited, optimized for speed
```python
# L1 Cache Configuration
REDIS_CONFIG = {
"maxmemory": "512mb",
"maxmemory_policy": "allkeys-lru",
"save": ["900 1", "300 10", "60 10000"], # Persistence snapshots
"appendonly": True, # AOF for durability
"appendfsync": "everysec"
}
```
#### **Level 2: Database Cache (Persistent)**
- **Purpose**: Persistent cache with analytics and soft deletion
- **TTL**: 1 hour to 48 hours based on endpoint volatility
- **Storage**: Full response data + metadata
- **Features**: Soft deletion, usage tracking, cost analytics
```sql
-- Cache Entry Schema
CREATE TABLE cache_entries (
id SERIAL PRIMARY KEY,
cache_key VARCHAR(64) UNIQUE NOT NULL,
endpoint VARCHAR(50) NOT NULL,
method VARCHAR(10) NOT NULL,
params_hash VARCHAR(64) NOT NULL,
response_data JSONB NOT NULL,
status_code INTEGER NOT NULL,
estimated_cost DECIMAL(10,2) DEFAULT 0.0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
is_valid BOOLEAN DEFAULT TRUE,
hit_count INTEGER DEFAULT 0,
last_accessed TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
```
### Cache TTL Strategy
| Endpoint Type | Data Volatility | Default TTL | Rationale |
|---------------|----------------|-------------|-----------|
| **Property Records** | Very Low | 24 hours | Property characteristics rarely change |
| **Value Estimates** | Medium | 1 hour | Market fluctuations affect valuations |
| **Rent Estimates** | Medium | 1 hour | Rental markets change regularly |
| **Listings** | High | 30 minutes | Active market with frequent updates |
| **Market Statistics** | Low | 2 hours | Aggregated data changes slowly |
| **Comparables** | Medium | 1 hour | Market-dependent analysis |
### Stale-While-Revalidate Pattern
```python
async def get_with_stale_while_revalidate(cache_key: str, ttl: int):
"""
Serve stale data immediately while refreshing in background
"""
cached_data = await cache.get(cache_key)
if cached_data:
if not cached_data.is_expired:
return cached_data # Fresh data
else:
# Serve stale data, trigger background refresh
asyncio.create_task(refresh_cache_entry(cache_key))
return cached_data # Stale but usable
# Cache miss - fetch fresh data
return await fetch_and_cache(cache_key, ttl)
```
**Benefits**:
- Improved user experience (no waiting for fresh data)
- Reduced upstream API calls during traffic spikes
- Graceful handling of upstream service issues
## 🚦 Rate Limiting Implementation
### Token Bucket Algorithm
```python
class TokenBucket:
def __init__(self, capacity: int, refill_rate: float):
self.capacity = capacity
self.tokens = capacity
self.refill_rate = refill_rate # tokens per second
self.last_refill = time.time()
async def consume(self, tokens: int = 1) -> bool:
await self._refill()
if self.tokens >= tokens:
self.tokens -= tokens
return True
return False
async def _refill(self):
now = time.time()
tokens_to_add = (now - self.last_refill) * self.refill_rate
self.tokens = min(self.capacity, self.tokens + tokens_to_add)
self.last_refill = now
```
### Multi-Tier Rate Limiting
#### **Global Limits**
- **Purpose**: Prevent overall API abuse
- **Scope**: Per API key across all endpoints
- **Implementation**: Redis-based distributed counters
#### **Per-Endpoint Limits**
- **Purpose**: Protect expensive operations
- **Scope**: Specific endpoints (e.g., value estimates)
- **Implementation**: Endpoint-specific token buckets
#### **Dynamic Rate Limiting**
```python
RATE_LIMITS = {
"properties": "60/minute", # Standard property searches
"value_estimate": "30/minute", # Expensive AI/ML operations
"rent_estimate": "30/minute", # Expensive AI/ML operations
"market_stats": "20/minute", # Computationally intensive
"listings_sale": "100/minute", # Less expensive, higher volume
"listings_rental": "100/minute", # Less expensive, higher volume
"comparables": "40/minute" # Moderate complexity
}
```
## 📊 Database Schema Design
### Core Tables
#### **API Keys Management**
```sql
CREATE TABLE api_keys (
id SERIAL PRIMARY KEY,
key_name VARCHAR(100) UNIQUE NOT NULL,
key_hash VARCHAR(64) UNIQUE NOT NULL, -- SHA-256 hash
is_active BOOLEAN DEFAULT TRUE,
daily_limit INTEGER DEFAULT 1000,
monthly_limit INTEGER DEFAULT 30000,
daily_usage INTEGER DEFAULT 0,
monthly_usage INTEGER DEFAULT 0,
last_daily_reset TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
last_monthly_reset TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
expires_at TIMESTAMP WITH TIME ZONE,
last_used TIMESTAMP WITH TIME ZONE
);
```
#### **Usage Analytics**
```sql
CREATE TABLE usage_stats (
id SERIAL PRIMARY KEY,
api_key_id INTEGER REFERENCES api_keys(id),
endpoint VARCHAR(50) NOT NULL,
method VARCHAR(10) NOT NULL,
status_code INTEGER NOT NULL,
response_time_ms DECIMAL(10,2) NOT NULL,
cache_hit BOOLEAN NOT NULL,
estimated_cost DECIMAL(10,2) DEFAULT 0.0,
user_agent TEXT,
ip_address INET,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
```
#### **Rate Limiting State**
```sql
CREATE TABLE rate_limits (
id SERIAL PRIMARY KEY,
api_key_id INTEGER REFERENCES api_keys(id),
endpoint VARCHAR(50) NOT NULL,
current_tokens INTEGER DEFAULT 0,
last_refill TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(api_key_id, endpoint)
);
```
### Indexing Strategy
```sql
-- Performance indexes
CREATE INDEX idx_cache_entries_key ON cache_entries(cache_key);
CREATE INDEX idx_cache_entries_endpoint_expires ON cache_entries(endpoint, expires_at);
CREATE INDEX idx_cache_entries_created_at ON cache_entries(created_at);
CREATE INDEX idx_usage_stats_api_key_created ON usage_stats(api_key_id, created_at);
CREATE INDEX idx_usage_stats_endpoint_created ON usage_stats(endpoint, created_at);
CREATE INDEX idx_usage_stats_cache_hit ON usage_stats(cache_hit, created_at);
CREATE INDEX idx_api_keys_hash ON api_keys(key_hash);
CREATE INDEX idx_api_keys_active ON api_keys(is_active);
```
## 🔒 Security Architecture
### Authentication Flow
```mermaid
graph LR
Client --> |Bearer Token| Auth[Auth Middleware]
Auth --> Hash[SHA-256 Hash]
Hash --> DB[(Database Lookup)]
DB --> Validate[Validate Expiry & Status]
Validate --> |Valid| Allow[Allow Request]
Validate --> |Invalid| Deny[401 Unauthorized]
```
### Security Measures
#### **API Key Protection**
- **Storage**: Only SHA-256 hashes stored, never plaintext
- **Transmission**: HTTPS only, bearer token format
- **Rotation**: Configurable expiration dates
- **Revocation**: Instant deactivation capability
#### **Network Security**
- **HTTPS Enforcement**: Automatic SSL with Caddy
- **CORS Configuration**: Configurable origin restrictions
- **Rate Limiting**: DDoS and abuse protection
- **Request Validation**: Comprehensive input sanitization
#### **Container Security**
- **Non-root User**: Containers run as unprivileged user
- **Minimal Images**: Alpine Linux base images
- **Secret Management**: Environment variable injection
- **Network Isolation**: Docker network segregation
## 📈 Performance Optimizations
### Application Level
#### **Async Architecture**
```python
# Concurrent request handling
async def handle_multiple_requests():
tasks = [
process_request(req1),
process_request(req2),
process_request(req3)
]
results = await asyncio.gather(*tasks)
return results
```
#### **Connection Pooling**
```python
# HTTP client configuration
http_client = httpx.AsyncClient(
timeout=30.0,
limits=httpx.Limits(
max_connections=100,
max_keepalive_connections=20
)
)
# Database connection pooling
engine = create_async_engine(
DATABASE_URL,
pool_size=20,
max_overflow=30,
pool_pre_ping=True,
pool_recycle=3600
)
```
#### **Response Optimization**
- **GZip Compression**: Automatic response compression
- **JSON Streaming**: Large response streaming
- **Conditional Requests**: ETag and If-Modified-Since support
### Database Level
#### **Query Optimization**
```sql
-- Efficient cache lookup
EXPLAIN ANALYZE
SELECT response_data, expires_at, is_valid
FROM cache_entries
WHERE cache_key = $1
AND expires_at > NOW()
AND is_valid = TRUE;
```
#### **Connection Management**
- **Prepared Statements**: Reduced parsing overhead
- **Connection Pooling**: Shared connection resources
- **Read Replicas**: Separate analytics queries
### Caching Level
#### **Cache Warming Strategies**
```python
async def warm_cache():
"""Pre-populate cache with common requests"""
common_requests = [
{"endpoint": "properties", "city": "Austin", "state": "TX"},
{"endpoint": "properties", "city": "Dallas", "state": "TX"},
{"endpoint": "market_stats", "zipCode": "78701"}
]
for request in common_requests:
await fetch_and_cache(request)
```
#### **Memory Management**
- **TTL Optimization**: Balanced freshness vs. efficiency
- **Compression**: Response data compression
- **Eviction Policies**: Smart cache replacement
## 📊 Monitoring and Observability
### Metrics Collection
#### **Business Metrics**
- Cache hit ratios by endpoint
- API cost savings
- Request volume trends
- Error rates and patterns
#### **System Metrics**
- Response time percentiles
- Database query performance
- Memory and CPU utilization
- Connection pool statistics
#### **Custom Metrics**
```python
# Prometheus-style metrics
cache_hit_ratio = Gauge('cache_hit_ratio', 'Cache hit ratio by endpoint', ['endpoint'])
api_request_duration = Histogram('api_request_duration_seconds', 'API request duration')
upstream_calls = Counter('upstream_api_calls_total', 'Total upstream API calls')
```
### Health Checks
#### **Application Health**
```python
async def health_check():
checks = {
"database": await check_database_connection(),
"cache": await check_cache_availability(),
"upstream": await check_upstream_api(),
"disk_space": await check_disk_usage()
}
overall_status = "healthy" if all(checks.values()) else "unhealthy"
return {"status": overall_status, "checks": checks}
```
#### **Dependency Health**
- Database connectivity and performance
- Redis availability and memory usage
- Upstream API response times
- Disk space and system resources
## 🔧 Configuration Management
### Environment-Based Configuration
```python
class Settings(BaseSettings):
# Server
host: str = "0.0.0.0"
port: int = 8000
debug: bool = False
# Database
database_url: str
database_echo: bool = False
# Cache
redis_url: Optional[str] = None
redis_enabled: bool = False
default_cache_ttl: int = 3600
# Rate Limiting
enable_rate_limiting: bool = True
global_rate_limit: str = "1000/hour"
class Config:
env_file = ".env"
case_sensitive = False
```
### Feature Flags
```python
class FeatureFlags:
ENABLE_REDIS_CACHE = os.getenv("ENABLE_REDIS_CACHE", "true").lower() == "true"
ENABLE_ANALYTICS = os.getenv("ENABLE_ANALYTICS", "true").lower() == "true"
ENABLE_CACHE_WARMING = os.getenv("ENABLE_CACHE_WARMING", "false").lower() == "true"
STRICT_RATE_LIMITING = os.getenv("STRICT_RATE_LIMITING", "false").lower() == "true"
```
## 🚀 Scalability Considerations
### Horizontal Scaling
#### **Stateless Design**
- No server-side sessions
- Shared state in Redis/Database
- Load balancer friendly
#### **Container Orchestration**
```yaml
# Kubernetes deployment example
apiVersion: apps/v1
kind: Deployment
metadata:
name: rentcache
spec:
replicas: 3
selector:
matchLabels:
app: rentcache
template:
spec:
containers:
- name: rentcache
image: rentcache:latest
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
```
### Vertical Scaling
#### **Resource Optimization**
- Memory: Cache size tuning
- CPU: Async I/O optimization
- Storage: Database indexing and partitioning
- Network: Connection pooling and keep-alive
### Data Partitioning
#### **Database Sharding**
```sql
-- Partition by date for analytics
CREATE TABLE usage_stats (
-- columns
) PARTITION BY RANGE (created_at);
CREATE TABLE usage_stats_2024_01 PARTITION OF usage_stats
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
```
#### **Cache Distribution**
- Redis Cluster for distributed caching
- Consistent hashing for cache key distribution
- Regional cache replication
## 🔄 Disaster Recovery
### Backup Strategy
#### **Database Backups**
```bash
# Automated daily backups
pg_dump rentcache | gzip > backup-$(date +%Y%m%d).sql.gz
# Point-in-time recovery
pg_basebackup -D /backup/base -Ft -z -P
```
#### **Configuration Backups**
- Environment variables
- Docker Compose files
- SSL certificates
- Application configuration
### Recovery Procedures
#### **Database Recovery**
```bash
# Restore from backup
gunzip -c backup-20240115.sql.gz | psql rentcache
# Point-in-time recovery
pg_ctl stop -D /var/lib/postgresql/data
rm -rf /var/lib/postgresql/data/*
pg_basebackup -D /var/lib/postgresql/data -R
```
#### **Cache Recovery**
- Redis persistence (RDB + AOF)
- Cache warming from database
- Graceful degradation to upstream API
---
This architecture is designed for high availability, performance, and cost optimization while maintaining security and operational simplicity. For implementation details, see the [Deployment Guide](DEPLOYMENT.md) and [Usage Guide](USAGE.md).

View File

@ -1,583 +0,0 @@
# Deployment Guide
This guide covers deploying RentCache in production using Docker, with Caddy reverse proxy, and comprehensive monitoring.
## 🐳 Docker Deployment
### Prerequisites
- **Docker Engine**: 20.10+ with Compose V2
- **External Caddy Network**: For reverse proxy integration
- **Domain**: Configured with DNS pointing to your server
- **SSL Certificate**: Automatic with Caddy (Let's Encrypt)
### Quick Production Deployment
```bash
# Clone repository
git clone https://git.supported.systems/MCP/rentcache.git
cd rentcache
# Set up environment
cp .env.example .env
nano .env # Configure your settings
# Deploy with reverse proxy
make setup
```
This command:
1. Creates the external Caddy network if needed
2. Builds the Docker images
3. Starts services with reverse proxy
4. Makes RentCache available at your domain
### Environment Configuration
#### Production .env File
```env
# Domain Configuration
DOMAIN=your-domain.com
COMPOSE_PROJECT=rentcache-prod
# Mode Configuration
MODE=production
DEBUG=false
LOG_LEVEL=INFO
# Server Configuration
HOST=0.0.0.0
PORT=8000
# Database Configuration (Production)
DATABASE_URL=postgresql://rentcache:secure_password@postgres:5432/rentcache
DATABASE_ECHO=false
# Redis Configuration (Recommended for Production)
REDIS_URL=redis://redis:6379
REDIS_ENABLED=true
# Cache Settings (Optimized for Production)
DEFAULT_CACHE_TTL=7200
EXPENSIVE_ENDPOINTS_TTL=172800
ENABLE_STALE_WHILE_REVALIDATE=true
# Rate Limiting (Production Limits)
ENABLE_RATE_LIMITING=true
GLOBAL_RATE_LIMIT=2000/hour
PER_ENDPOINT_RATE_LIMIT=100/minute
# Security (Restrict Access)
ALLOWED_HOSTS=your-domain.com,api.your-domain.com
CORS_ORIGINS=https://your-domain.com,https://app.your-domain.com
# Monitoring
ENABLE_METRICS=true
LOG_FORMAT=json
```
### Docker Compose Production Setup
The included `docker-compose.yml` supports multiple deployment scenarios:
#### Basic Production Deployment
```bash
# Production mode with PostgreSQL
MODE=production docker compose up -d rentcache postgres
```
#### High-Performance Deployment with Redis
```bash
# Production with Redis caching
MODE=production docker compose --profile redis up -d
```
#### Development with Hot Reload
```bash
# Development mode with file watching
make dev
```
## 🌐 Reverse Proxy with Caddy
### Caddy Docker Proxy Integration
RentCache is designed to work with [caddy-docker-proxy](https://github.com/lucaslorentz/caddy-docker-proxy) for automatic HTTPS and load balancing.
#### Setup External Caddy Network
```bash
# Create the external network (if not exists)
docker network create caddy
# Verify network exists
docker network ls | grep caddy
```
#### Caddy Labels Configuration
The `docker-compose.yml` includes automatic Caddy configuration:
```yaml
services:
rentcache:
# ... other config
networks:
- caddy
labels:
caddy: ${DOMAIN:-rentcache.l.supported.systems}
caddy.reverse_proxy: "{{upstreams}}"
caddy.header.X-Forwarded-Proto: https
caddy.header.X-Real-IP: "{remote_host}"
```
#### Manual Caddy Configuration
If using standalone Caddy, create a `Caddyfile`:
```caddyfile
your-domain.com {
reverse_proxy rentcache:8000
# Security headers
header {
X-Content-Type-Options nosniff
X-Frame-Options DENY
X-XSS-Protection "1; mode=block"
Strict-Transport-Security "max-age=31536000;"
}
# Health check endpoint
handle /health {
reverse_proxy rentcache:8000
}
# API endpoints
handle /api/* {
reverse_proxy rentcache:8000
}
# Admin endpoints (restrict access)
handle /admin/* {
reverse_proxy rentcache:8000
# Add basic auth or IP restrictions here
}
}
```
## 🗄️ Database Configuration
### PostgreSQL Production Setup
#### Using Docker Compose
```yaml
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: rentcache
POSTGRES_USER: rentcache
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_INITDB_ARGS: "--auth-host=scram-sha-256"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
networks:
- caddy
restart: unless-stopped
command: >
postgres
-c shared_preload_libraries=pg_stat_statements
-c max_connections=200
-c shared_buffers=256MB
-c effective_cache_size=1GB
-c maintenance_work_mem=64MB
-c checkpoint_completion_target=0.9
-c wal_buffers=16MB
-c default_statistics_target=100
volumes:
postgres_data:
driver: local
```
#### External PostgreSQL
For external PostgreSQL (AWS RDS, Google Cloud SQL, etc.):
```env
DATABASE_URL=postgresql://username:password@host:5432/database?sslmode=require
DATABASE_ECHO=false
```
### Redis Configuration
#### Docker Redis
```yaml
services:
redis:
image: redis:7-alpine
command: >
redis-server
--appendonly yes
--appendfsync everysec
--save 900 1
--save 300 10
--save 60 10000
--maxmemory 512mb
--maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
networks:
- caddy
restart: unless-stopped
profiles:
- redis
volumes:
redis_data:
driver: local
```
#### External Redis
```env
REDIS_URL=redis://username:password@host:6379/0
REDIS_ENABLED=true
```
## 🔐 Security Configuration
### SSL/TLS
With Caddy, SSL is automatic using Let's Encrypt. For manual SSL:
```caddyfile
your-domain.com {
tls your-email@domain.com # Let's Encrypt
# OR
tls /path/to/cert.pem /path/to/key.pem # Custom certificates
reverse_proxy rentcache:8000
}
```
### API Key Security
```bash
# Create production API key with strict limits
docker compose exec rentcache uv run rentcache create-key production_app YOUR_RENTCAST_KEY \
--daily-limit 5000 \
--monthly-limit 100000 \
--expires 2024-12-31
# Create development key with higher limits
docker compose exec rentcache uv run rentcache create-key dev_app YOUR_RENTCAST_KEY \
--daily-limit 10000 \
--monthly-limit 200000
```
### Network Security
```yaml
# Restrict network access
services:
rentcache:
networks:
- caddy
- internal
# Don't expose ports directly in production
postgres:
networks:
- internal # Only internal network
# No external access
redis:
networks:
- internal # Only internal network
networks:
caddy:
external: true
internal:
driver: bridge
```
## 📊 Monitoring and Logging
### Health Checks
```yaml
services:
rentcache:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
```
### Logging Configuration
#### JSON Structured Logging
```env
LOG_FORMAT=json
LOG_LEVEL=INFO
```
#### Log Aggregation with Docker
```yaml
services:
rentcache:
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "5"
tag: "rentcache-{{.Name}}"
```
#### Centralized Logging
For production, consider using:
- **ELK Stack** (Elasticsearch, Logstash, Kibana)
- **Grafana Loki** with Promtail
- **Fluentd** or **Fluent Bit**
Example Promtail configuration:
```yaml
# promtail-config.yml
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: rentcache
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
relabel_configs:
- source_labels: ['__meta_docker_container_label_com_docker_compose_service']
target_label: 'service'
- source_labels: ['__meta_docker_container_name']
target_label: 'container'
```
### Metrics Collection
#### Prometheus Integration
```yaml
# prometheus.yml
scrape_configs:
- job_name: 'rentcache'
static_configs:
- targets: ['rentcache:8000']
metrics_path: '/metrics'
scrape_interval: 30s
scrape_timeout: 10s
```
#### Grafana Dashboard
Key metrics to monitor:
- **Cache Hit Ratio**: Target > 80%
- **Response Time**: 95th percentile < 200ms
- **Error Rate**: < 1%
- **API Cost**: Daily/monthly spending
- **Request Volume**: Requests per minute
- **Database Performance**: Query time, connection pool
## 🚀 Production Deployment Checklist
### Pre-Deployment
- [ ] **Environment Variables**: Configure production .env
- [ ] **SSL Certificates**: Verify domain and SSL setup
- [ ] **Database**: PostgreSQL configured and accessible
- [ ] **Redis**: Optional but recommended for performance
- [ ] **Monitoring**: Health checks and metrics collection
- [ ] **Backup Strategy**: Database and configuration backups
- [ ] **Security**: Network restrictions and API key management
### Deployment Steps
```bash
# 1. Clone and configure
git clone https://git.supported.systems/MCP/rentcache.git
cd rentcache
cp .env.example .env
# Edit .env with production settings
# 2. Deploy
make setup
# 3. Verify deployment
curl https://your-domain.com/health
# 4. Create API keys
make create-key NAME=production_app KEY=your_rentcast_key
# 5. Test API access
curl -H "Authorization: Bearer your_rentcast_key" \
"https://your-domain.com/api/v1/properties?city=Austin&state=TX&limit=1"
# 6. Monitor metrics
curl https://your-domain.com/metrics
```
### Post-Deployment
- [ ] **Monitor Logs**: Check for errors and warnings
- [ ] **Test All Endpoints**: Verify API functionality
- [ ] **Cache Performance**: Monitor hit ratios
- [ ] **Cost Tracking**: Track API cost savings
- [ ] **Backup Verification**: Test restore procedures
- [ ] **Performance Baseline**: Establish performance metrics
## 🔄 Maintenance and Updates
### Regular Maintenance
```bash
# Update containers
docker compose pull
docker compose up -d
# Clean old images
docker system prune -f
# Check logs
make logs
# Monitor health
make health
# View statistics
make stats
```
### Database Maintenance
```bash
# PostgreSQL maintenance
docker compose exec postgres psql -U rentcache -d rentcache -c "VACUUM ANALYZE;"
# Clear old cache entries (older than 7 days)
docker compose exec rentcache uv run rentcache clear-cache --older-than 168
```
### Backup Procedures
```bash
# Database backup
docker compose exec postgres pg_dump -U rentcache rentcache > backup-$(date +%Y%m%d).sql
# Configuration backup
tar -czf config-backup-$(date +%Y%m%d).tar.gz .env docker-compose.yml
# Restore database
docker compose exec -T postgres psql -U rentcache -d rentcache < backup-20240115.sql
```
## 🚨 Troubleshooting
### Common Issues
#### Service Won't Start
```bash
# Check logs
docker compose logs rentcache
# Check network
docker network ls | grep caddy
# Verify configuration
docker compose config
```
#### SSL Certificate Issues
```bash
# Check Caddy logs
docker logs caddy-docker-proxy
# Force certificate renewal
docker exec caddy-docker-proxy caddy reload
```
#### Database Connection Issues
```bash
# Test database connection
docker compose exec rentcache uv run python -c "
from sqlalchemy import create_engine
engine = create_engine('$DATABASE_URL')
print('Database connection successful!')
"
```
#### High Response Times
```bash
# Enable Redis if not already
docker compose --profile redis up -d
# Check cache hit ratio
curl https://your-domain.com/metrics | jq '.cache_hit_ratio'
# Monitor database performance
docker compose exec postgres psql -U rentcache -d rentcache -c "
SELECT query, mean_time, calls
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;"
```
### Performance Tuning
#### Database Optimization
```sql
-- Create indexes for better performance
CREATE INDEX IF NOT EXISTS idx_cache_entries_endpoint ON cache_entries(endpoint);
CREATE INDEX IF NOT EXISTS idx_cache_entries_created_at ON cache_entries(created_at);
CREATE INDEX IF NOT EXISTS idx_usage_stats_api_key_id ON usage_stats(api_key_id);
CREATE INDEX IF NOT EXISTS idx_usage_stats_created_at ON usage_stats(created_at);
```
#### Application Tuning
```env
# Increase cache TTLs for stable data
DEFAULT_CACHE_TTL=7200
EXPENSIVE_ENDPOINTS_TTL=172800
# Optimize rate limits
GLOBAL_RATE_LIMIT=5000/hour
PER_ENDPOINT_RATE_LIMIT=200/minute
```
---
Ready for production? Ensure you've followed all security best practices and monitoring is properly configured. Check the [Architecture Guide](ARCHITECTURE.md) for system design details.

View File

@ -1,391 +0,0 @@
# Quick Start Guide
Get RentCache running in 5 minutes and start saving on Rentcast API costs immediately.
## ⚡ 5-Minute Setup
### Prerequisites
- **Docker & Docker Compose**: [Install Docker](https://docs.docker.com/get-docker/)
- **Rentcast API Key**: [Get your key](https://developers.rentcast.io/)
- **Domain** (optional): For production deployment
### Step 1: Clone and Configure
```bash
# Clone repository
git clone https://git.supported.systems/MCP/rentcache.git
cd rentcache
# Quick setup with defaults
make setup
```
### Step 2: Create API Key
```bash
# Replace 'your_rentcast_api_key' with your actual Rentcast API key
make create-key NAME=quickstart KEY=your_rentcast_api_key
```
### Step 3: Test Your Setup
```bash
# Test with a simple property search
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/properties?city=Austin&state=TX&limit=1"
```
**🎉 That's it!** RentCache is now proxying your Rentcast API calls with intelligent caching.
## 🔍 Verify Everything Works
### Check System Health
```bash
curl https://rentcache.l.supported.systems/health
```
**Expected Response:**
```json
{
"status": "healthy",
"timestamp": "2024-01-15T10:30:00Z",
"version": "1.0.0",
"database": "healthy",
"cache_backend": "sqlite",
"active_keys": 1,
"total_cache_entries": 0,
"cache_hit_ratio_24h": null
}
```
### View API Documentation
Open in browser: **https://rentcache.l.supported.systems/docs**
### Monitor Performance
```bash
# View real-time metrics
curl https://rentcache.l.supported.systems/metrics | jq
```
## 🚀 First API Calls
### Property Search
```bash
# Search properties in Austin, TX
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/properties?city=Austin&state=TX&limit=5"
```
### Value Estimate
```bash
# Get property value estimate
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/estimates/value?address=123%20Main%20St&city=Austin&state=TX"
```
### Rent Estimate
```bash
# Get rent estimate
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/estimates/rent?address=123%20Main%20St&city=Austin&state=TX"
```
### Market Statistics
```bash
# Get market stats for ZIP code
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/markets/stats?zipCode=78701"
```
## 💰 See Your Savings
### Make the Same Call Twice
```bash
# First call (cache miss - costs money)
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/properties?city=Dallas&state=TX&limit=1"
# Second call (cache hit - FREE!)
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/properties?city=Dallas&state=TX&limit=1"
```
### Check Response Headers
```bash
# Look for cache hit indicators
curl -I -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/properties?city=Dallas&state=TX&limit=1"
```
**Response Headers:**
```
X-Cache-Hit: true
X-Response-Time-MS: 12.5
# X-Estimated-Cost header only appears on cache misses
```
### View Usage Statistics
```bash
# Check your savings so far
curl https://rentcache.l.supported.systems/metrics | jq '{
total_requests: .total_requests,
cache_hits: .cache_hits,
cache_hit_ratio: .cache_hit_ratio,
estimated_savings: "Calculated from cache hits"
}'
```
## 🔧 Common Use Cases
### Real Estate Applications
#### Property Portfolio Analysis
```bash
# Get multiple properties in a neighborhood
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/properties?zipCode=78701&limit=50"
# Get value estimates for each (subsequent calls will be cached)
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/estimates/value?zipCode=78701&propertyType=Single%20Family"
```
#### Market Research
```bash
# Research multiple markets efficiently
for city in Austin Dallas Houston; do
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/markets/stats?city=$city&state=TX"
done
```
#### Rental Property Management
```bash
# Monitor rental market for your properties
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/listings/rental?city=Austin&state=TX&bedrooms=3&limit=20"
# Get rent estimates for comparison
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/estimates/rent?address=123%20Property%20St&city=Austin&state=TX"
```
### Investment Analysis
#### Comparative Market Analysis
```bash
# Get comparable properties
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/comparables?address=456%20Investment%20Ave&city=Austin&state=TX"
# Analyze multiple similar properties (cached for efficiency)
for address in "123 Main St" "456 Oak Ave" "789 Pine St"; do
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/estimates/value?address=$address&city=Austin&state=TX"
done
```
## 🎛️ Cache Control
### Force Fresh Data
When you need the absolute latest data:
```bash
# Force refresh (bypasses cache)
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/estimates/value?address=123%20Main%20St&city=Austin&state=TX&force_refresh=true"
```
### Custom Cache Duration
Set custom cache times for your specific needs:
```bash
# Cache for 2 hours (7200 seconds)
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/properties?city=Austin&state=TX&ttl_override=7200"
# Cache for 10 minutes (600 seconds) for frequently changing data
curl -H "Authorization: Bearer your_rentcast_api_key" \
"https://rentcache.l.supported.systems/api/v1/listings/rental?city=Austin&state=TX&ttl_override=600"
```
## 📊 Monitoring Your Usage
### Real-Time Dashboard
Access your usage dashboard:
**https://rentcache.l.supported.systems/docs**
### CLI Monitoring
```bash
# View usage statistics
make stats
# Check system health
make health
# View recent logs
make logs
```
### Key Metrics to Watch
1. **Cache Hit Ratio**: Aim for >80%
```bash
curl -s https://rentcache.l.supported.systems/metrics | jq '.cache_hit_ratio'
```
2. **Response Times**: Should be <50ms for cache hits
```bash
curl -s https://rentcache.l.supported.systems/metrics | jq '.avg_response_time_ms'
```
3. **Cost Savings**: Track your monthly savings
```bash
curl -s https://rentcache.l.supported.systems/metrics | jq '.cost_24h'
```
## 🛠️ Troubleshooting
### Common Issues
#### "401 Unauthorized" Error
```bash
# Check if your API key is created and active
make list-keys
# Recreate if needed
make create-key NAME=quickstart KEY=your_correct_rentcast_key
```
#### "Service Unavailable" Error
```bash
# Check system health
curl https://rentcache.l.supported.systems/health
# Check logs
make logs
```
#### Slow Response Times
```bash
# Check if Redis is enabled for better cache performance
make dev # Includes Redis profile
```
### Getting Help
1. **Check Logs**: `make logs`
2. **Verify Health**: `curl https://rentcache.l.supported.systems/health`
3. **Test API Key**: `make list-keys`
4. **View Documentation**: https://rentcache.l.supported.systems/docs
## 🎯 Next Steps
### Optimize for Your Workload
1. **Adjust Cache TTLs**: Based on your data freshness needs
2. **Monitor Usage Patterns**: Use the metrics endpoint
3. **Set Up Alerts**: Monitor cache hit ratios and costs
4. **Scale Resources**: Add Redis for high-traffic applications
### Integration Examples
#### Python Application
```python
import httpx
class RentCacheClient:
def __init__(self, api_key: str, base_url: str = "https://rentcache.l.supported.systems"):
self.api_key = api_key
self.base_url = base_url
self.client = httpx.AsyncClient()
async def search_properties(self, city: str, state: str, limit: int = 10):
headers = {"Authorization": f"Bearer {self.api_key}"}
params = {"city": city, "state": state, "limit": limit}
response = await self.client.get(
f"{self.base_url}/api/v1/properties",
headers=headers,
params=params
)
return response.json()
# Usage
client = RentCacheClient("your_rentcast_api_key")
properties = await client.search_properties("Austin", "TX")
```
#### Node.js Application
```javascript
const axios = require('axios');
class RentCacheClient {
constructor(apiKey, baseUrl = 'https://rentcache.l.supported.systems') {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
this.client = axios.create({
baseURL: baseUrl,
headers: {
'Authorization': `Bearer ${apiKey}`
}
});
}
async searchProperties(city, state, limit = 10) {
const response = await this.client.get('/api/v1/properties', {
params: { city, state, limit }
});
return response.data;
}
}
// Usage
const client = new RentCacheClient('your_rentcast_api_key');
const properties = await client.searchProperties('Austin', 'TX');
```
### Advanced Configuration
#### Custom Deployment
```bash
# Clone for custom configuration
git clone https://git.supported.systems/MCP/rentcache.git
cd rentcache
# Edit configuration
cp .env.example .env
nano .env # Customize settings
# Deploy with custom config
make setup
```
#### Production Deployment
See the [Deployment Guide](DEPLOYMENT.md) for:
- PostgreSQL database setup
- Redis configuration
- SSL certificate management
- Monitoring and alerting
- Backup strategies
---
**🎉 Congratulations!** You're now using RentCache to reduce your Rentcast API costs. Monitor your cache hit ratio and enjoy the savings!
**Need help?** Check the [Usage Guide](USAGE.md) for detailed examples or the [API Reference](API.md) for complete endpoint documentation.

View File

@ -132,10 +132,6 @@ curl -H "X-Api-Key: YOUR_RENTCAST_KEY" \
"https://api.rentcast.io/v1/properties?city=Austin&state=TX" "https://api.rentcast.io/v1/properties?city=Austin&state=TX"
# Through RentCache (what you should do now) # Through RentCache (what you should do now)
curl -H "Authorization: Bearer YOUR_RENTCAST_KEY" \
"https://rentcache.l.supported.systems/api/v1/properties?city=Austin&state=TX"
# Or for local development
curl -H "Authorization: Bearer YOUR_RENTCAST_KEY" \ curl -H "Authorization: Bearer YOUR_RENTCAST_KEY" \
"http://localhost:8000/api/v1/properties?city=Austin&state=TX" "http://localhost:8000/api/v1/properties?city=Austin&state=TX"
``` ```
@ -147,22 +143,22 @@ curl -H "Authorization: Bearer YOUR_RENTCAST_KEY" \
```bash ```bash
# Basic property search # Basic property search
curl -H "Authorization: Bearer YOUR_API_KEY" \ curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://rentcache.l.supported.systems/api/v1/properties?city=Austin&state=TX&limit=10" "http://localhost:8000/api/v1/properties?city=Austin&state=TX&limit=10"
# Advanced property search # Advanced property search
curl -H "Authorization: Bearer YOUR_API_KEY" \ curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://rentcache.l.supported.systems/api/v1/properties?address=123%20Main%20St&zipCode=78701&propertyType=Single%20Family&bedrooms=3&bathrooms=2&squareFootage=1500" "http://localhost:8000/api/v1/properties?address=123%20Main%20St&zipCode=78701&propertyType=Single%20Family&bedrooms=3&bathrooms=2&squareFootage=1500"
# With pagination # With pagination
curl -H "Authorization: Bearer YOUR_API_KEY" \ curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://rentcache.l.supported.systems/api/v1/properties?city=Austin&state=TX&offset=20&limit=20" "http://localhost:8000/api/v1/properties?city=Austin&state=TX&offset=20&limit=20"
``` ```
#### Get Property by ID #### Get Property by ID
```bash ```bash
curl -H "Authorization: Bearer YOUR_API_KEY" \ curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://rentcache.l.supported.systems/api/v1/properties/12345" "http://localhost:8000/api/v1/properties/12345"
``` ```
### Value and Rent Estimates ### Value and Rent Estimates
@ -172,11 +168,11 @@ curl -H "Authorization: Bearer YOUR_API_KEY" \
```bash ```bash
# Get value estimate # Get value estimate
curl -H "Authorization: Bearer YOUR_API_KEY" \ curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://rentcache.l.supported.systems/api/v1/estimates/value?address=123%20Main%20St&city=Austin&state=TX" "http://localhost:8000/api/v1/estimates/value?address=123%20Main%20St&city=Austin&state=TX"
# Value estimate with property details # Value estimate with property details
curl -H "Authorization: Bearer YOUR_API_KEY" \ curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://rentcache.l.supported.systems/api/v1/estimates/value?zipCode=78701&propertyType=Single%20Family&bedrooms=3&bathrooms=2&squareFootage=1800" "http://localhost:8000/api/v1/estimates/value?zipCode=78701&propertyType=Single%20Family&bedrooms=3&bathrooms=2&squareFootage=1800"
``` ```
#### Rent Estimates #### Rent Estimates
@ -260,7 +256,7 @@ Force a fresh API call even if cached data exists:
```bash ```bash
curl -H "Authorization: Bearer YOUR_API_KEY" \ curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://rentcache.l.supported.systems/api/v1/properties?city=Austin&state=TX&force_refresh=true" "http://localhost:8000/api/v1/properties?city=Austin&state=TX&force_refresh=true"
``` ```
#### Override TTL #### Override TTL
@ -270,11 +266,11 @@ Set custom cache duration (in seconds):
```bash ```bash
# Cache for 2 hours (7200 seconds) # Cache for 2 hours (7200 seconds)
curl -H "Authorization: Bearer YOUR_API_KEY" \ curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://rentcache.l.supported.systems/api/v1/estimates/value?address=123%20Main%20St&ttl_override=7200" "http://localhost:8000/api/v1/estimates/value?address=123%20Main%20St&ttl_override=7200"
# Cache for 10 minutes (600 seconds) # Cache for 10 minutes (600 seconds)
curl -H "Authorization: Bearer YOUR_API_KEY" \ curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://rentcache.l.supported.systems/api/v1/listings/sale?city=Austin&ttl_override=600" "http://localhost:8000/api/v1/listings/sale?city=Austin&ttl_override=600"
``` ```
### Reading Response Headers ### Reading Response Headers
@ -283,7 +279,7 @@ Every response includes cache information:
```bash ```bash
curl -I -H "Authorization: Bearer YOUR_API_KEY" \ curl -I -H "Authorization: Bearer YOUR_API_KEY" \
"https://rentcache.l.supported.systems/api/v1/properties?city=Austin&state=TX" "http://localhost:8000/api/v1/properties?city=Austin&state=TX"
# Response headers include: # Response headers include:
# X-Cache-Hit: true # X-Cache-Hit: true
@ -367,10 +363,10 @@ uv run rentcache health
```bash ```bash
# Get detailed system metrics # Get detailed system metrics
curl https://rentcache.l.supported.systems/metrics | jq '.' curl http://localhost:8000/metrics | jq '.'
# Key metrics to monitor: # Key metrics to monitor:
curl https://rentcache.l.supported.systems/metrics | jq '{ curl http://localhost:8000/metrics | jq '{
cache_hit_ratio: .cache_hit_ratio, cache_hit_ratio: .cache_hit_ratio,
avg_response_time: .avg_response_time_ms, avg_response_time: .avg_response_time_ms,
requests_24h: .requests_24h, requests_24h: .requests_24h,
@ -400,10 +396,10 @@ RentCache tracks estimated costs for different endpoint types:
uv run rentcache stats | grep -A 5 "Cost" uv run rentcache stats | grep -A 5 "Cost"
# Daily cost tracking # Daily cost tracking
curl https://rentcache.l.supported.systems/metrics | jq '.cost_24h' curl http://localhost:8000/metrics | jq '.cost_24h'
# Calculate savings # Calculate savings
curl https://rentcache.l.supported.systems/metrics | jq ' curl http://localhost:8000/metrics | jq '
.total_requests as $total | .total_requests as $total |
.cache_hits as $hits | .cache_hits as $hits |
($hits / $total * 100) as $hit_ratio | ($hits / $total * 100) as $hit_ratio |
@ -417,21 +413,21 @@ curl https://rentcache.l.supported.systems/metrics | jq '
```bash ```bash
# Cache property records for 48 hours instead of 24 # Cache property records for 48 hours instead of 24
curl -H "Authorization: Bearer YOUR_API_KEY" \ curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://rentcache.l.supported.systems/api/v1/properties?address=123%20Main%20St&ttl_override=172800" "http://localhost:8000/api/v1/properties?address=123%20Main%20St&ttl_override=172800"
``` ```
2. **Batch Related Requests**: 2. **Batch Related Requests**:
```bash ```bash
# Instead of multiple individual requests, search broader then filter locally # Instead of multiple individual requests, search broader then filter locally
curl -H "Authorization: Bearer YOUR_API_KEY" \ curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://rentcache.l.supported.systems/api/v1/properties?zipCode=78701&limit=100" "http://localhost:8000/api/v1/properties?zipCode=78701&limit=100"
``` ```
3. **Use Appropriate Endpoints**: 3. **Use Appropriate Endpoints**:
```bash ```bash
# Use less expensive listing searches when you don't need full property records # Use less expensive listing searches when you don't need full property records
curl -H "Authorization: Bearer YOUR_API_KEY" \ curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://rentcache.l.supported.systems/api/v1/listings/sale?city=Austin&state=TX" "http://localhost:8000/api/v1/listings/sale?city=Austin&state=TX"
``` ```
## 🔧 Advanced Configuration ## 🔧 Advanced Configuration
@ -601,7 +597,7 @@ tail -f /var/log/rentcache.log | grep "ERROR\|WARNING"
```bash ```bash
# Monitor request patterns # Monitor request patterns
watch -n 5 'curl -s https://rentcache.l.supported.systems/metrics | jq "{requests_24h, cache_hits_24h, hit_ratio: (.cache_hits_24h / .requests_24h * 100)}"' watch -n 5 'curl -s http://localhost:8000/metrics | jq "{requests_24h, cache_hits_24h, hit_ratio: (.cache_hits_24h / .requests_24h * 100)}"'
# Monitor system resources # Monitor system resources
htop htop