trading-platform-data-servi.../src/api/dependencies.py
rckrdmrd 62a9f3e1d9 feat: Initial commit - Data Service
Data aggregation and distribution service:
- Market data collection
- OHLCV aggregation
- Real-time data feeds
- Data API endpoints

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 04:30:42 -06:00

104 lines
2.9 KiB
Python

"""
FastAPI Dependencies
OrbiQuant IA Trading Platform - Data Service
"""
from typing import Optional, AsyncGenerator
import asyncpg
from fastapi import Request, HTTPException, status
from config import Config
async def get_db_pool(request: Request) -> asyncpg.Pool:
"""Get database connection pool from app state."""
pool = request.app.state.db_pool
if not pool:
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail="Database connection not available"
)
return pool
async def get_db_connection(request: Request) -> AsyncGenerator[asyncpg.Connection, None]:
"""Get a database connection from pool."""
pool = await get_db_pool(request)
async with pool.acquire() as connection:
yield connection
def get_data_service(request: Request):
"""Get DataService instance from app state."""
service = request.app.state.data_service
if not service:
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail="Data service not initialized"
)
return service
def get_config(request: Request) -> Config:
"""Get configuration from app state."""
return request.app.state.config
def get_polygon_client(request: Request):
"""Get Polygon client from app state."""
client = request.app.state.polygon_client
if not client:
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail="Polygon client not configured"
)
return client
def get_mt4_client(request: Request):
"""Get MT4/MetaAPI client from app state."""
return request.app.state.mt4_client # May be None
class RateLimiter:
"""Simple in-memory rate limiter."""
def __init__(self, requests_per_minute: int = 60):
self.requests_per_minute = requests_per_minute
self._requests: dict[str, list[float]] = {}
async def check(self, client_id: str) -> bool:
"""Check if client can make a request."""
import time
now = time.time()
minute_ago = now - 60
if client_id not in self._requests:
self._requests[client_id] = []
# Clean old requests
self._requests[client_id] = [
ts for ts in self._requests[client_id] if ts > minute_ago
]
if len(self._requests[client_id]) >= self.requests_per_minute:
return False
self._requests[client_id].append(now)
return True
# Global rate limiter instance
rate_limiter = RateLimiter(requests_per_minute=60)
async def check_rate_limit(request: Request) -> None:
"""Rate limit dependency."""
client_ip = request.client.host if request.client else "unknown"
if not await rate_limiter.check(client_ip):
raise HTTPException(
status_code=status.HTTP_429_TOO_MANY_REQUESTS,
detail="Too many requests. Please slow down."
)