# -*- coding: utf-8 -*- """Trading data FastAPI surface.""" from __future__ import annotations from typing import Any from fastapi import FastAPI, Query from backend.apps.cors import add_cors_middleware from backend.domains import trading as trading_domain 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", ) add_cors_middleware(app) @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: payload = trading_domain.get_prices_payload( ticker=ticker, start_date=start_date, end_date=end_date, ) return PriceResponse(ticker=payload["ticker"], prices=payload["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: payload = trading_domain.get_financials_payload( ticker=ticker, end_date=end_date, period=period, limit=limit, ) return FinancialMetricsResponse(financial_metrics=payload["financial_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: payload = trading_domain.get_news_payload( ticker=ticker, end_date=end_date, start_date=start_date, limit=limit, ) return CompanyNewsResponse(news=payload["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: payload = trading_domain.get_insider_trades_payload( ticker=ticker, end_date=end_date, start_date=start_date, limit=limit, ) return InsiderTradeResponse(insider_trades=payload["insider_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.""" return trading_domain.get_market_status_payload() @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.""" return trading_domain.get_market_cap_payload( ticker=ticker, end_date=end_date, ) @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: payload = trading_domain.get_line_items_payload( ticker=ticker, line_items=line_items, end_date=end_date, period=period, limit=limit, ) return LineItemResponse(search_results=payload["search_results"]) return app app = create_app() if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8001)