""" Main FastAPI application """ import os from contextlib import asynccontextmanager from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import RedirectResponse, HTMLResponse from app.core.config import settings from app.api.v1.api import api_router from app.core.database import engine, Base from app.middleware.error_logger import ErrorLoggingMiddleware from app.models import error_log, request_log, fred_data, filing # Import to register models # Create database tables @asynccontextmanager async def lifespan(app: FastAPI): # Startup - ensure tables exist async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) yield # Shutdown await engine.dispose() # Create FastAPI app app = FastAPI( title=settings.APP_NAME, version=settings.APP_VERSION, openapi_url=f"{settings.API_PREFIX}/openapi.json", docs_url=f"{settings.API_PREFIX}/docs", redoc_url=f"{settings.API_PREFIX}/redoc", lifespan=lifespan ) # Add error logging middleware app.add_middleware(ErrorLoggingMiddleware) # Set up CORS - use configured origins if available, otherwise allow all cors_origins = [str(o) for o in settings.BACKEND_CORS_ORIGINS] if settings.BACKEND_CORS_ORIGINS else ["*"] app.add_middleware( CORSMiddleware, allow_origins=cors_origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Include API router app.include_router(api_router, prefix=settings.API_PREFIX) # Root documentation endpoint @app.get("/", response_class=HTMLResponse, include_in_schema=False) async def root_documentation(): """ Display comprehensive API documentation at root path """ try: # Simple working version simple_html = f"""
Comprehensive Investment Data Analysis API
Base URL: http://localhost:18001/api/v1
GET /health - API health statusGET /health/detailed - Detailed system healthPOST /financial/data - Get comprehensive financial dataGET /financial/data/{{ticker}} - Simple financial dataPOST /financial/data/bulk - Bulk financial dataPOST /price/data - Get historical price data (OHLCV)GET /price/data/{{ticker}} - Simple price dataPOST /price/data/bulk - Bulk price dataGET /price/quote/{{ticker}} - Latest quote (regular/pre/post market)GET /price/intraday/{{ticker}} - Intraday candles (interval, period)GET /price/today/{{ticker}} - Today's OHLC (daily or 1m aggregate)GET /stocks/trending - Trending stocks with intelligent parameter coordination (n=500 default)GET /stocks/most-active - Most actively traded stocksGET /stocks/52-week-gainers - Top 52-week gaining stocksGET /fred/proxy/{{endpoint}} - Universal FRED API proxy with cachingGET /fred/endpoints - List all supported FRED API endpointsGET /fred/stats/usage - API usage statistics and monitoringGET /news/{{ticker}} - Complete news and social media dataGET /news/{{ticker}}/news-only - News articles only (faster)GET /news/{{ticker}}/social-only - Social media posts onlyGET /etf/holdings/{{ticker}} - ETF holdings at date or most recentPOST /etf/admin/refresh-maps - Refresh CUSIP/CIK mapscurl -X POST "http://localhost:18001/api/v1/financial/data" \\
-H "Content-Type: application/json" \\
-d '{{"ticker": "AAPL", "period": "1y", "include_metrics": true}}'
# Get trending stocks (default: 500 total stocks with intelligent coordination)
curl "http://localhost:18001/api/v1/stocks/trending"
# Custom total count
curl "http://localhost:18001/api/v1/stocks/trending?n=200"
# Get GDP series information
curl "http://localhost:18001/api/v1/fred/proxy/series?series_id=GDP"
# Get unemployment rate observations
curl "http://localhost:18001/api/v1/fred/proxy/series/observations?series_id=UNRATE&limit=12"
curl "http://localhost:18001/api/v1/news/AAPL?days_back=7&max_articles=20"
# Quote (latest regular/pre/post)
curl "http://localhost:18001/api/v1/price/quote/AAPL?use_prepost=true"
# Intraday 1m candles for 1 day
curl "http://localhost:18001/api/v1/price/intraday/AAPL?interval=1m&period=1d"
# Today's OHLC (daily if available; otherwise 1m aggregate)
curl "http://localhost:18001/api/v1/price/today/AAPL"
curl "http://localhost:18001/api/v1/etf/holdings/QQQ"
from stock_oracle_client import StockOracleClient
client = StockOracleClient("http://localhost:18001")
# Check health
health = client.get_health()
print("API Status:", health["status"])
# Get financial data
data = client.get_financial_data("AAPL", period="1y")
# Get news data (NEW!)
news = client.get_news_social_data("AAPL", days_back=7)