# -*- coding: utf-8 -*- """Trading data FastAPI surface.""" from __future__ import annotations from typing import Any from fastapi import FastAPI, Query from fastapi.middleware.cors import CORSMiddleware from backend.config.env_config import get_cors_origins from backend.services.market import MarketService from backend.tools.data_tools import ( get_company_news, get_financial_metrics, get_insider_trades, get_market_cap, get_prices, search_line_items, ) from shared.schema import ( CompanyNewsResponse, FinancialMetricsResponse, InsiderTradeResponse, LineItemResponse, PriceResponse, ) def create_app() -> FastAPI: """Create the trading data service app.""" app = FastAPI( title="EvoTraders Trading Service", description="Read-only trading data service surface extracted from the monolith", version="0.1.0", ) app.add_middleware( CORSMiddleware, allow_origins=get_cors_origins(), allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get("/health") async def health_check() -> dict[str, str]: """Health check endpoint.""" return {"status": "healthy", "service": "trading-service"} @app.get("/api/prices", response_model=PriceResponse) async def api_get_prices( ticker: str = Query(..., min_length=1), start_date: str = Query(...), end_date: str = Query(...), ) -> PriceResponse: prices = get_prices(ticker=ticker, start_date=start_date, end_date=end_date) return PriceResponse(ticker=ticker, prices=prices) @app.get("/api/financials", response_model=FinancialMetricsResponse) async def api_get_financials( ticker: str = Query(..., min_length=1), end_date: str = Query(...), period: str = Query("ttm"), limit: int = Query(10, ge=1, le=100), ) -> FinancialMetricsResponse: metrics = get_financial_metrics( ticker=ticker, end_date=end_date, period=period, limit=limit, ) return FinancialMetricsResponse(financial_metrics=metrics) @app.get("/api/news", response_model=CompanyNewsResponse) async def api_get_news( ticker: str = Query(..., min_length=1), end_date: str = Query(...), start_date: str | None = Query(None), limit: int = Query(1000, ge=1, le=5000), ) -> CompanyNewsResponse: news = get_company_news( ticker=ticker, end_date=end_date, start_date=start_date, limit=limit, ) return CompanyNewsResponse(news=news) @app.get("/api/insider-trades", response_model=InsiderTradeResponse) async def api_get_insider_trades( ticker: str = Query(..., min_length=1), end_date: str = Query(...), start_date: str | None = Query(None), limit: int = Query(1000, ge=1, le=5000), ) -> InsiderTradeResponse: trades = get_insider_trades( ticker=ticker, end_date=end_date, start_date=start_date, limit=limit, ) return InsiderTradeResponse(insider_trades=trades) @app.get("/api/market/status") async def api_get_market_status() -> dict[str, Any]: """Return current market status using the existing market service logic.""" service = MarketService(tickers=[]) return service.get_market_status() @app.get("/api/market-cap") async def api_get_market_cap( ticker: str = Query(..., min_length=1), end_date: str = Query(...), ) -> dict[str, Any]: """Return market cap for one ticker/date.""" market_cap = get_market_cap(ticker=ticker, end_date=end_date) return { "ticker": ticker, "end_date": end_date, "market_cap": market_cap, } @app.get("/api/line-items", response_model=LineItemResponse) async def api_get_line_items( ticker: str = Query(..., min_length=1), line_items: list[str] = Query(...), end_date: str = Query(...), period: str = Query("ttm"), limit: int = Query(10, ge=1, le=100), ) -> LineItemResponse: items = search_line_items( ticker=ticker, line_items=line_items, end_date=end_date, period=period, limit=limit, ) return LineItemResponse(search_results=items) return app app = create_app() if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8001)