Skip to main content

Congressional trading disclosure scraper and REST API

Project description

Congressional Trading Datastore

PyPI version Python 3.12+ License: MIT

Scrapes, parses, and serves U.S. House financial disclosure (PTR) filings as a REST API with an interactive dashboard.

Installation

pip install congressional-trading

System dependency: This package requires pdftotext from Poppler:

# macOS
brew install poppler

# Debian/Ubuntu
sudo apt-get install poppler-utils

# Fedora
sudo dnf install poppler-utils

Quick Start (Local)

# Prerequisites: Python 3.12+, uv, pdftotext (poppler)
brew install poppler  # macOS

# Install dependencies
uv sync

# Run the server
DATABASE_PATH=data/congressional_trades.db uv run uvicorn congressional_trading.main:app --reload --port 8080
  • Dashboard: http://localhost:8080/dashboard
  • API docs: http://localhost:8080/docs
  • Health check: http://localhost:8080/api/v1/health

On first startup the scraper runs automatically if no recent scrape exists, pulling filings from 2020 to present.

Deployment

See docs/deployment.md for Railway production deployment instructions.

Environment Variables

Variable Default Description
DATABASE_PATH /data/congressional_trades.db SQLite DB path. Set to data/congressional_trades.db for local dev.
LOG_LEVEL INFO Logging level
SCRAPE_HOUR_UTC 6 Hour (UTC) for the daily scrape cron job
SCRAPE_START_YEAR 2020 Earliest year to scrape filings from

API Endpoints

All endpoints are prefixed with /api/v1. Rate limited to 10 req/sec.

Core

Method Path Description
GET /trades List trades. Requires ticker or member. Params: days, transaction_type, limit, offset
GET /trades/summary Aggregate stats for a ticker. Params: ticker (required), days
GET /members Members with recent trading activity. Params: days, limit, offset
GET /health DB stats, last scrape time. Returns 503 if stale (>48h)

Charts / Dashboard

Method Path Description
GET /trades/recent Recent trades for charting. Params: days, member, ticker, transaction_type
GET /trades/trending Most-traded tickers with buy/sell breakdown. Params: days, limit
GET /members/{member}/performance Member returns (30/60/90d) vs SPY with win rate
GET /tickers/{ticker}/activity Ticker price history with congressional trade markers

Dashboard UI

Path Description
/dashboard Interactive HTML dashboard with charts (Plotly.js)

Database Schema

SQLite with WAL mode. Four tables:

  • filings — One row per House PTR filing. Tracks member info, filing date/year, processing status, retry count.
  • trades — Individual transactions parsed from filings. Ticker, asset description, transaction type/date, amount range, owner.
  • scraper_runs — Audit log of scrape cycles with counts and timing.
  • price_cache — Cached stock closing prices from yfinance (ticker + date).

How the Scraper Works

  1. Downloads annual ZIP index files from disclosures-clerk.house.gov
  2. Parses the XML index to find PTR (Periodic Transaction Report) filings
  3. Downloads each PDF, extracts text with pdftotext -layout
  4. Parses columnar text into structured trade records
  5. Validates dates (rejects impossible years from PDF misalignment) and amounts

Runs daily at SCRAPE_HOUR_UTC via APScheduler. Includes rate limiting (1s between requests), circuit breaker (pauses after 5 consecutive failures), and retry logic (up to 3 attempts per filing).

Running Tests

uv run pytest tests/unit/test_parser.py -v

Project Structure

src/congressional_trading/
├── main.py              # FastAPI app, lifespan, static files
├── config.py            # Environment variables and constants
├── api/
│   ├── routes.py        # Core API endpoints
│   └── chart_routes.py  # Dashboard/chart endpoints
├── db/
│   ├── database.py      # SQLite connection, schema, pragmas
│   ├── queries.py       # All SQL queries
│   └── models.py        # Pydantic response models
├── parser/
│   ├── ptr_parser.py    # PDF text → structured trades
│   ├── patterns.py      # Regex constants
│   └── xml_index.py     # XML index parser
├── scraper/
│   ├── downloader.py    # PDF download + text extraction
│   └── scheduler.py     # APScheduler cron setup
└── services/
    └── price_service.py # yfinance price fetching + caching

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

congressional_trading-0.1.0.tar.gz (127.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

congressional_trading-0.1.0-py3-none-any.whl (29.0 kB view details)

Uploaded Python 3

File details

Details for the file congressional_trading-0.1.0.tar.gz.

File metadata

  • Download URL: congressional_trading-0.1.0.tar.gz
  • Upload date:
  • Size: 127.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for congressional_trading-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1820a0835b9f5266aa9912b9048bbbcef214d10b727cafac7a5354c8ff88e830
MD5 0a9ebf555e40c7179de9cbd090fcb17d
BLAKE2b-256 7bcf75ff378e48d40908bfde335535a5bd153aa31f85eba4532b778e7b48db49

See more details on using hashes here.

File details

Details for the file congressional_trading-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: congressional_trading-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 29.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for congressional_trading-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 adfa150b3813b120dcd396878e8afd38c3da8d70fc64b63806f920b76fa5b670
MD5 d055aac54f0f6f2d3ddb3829f55950f7
BLAKE2b-256 220f2ae8d867fa96658a10bd2c90df5a2760528cf24123ac94f5e0f2f9c171b1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page