- PR1: Project scaffold, DB models, price loader - PR2: Congressional trade ingestion (House Stock Watcher) - PR3: Security enrichment + deployment infrastructure - 37 passing tests, 87%+ coverage - Docker + Proxmox deployment ready - Complete documentation - Works 100% offline with fixtures
85 lines
2.7 KiB
Python
85 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Ingest sample congressional trades from fixture files (no network required).
|
|
Usage: python scripts/ingest_from_fixtures.py
|
|
"""
|
|
|
|
import json
|
|
import logging
|
|
from pathlib import Path
|
|
|
|
from pote.db import SessionLocal
|
|
from pote.ingestion.trade_loader import TradeLoader
|
|
|
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s")
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def main():
|
|
"""Ingest sample trades from fixtures."""
|
|
logger.info("=== Ingesting Sample Congressional Trades from Fixtures ===")
|
|
logger.info("(No network required - using test fixtures)")
|
|
|
|
# Load fixture
|
|
fixture_path = Path(__file__).parent.parent / "tests" / "fixtures" / "sample_house_watcher.json"
|
|
|
|
if not fixture_path.exists():
|
|
logger.error(f"Fixture file not found: {fixture_path}")
|
|
return 1
|
|
|
|
with open(fixture_path) as f:
|
|
transactions = json.load(f)
|
|
|
|
logger.info(f"Loaded {len(transactions)} sample transactions from fixture")
|
|
|
|
# Show sample
|
|
logger.info("\nSample transaction:")
|
|
sample = transactions[0]
|
|
for key, val in sample.items():
|
|
logger.info(f" {key}: {val}")
|
|
|
|
# Ingest into database
|
|
logger.info("\n=== Ingesting into database ===")
|
|
with SessionLocal() as session:
|
|
loader = TradeLoader(session)
|
|
counts = loader.ingest_transactions(transactions)
|
|
|
|
logger.info("\n=== Summary ===")
|
|
logger.info(f"✓ Officials created/updated: {counts['officials']}")
|
|
logger.info(f"✓ Securities created/updated: {counts['securities']}")
|
|
logger.info(f"✓ Trades ingested: {counts['trades']}")
|
|
|
|
# Query some stats
|
|
with SessionLocal() as session:
|
|
from sqlalchemy import func, select
|
|
|
|
from pote.db.models import Official, Trade
|
|
|
|
total_trades = session.scalar(select(func.count(Trade.id)))
|
|
total_officials = session.scalar(select(func.count(Official.id)))
|
|
|
|
logger.info("\nDatabase totals:")
|
|
logger.info(f" Total officials: {total_officials}")
|
|
logger.info(f" Total trades: {total_trades}")
|
|
|
|
# Show some actual data
|
|
logger.info("\n=== Sample Officials ===")
|
|
with SessionLocal() as session:
|
|
stmt = select(Official).limit(5)
|
|
officials = session.scalars(stmt).all()
|
|
for official in officials:
|
|
stmt = select(func.count(Trade.id)).where(Trade.official_id == official.id)
|
|
trade_count = session.scalar(stmt)
|
|
logger.info(
|
|
f" {official.name} ({official.chamber}, {official.party}): {trade_count} trades"
|
|
)
|
|
|
|
logger.info("\n✅ Done! All sample data ingested successfully.")
|
|
logger.info("Note: This works 100% offline using fixture files.")
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
exit(main())
|