Build a Python module that fetches and filters SEC EDGAR filings. This is a 2-3 hour coding test focusing on clean code, typing, and testability.
You'll build:
- Company lookup (ticker → CIK)
- Filing list with filters (form type, date range)
- Basic download capability
sec_connector/
pyproject.toml
README.md
sec_connector/
__init__.py
models.py # Data models
client.py # Core logic
cli.py # Simple CLI
tests/
test_client.py
fixtures/
company_tickers.json
filings_sample.json
Dependencies: httpx, pydantic, pytest
# pyproject.toml
[project]
name = "sec-connector"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = ["httpx>=0.24", "pydantic>=2.0", "pytest>=7.0"]Create Pydantic models in models.py:
from pydantic import BaseModel
from datetime import date
class Company(BaseModel):
ticker: str
cik: str
name: str
class Filing(BaseModel):
cik: str
company_name: str
form_type: str
filing_date: date
accession_number: str
class FilingFilter(BaseModel):
form_types: list[str] | None = None
date_from: date | None = None
date_to: date | None = None
limit: int = 10Test: Models validate correctly and reject bad data.
In client.py, implement:
class SECClient:
def __init__(self, companies_data: dict[str, dict]):
"""Initialize with company ticker->info mapping."""
self._companies = companies_data
def lookup_company(self, ticker: str) -> Company:
"""Find company by ticker, raise ValueError if not found."""
# TODO: implement
passTests:
- Valid ticker returns Company
- Invalid ticker raises ValueError
- CIK is zero-padded to 10 digits
Implement filing search with filters:
class SECClient:
# ... previous code ...
def list_filings(self, cik: str, filters: FilingFilter) -> list[Filing]:
"""
Get filings for a CIK, applying filters.
- Filter by form_types (if provided)
- Filter by date range (if provided)
- Sort by date descending
- Limit results
"""
# TODO: implement
passTests:
- No filters returns all filings (limited)
- Form type filter works (only 10-K)
- Date range filter works
- Results sorted newest first
- Limit respected
Simple command-line interface in cli.py:
import json
from pathlib import Path
from sec_connector.client import SECClient
from sec_connector.models import FilingFilter
def main():
"""
Usage: python -m sec_connector.cli AAPL --form 10-K --limit 5
"""
# TODO: Parse args (use argparse or simple sys.argv)
# Load fixtures
# Call client methods
# Print results as table or JSON
pass
if __name__ == "__main__":
main()Test: Run CLI with test data and verify output.
Add:
- Input validation (empty strings, invalid dates)
- Helpful error messages
- Type hints throughout
- Docstrings for public methods
Clean code - Readable, well-organized
Type safety - Proper type hints, Pydantic validation
Error handling - Graceful failures with clear messages
Filtering logic - Correct implementation of all filters
Provide:
- Working code in the structure above
- Tests that pass:
pytest tests/ - Brief README with:
- How to install:
pip install -e . - How to run tests:
pytest - Example CLI usage
- How to install:
Time estimate: 2-3 hours
Good luck! Focus on correctness and clarity over completeness.