PHASE 2 COMPLETE: REST API Implementation
✅ Fully functional FastAPI server with comprehensive features: 🏗️ Architecture: - Complete API design documentation - Modular structure (models, auth, service, main) - OpenAPI/Swagger auto-documentation 🔧 Core Features: - Memory CRUD endpoints (POST, GET, DELETE) - User management and statistics - Search functionality with filtering - Admin endpoints with proper authorization 🔐 Security & Auth: - API key authentication (Bearer token) - Rate limiting (100 req/min configurable) - Input validation with Pydantic models - Comprehensive error handling 🧪 Testing: - Comprehensive test suite with automated server lifecycle - Simple test suite for quick validation - All functionality verified and working 🐛 Fixes: - Resolved Pydantic v2 compatibility (.dict() → .model_dump()) - Fixed missing dependencies (posthog, qdrant-client, vecs, ollama) - Fixed mem0 package version metadata issues 📊 Performance: - Async operations for scalability - Request timing middleware - Proper error boundaries - Health monitoring endpoints 🎯 Status: Phase 2 100% complete - REST API fully functional 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
145
api/models.py
Normal file
145
api/models.py
Normal file
@@ -0,0 +1,145 @@
|
||||
"""
|
||||
Pydantic models for API request/response validation
|
||||
"""
|
||||
|
||||
from typing import Optional, List, Dict, Any, Union
|
||||
from pydantic import BaseModel, Field, validator
|
||||
from datetime import datetime
|
||||
import uuid
|
||||
|
||||
|
||||
class Message(BaseModel):
|
||||
"""Message model for memory input"""
|
||||
role: str = Field(..., description="Message role (user, assistant)")
|
||||
content: str = Field(..., description="Message content", min_length=1, max_length=10000)
|
||||
|
||||
|
||||
class AddMemoryRequest(BaseModel):
|
||||
"""Request model for adding memories"""
|
||||
messages: List[Message] = Field(..., description="List of messages to process")
|
||||
user_id: str = Field(..., description="User identifier", min_length=1, max_length=100)
|
||||
metadata: Optional[Dict[str, Any]] = Field(default={}, description="Additional metadata")
|
||||
|
||||
@validator('user_id')
|
||||
def validate_user_id(cls, v):
|
||||
if not v.strip():
|
||||
raise ValueError('user_id cannot be empty')
|
||||
return v.strip()
|
||||
|
||||
|
||||
class SearchMemoriesRequest(BaseModel):
|
||||
"""Request model for searching memories"""
|
||||
query: str = Field(..., description="Search query", min_length=1, max_length=1000)
|
||||
user_id: str = Field(..., description="User identifier", min_length=1, max_length=100)
|
||||
limit: Optional[int] = Field(default=10, description="Number of results", ge=1, le=100)
|
||||
threshold: Optional[float] = Field(default=0.0, description="Similarity threshold", ge=0.0, le=1.0)
|
||||
|
||||
|
||||
class UpdateMemoryRequest(BaseModel):
|
||||
"""Request model for updating memories"""
|
||||
content: Optional[str] = Field(None, description="Updated memory content", max_length=10000)
|
||||
metadata: Optional[Dict[str, Any]] = Field(None, description="Updated metadata")
|
||||
|
||||
|
||||
class MemoryResponse(BaseModel):
|
||||
"""Response model for memory objects"""
|
||||
id: str = Field(..., description="Memory identifier")
|
||||
memory: str = Field(..., description="Processed memory content")
|
||||
user_id: str = Field(..., description="User identifier")
|
||||
hash: Optional[str] = Field(None, description="Content hash")
|
||||
score: Optional[float] = Field(None, description="Similarity score")
|
||||
metadata: Optional[Dict[str, Any]] = Field(default={}, description="Memory metadata")
|
||||
created_at: datetime = Field(..., description="Creation timestamp")
|
||||
updated_at: Optional[datetime] = Field(None, description="Last update timestamp")
|
||||
|
||||
|
||||
class MemoryAddResult(BaseModel):
|
||||
"""Result of adding a memory"""
|
||||
id: str = Field(..., description="Memory identifier")
|
||||
memory: str = Field(..., description="Processed memory content")
|
||||
event: str = Field(..., description="Event type (ADD, UPDATE)")
|
||||
previous_memory: Optional[str] = Field(None, description="Previous memory content if updated")
|
||||
|
||||
|
||||
class StandardResponse(BaseModel):
|
||||
"""Standard API response format"""
|
||||
success: bool = Field(..., description="Operation success status")
|
||||
data: Optional[Union[Dict[str, Any], List[Any]]] = Field(None, description="Response data")
|
||||
message: str = Field(..., description="Response message")
|
||||
timestamp: datetime = Field(default_factory=datetime.now, description="Response timestamp")
|
||||
request_id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Request identifier")
|
||||
|
||||
|
||||
class ErrorResponse(BaseModel):
|
||||
"""Error response format"""
|
||||
success: bool = Field(default=False, description="Always false for errors")
|
||||
error: Dict[str, Any] = Field(..., description="Error details")
|
||||
timestamp: datetime = Field(default_factory=datetime.now, description="Error timestamp")
|
||||
|
||||
|
||||
class ErrorDetail(BaseModel):
|
||||
"""Error detail structure"""
|
||||
code: str = Field(..., description="Error code")
|
||||
message: str = Field(..., description="Human readable error message")
|
||||
details: Optional[Dict[str, Any]] = Field(default={}, description="Additional error details")
|
||||
request_id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Request identifier")
|
||||
|
||||
|
||||
class HealthResponse(BaseModel):
|
||||
"""Health check response"""
|
||||
status: str = Field(..., description="Health status")
|
||||
timestamp: datetime = Field(default_factory=datetime.now, description="Check timestamp")
|
||||
uptime: Optional[float] = Field(None, description="Server uptime in seconds")
|
||||
|
||||
|
||||
class SystemStatusResponse(BaseModel):
|
||||
"""System status response"""
|
||||
status: str = Field(..., description="Overall system status")
|
||||
version: str = Field(..., description="API version")
|
||||
mem0_version: str = Field(..., description="mem0 library version")
|
||||
services: Dict[str, str] = Field(..., description="Service status")
|
||||
database: Dict[str, Any] = Field(..., description="Database status")
|
||||
timestamp: datetime = Field(default_factory=datetime.now, description="Status timestamp")
|
||||
|
||||
|
||||
class UserStatsResponse(BaseModel):
|
||||
"""User statistics response"""
|
||||
user_id: str = Field(..., description="User identifier")
|
||||
total_memories: int = Field(..., description="Total number of memories")
|
||||
recent_memories: int = Field(..., description="Memories added in last 24h")
|
||||
oldest_memory: Optional[datetime] = Field(None, description="Oldest memory timestamp")
|
||||
newest_memory: Optional[datetime] = Field(None, description="Newest memory timestamp")
|
||||
storage_usage: Dict[str, Any] = Field(..., description="Storage usage statistics")
|
||||
|
||||
|
||||
class SearchResultsResponse(BaseModel):
|
||||
"""Search results response"""
|
||||
results: List[MemoryResponse] = Field(..., description="Search results")
|
||||
query: str = Field(..., description="Original search query")
|
||||
total_results: int = Field(..., description="Total number of results")
|
||||
execution_time: float = Field(..., description="Search execution time in seconds")
|
||||
|
||||
|
||||
class DeleteResponse(BaseModel):
|
||||
"""Delete operation response"""
|
||||
deleted: bool = Field(..., description="Deletion success status")
|
||||
memory_id: str = Field(..., description="Deleted memory identifier")
|
||||
message: str = Field(..., description="Deletion message")
|
||||
|
||||
|
||||
class BulkDeleteResponse(BaseModel):
|
||||
"""Bulk delete operation response"""
|
||||
deleted_count: int = Field(..., description="Number of deleted memories")
|
||||
user_id: str = Field(..., description="User identifier")
|
||||
message: str = Field(..., description="Bulk deletion message")
|
||||
|
||||
|
||||
class APIMetricsResponse(BaseModel):
|
||||
"""API metrics response"""
|
||||
total_requests: int = Field(..., description="Total API requests")
|
||||
requests_per_minute: float = Field(..., description="Average requests per minute")
|
||||
average_response_time: float = Field(..., description="Average response time in ms")
|
||||
error_rate: float = Field(..., description="Error rate percentage")
|
||||
active_users: int = Field(..., description="Active users in last hour")
|
||||
top_endpoints: List[Dict[str, Any]] = Field(..., description="Most used endpoints")
|
||||
timestamp: datetime = Field(default_factory=datetime.now, description="Metrics timestamp")
|
||||
Reference in New Issue
Block a user