diff --git a/app/main.py b/app/main.py index a356070..8b2c38a 100644 --- a/app/main.py +++ b/app/main.py @@ -4,7 +4,7 @@ Main FastAPI application import os from contextlib import asynccontextmanager -from fastapi import FastAPI, HTTPException +from fastapi import FastAPI, HTTPException, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import RedirectResponse, HTMLResponse @@ -62,350 +62,119 @@ app.add_middleware( # Include API router app.include_router(api_router, prefix=settings.API_PREFIX) -# Root documentation endpoint +# Root documentation endpoint โ auto-generated from OpenAPI schema @app.get("/", response_class=HTMLResponse, include_in_schema=False) -async def root_documentation(): - """ - Display comprehensive API documentation at root path - """ +async def root_documentation(request: Request): try: - # Simple working version - simple_html = f""" - - -
- - -Comprehensive Investment Data Analysis API
- - + schema = request.app.openapi() + paths = schema.get("paths", {}) + api_prefix = settings.API_PREFIX + + # Collect all tags defined in schema (preserves order) + tag_order = [t["name"] for t in schema.get("tags", [])] + + # Group routes by first tag + from collections import defaultdict + tag_routes: dict = defaultdict(list) + untagged: list = [] + for path, methods in paths.items(): + for method, op in methods.items(): + if method.upper() not in ("GET", "POST", "PUT", "DELETE", "PATCH"): + continue + tags = op.get("tags", []) + entry = { + "method": method.upper(), + "path": path, + "summary": op.get("summary", ""), + "deprecated": op.get("deprecated", False), + } + if tags: + tag_routes[tags[0]].append(entry) + else: + untagged.append(entry) + + # Build tag sections โ respect schema tag order, then alphabetical remainder + all_tags = tag_order + sorted(t for t in tag_routes if t not in tag_order) + if untagged: + all_tags.append("other") + tag_routes["other"] = untagged + + method_colors = { + "GET": "#61affe", + "POST": "#49cc90", + "PUT": "#fca130", + "DELETE": "#f93e3e", + "PATCH": "#50e3c2", + } + + sections_html = "" + for tag in all_tags: + routes = tag_routes.get(tag, []) + if not routes: + continue + rows = "" + for r in routes: + color = method_colors.get(r["method"], "#999") + deprecated = " style='opacity:0.5;text-decoration:line-through'" if r["deprecated"] else "" + display_path = r["path"].removeprefix(api_prefix) + rows += ( + f"{display_path}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 /stocks/index/{{index_name}} - S&P 500 / Nasdaq 100 constituents from Wikipedia (24h cache) โ sp500 | nasdaq100GET /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 /filings/search/{{ticker}} - Search SEC filings (8-K, 6-K, 20-F, 40-F, 10-K, 10-Q)GET /filings/documents/{{accession_number}} - List all documents in a filingGET /filings/exhibit/{{accession_number}} - Extract exhibit content (e.g., EX-99.1 press releases)GET /alpaca/status - Alpaca connection status and key validityGET /alpaca/bars/{{ticker}} - Fetch bars directly from Alpaca (raw, no DB)GET /finra/short-volume/{{symbol}} - Short sale volume data for a symbolGET /finra/short-ratio/{{symbol}} - Short ratio history (aggregated)POST /finra/admin/ingest - Manually ingest FINRA data for a date/rangeGET /etf/holdings/{{ticker}} - ETF holdings at date or most recentPOST /etf/admin/refresh-maps - Refresh CUSIP/CIK mapsGET /screener/stocks - Filter stocks by market cap, volume, price, P/E, sector, exchangeGET /screener/fields - Available filter options, sectors, sort fields (metadata)GET /overlay/{{symbol}} - Overlay score + features + source details (0~1 score, band, hints)GET /overlay/bulk?symbols=AAPL,TSLA,NVDA - Bulk overlay scores (max 50 symbols)GET /overlay/top-movers - Symbols with highest overlay scores in last 24hGET /overlay/{{symbol}}/headlines - Recent news headlines matched to symbolGET /overlay/{{symbol}}/youtube - YouTube video mentions from investing channelsGET /overlay/{{symbol}}/wiki - Wikipedia pageview time seriesGET /overlay/{{symbol}}/crowding - FINRA short-sale crowding metricsGET /overlay/{{symbol}}/trends - Google Trends interest data (if enabled)GET /overlay/{{symbol}}/history - Historical overlay scores (backtesting)GET /overlay/admin/health - Data source health and last collection statusPOST /overlay/admin/trigger-pipeline - Manually trigger full data collection + scoringGET /overlay/admin/job-log - Pipeline job execution logcurl -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"
-
- # S&P 500 constituents (~503 stocks, cached 24h)
-curl "http://localhost:18001/api/v1/stocks/index/sp500"
-
-# Nasdaq 100 constituents (~101 stocks, cached 24h)
-curl "http://localhost:18001/api/v1/stocks/index/nasdaq100"
-
-# Force refresh (bypass cache)
-curl "http://localhost:18001/api/v1/stocks/index/sp500?force_refresh=true"
-
- # 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"
-
- # Search AAPL 8-K filings (earnings announcements, material events)
-curl "http://localhost:18001/api/v1/filings/search/AAPL?form_type=8-K&limit=5"
-
-# Search foreign issuer filings
-curl "http://localhost:18001/api/v1/filings/search/TSM?form_type=20-F"
-curl "http://localhost:18001/api/v1/filings/search/SAP?form_type=6-K"
-
-# List all documents in a filing
-curl "http://localhost:18001/api/v1/filings/documents/0000320193-26-000005"
-
-# Extract press release (Exhibit 99.1) from an 8-K
-curl "http://localhost:18001/api/v1/filings/exhibit/0000320193-26-000005?exhibit_type=EX-99.1"
-
- 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)
-
- GET /api/v1/overlay/AAPL
-{{
- "symbol": "AAPL",
- "as_of_ts": "2026-03-13T20:30:00Z",
- "overlay_score": 0.72, // 0~1 (higher = more retail attention)
- "overlay_confidence": 0.80, // fraction of sources with data
- "overlay_band": "supportive", // silent / tepid / supportive / loud / frenzied
- "hold_extension_hint": "neutral", // extend / neutral / trim
- "add_on_eligibility": false,
- "features": {{
- "headline_burst_z": 1.2, // z-score vs 30-day window
- "youtube_influence_z": 0.8,
- "wiki_attention_z": null,
- "theme_heat_z": null,
- "crowding_stress_z": -0.3
- }},
- "source_presence": {{
- "yahoo": true, "youtube": true,
- "wikimedia": false, "google_trends": false, "finra": true
- }},
- "source_details": {{
- "yahoo": {{"headline_count_6h": 5, "headline_count_24h": 12, "publisher_breadth_24h": 4}},
- "finra": {{"short_volume_ratio": 0.42, "short_volume_spike_zscore": -0.3}}
- }}
-}}
-
- # Check Alpaca connection status
-curl "http://localhost:18001/api/v1/alpaca/status"
-
-# Get daily bars from Alpaca
-curl "http://localhost:18001/api/v1/alpaca/bars/AAPL?interval=1d&start_date=2025-01-01&end_date=2025-01-31"
-
- # Ingest FINRA data for a specific date
-curl -X POST "http://localhost:18001/api/v1/finra/admin/ingest?date=2025-03-10"
-
-# Get short volume for AAPL (last 30 days)
-curl "http://localhost:18001/api/v1/finra/short-volume/AAPL?days=30"
-
-# Get short ratio history
-curl "http://localhost:18001/api/v1/finra/short-ratio/AAPL?days=60"
-
- # Small/mid-cap stocks on NYSE+NASDAQ with avg volume > 500K, sorted by market cap
-curl "http://localhost:18001/api/v1/screener/stocks?market_cap_min=500000000&market_cap_max=10000000000&exchange=NYSE,NASDAQ&min_avg_volume=500000&exclude_types=ETF,FUND"
-
-# Technology sector only
-curl "http://localhost:18001/api/v1/screener/stocks?market_cap_min=500000000&exchange=NASDAQ§or=Technology&page=1&page_size=50"
-
-# Available filter metadata
-curl "http://localhost:18001/api/v1/screener/fields"
-
- # Overlay score for a single symbol
-curl "http://localhost:18001/api/v1/overlay/AAPL"
-
-# Bulk scores (comma-separated, max 50)
-curl "http://localhost:18001/api/v1/overlay/bulk?symbols=AAPL,TSLA,NVDA,AMD,META"
-
-# Top movers by overlay score (last 24h)
-curl "http://localhost:18001/api/v1/overlay/top-movers?limit=10"
-
-# Recent headlines matched to AAPL
-curl "http://localhost:18001/api/v1/overlay/AAPL/headlines?hours=24"
-
-# Wikipedia pageview trend (last 30 days)
-curl "http://localhost:18001/api/v1/overlay/AAPL/wiki?days=30"
-
-# FINRA crowding metrics
-curl "http://localhost:18001/api/v1/overlay/AAPL/crowding"
-
-# Historical overlay scores (backtesting)
-curl "http://localhost:18001/api/v1/overlay/AAPL/history?days=90"
-
-# Manually trigger full pipeline
-curl -X POST "http://localhost:18001/api/v1/overlay/admin/trigger-pipeline"
-
-