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""" - - - - - - Stock Oracle API Documentation - - - -

๐Ÿ”ฎ Stock Oracle API Documentation

-

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"" + f"{r['method']}" + f"{display_path}" + f"{r['summary']}" + f"" + ) + sections_html += f"

{tag}

{rows}
" + + title = schema.get("info", {}).get("title", "API") + version = schema.get("info", {}).get("version", "") + total = sum(len(v) for v in tag_routes.values()) + + html = f""" + + + + + {title} + + + +

๐Ÿ”ฎ {title}

+ +

v{version}  ยท  Base URL: {api_prefix}  ยท  {total} endpoints

+ {sections_html} + + +""" + + return HTMLResponse(content=html) -

๐Ÿš€ Quick Start

-

Base URL: http://localhost:18001/api/v1

- -

๐ŸŽฏ Main Endpoints

- -

Health & System

- - -

Financial Data

- - -

Price Data

- - -

Stock Market Data NEW

- - -

FRED Economic Data NEW

- - -

News & Social Media NEW

- - -

SEC Filings NEW

- - -

Alpaca Market Data NEW

- - -

FINRA Short Volume NEW

- - -

ETF Holdings

- - -

Stock Screener NEW

- - -

Attention Overlay NEW

- - -

๐Ÿ“Š Example Requests

- -

Financial Data

-
curl -X POST "http://localhost:18001/api/v1/financial/data" \\
-  -H "Content-Type: application/json" \\
-  -d '{{"ticker": "AAPL", "period": "1y", "include_metrics": true}}'
- -

Trending Stocks NEW

-
# 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"
- -

Index Constituents NEW

-
# 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"
- -

FRED Economic Data NEW

-
# 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"
- -

News & Social Data NEW

-
curl "http://localhost:18001/api/v1/news/AAPL?days_back=7&max_articles=20"
- -

Price - Quote/Intraday/Today NEW

-
# 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"
- -

SEC Filings NEW

-
# 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"
- -

ETF Holdings

-
curl "http://localhost:18001/api/v1/etf/holdings/QQQ"
- -

๐Ÿ Python Client

-
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)
- -

๐Ÿ“ˆ Key Features

- - -

Attention Overlay Response Example NEW

-
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}}
-  }}
-}}
- -

Alpaca Market Data NEW

-
# 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"
- -

FINRA Short Volume NEW

-
# 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"
- -

Stock Screener NEW

-
# 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"
- -

Attention Overlay NEW

-
# 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"
- -

๐Ÿ”ง Data Sources

- - - - - - """ - - return HTMLResponse(content=simple_html) - - except Exception as e: - # Fallback to Swagger UI if anything goes wrong + except Exception: return RedirectResponse(url=f"{settings.API_PREFIX}/docs") # Additional metadata for OpenAPI