Metadata-Version: 2.4
Name: fiscaldata-treasury-api
Version: 0.1.2
Summary: Python client for the U.S. Treasury Fiscal Data API
Author-email: Charles-Emmanuel Teuf <charles-emmanuel.teuf@protonmail.com>
License: MIT
Project-URL: Homepage, https://github.com/user/fiscaldata-treasury-api
Project-URL: Documentation, https://user.github.io/fiscaldata-treasury-api
Project-URL: Repository, https://github.com/user/fiscaldata-treasury-api.git
Project-URL: Bug Tracker, https://github.com/user/fiscaldata-treasury-api/issues
Project-URL: Changelog, https://github.com/user/fiscaldata-treasury-api/blob/main/CHANGELOG.md
Keywords: treasury,fiscal-data,api-client,government-data,finance,bonds
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial :: Investment
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.25.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: urllib3>=1.26.0
Provides-Extra: dev
Requires-Dist: pytest>=7.4; extra == "dev"
Requires-Dist: pytest-cov>=4.1; extra == "dev"
Requires-Dist: ruff>=0.3; extra == "dev"
Requires-Dist: mypy>=1.8; extra == "dev"
Requires-Dist: types-requests>=2.31; extra == "dev"
Provides-Extra: docs
Requires-Dist: mkdocs>=1.5; extra == "docs"
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
Provides-Extra: pandas
Requires-Dist: pandas>=1.3; extra == "pandas"
Dynamic: license-file


# Treasury Fiscal Data API Client

[![PyPI version](https://img.shields.io/pypi/v/fiscaldata-treasury-api.svg)](https://pypi.org/project/fiscaldata-treasury-api/)
[![Python](https://img.shields.io/pypi/pyversions/fiscaldata-treasury-api.svg)](https://pypi.org/project/fiscaldata-treasury-api/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Tests](https://github.com/user/fiscaldata-treasury-api/actions/workflows/tests.yml/badge.svg)](https://github.com/user/fiscaldata-treasury-api/actions)
[![Coverage](https://img.shields.io/codecov/c/github/user/fiscaldata-treasury-api)](https://codecov.io/gh/user/fiscaldata-treasury-api)

A professional Python client for the [U.S. Treasury Fiscal Data API](https://fiscaldata.treasury.gov/). No API key required.

## Features

- **Zero config** — no API key, no registration
- **Type-safe** — Pydantic v2 models for every dataset
- **Fluent filters** — `FilterBuilder` for clean, composable queries
- **Auto-pagination** — lazy `iter_pages()` generator and `get_all()` collector
- **Resilient** — automatic retries with exponential backoff on server errors
- **pandas-ready** — one-line `response.to_dataframe()` export
- **Context manager** — proper session lifecycle management

## Installation

```bash
pip install fiscaldata-treasury-api
```

With pandas support:

```bash
pip install "fiscaldata-treasury-api[pandas]"
```

## Quick Start

```python
from core import TreasuryClient

client = TreasuryClient()

# Latest U.S. public debt figures
debt = client.get_public_debt(limit=5)
for record in debt:
    print(f"{record.record_date}  ${record.tot_pub_debt_out_amt:,.0f}")

# Recent T-Bill auction results
auctions = client.get_auctions(security_type="Bill", limit=10)
for a in auctions:
    print(f"{a.auction_date}  {a.security_term}  rate={a.high_investment_rate}%")

# USD/EUR exchange rates
rates = client.get_exchange_rates(country_currency="Euro Zone-Euro", limit=4)
for r in rates:
    print(f"{r.record_date}  {r.exchange_rate}")
```

## Filtering

Use `FilterBuilder` to compose queries with a fluent API:

```python
from core import TreasuryClient
from core.filters import FilterBuilder

client = TreasuryClient()

f = (
    FilterBuilder()
    .eq("security_type", "Note")
    .gte("auction_date", "2024-01-01")
    .lte("auction_date", "2024-12-31")
)

auctions = client.get_all("auctions", filters=f, sort="-auction_date")
```

| Method | Operator |
|--------|----------|
| `.eq(field, value)` | `field == value` |
| `.neq(field, value)` | `field != value` |
| `.gt(field, value)` | `field > value` |
| `.gte(field, value)` | `field >= value` |
| `.lt(field, value)` | `field < value` |
| `.lte(field, value)` | `field <= value` |
| `.in_(field, [v1, v2])` | `field in (v1, v2)` |

## Pagination

```python
# Lazy page-by-page iteration (memory-efficient for large datasets)
for page in client.iter_pages("auctions", page_size=1000, sort="-auction_date"):
    for record in page.data:
        process(record)

# Collect all records into a flat list
all_records = client.get_all(
    "debt_to_penny",
    filters=FilterBuilder().gte("record_date", "2023-01-01"),
    page_size=1000,
)
```

## Export to pandas

```python
response = client.get("debt_to_penny", page_size=200, sort="-record_date")
df = response.to_dataframe()
```

## Raw endpoint access

```python
# Named key (recommended)
response = client.get("debt_to_penny", page_size=10)

# Raw path (access any endpoint, including undocumented ones)
response = client.get("/v2/accounting/od/debt_to_penny", page_size=10)
```

## Available Endpoints

| Key | Description | API Version |
|-----|-------------|-------------|
| `debt_to_penny` | Daily U.S. public debt outstanding | v2 |
| `avg_interest_rates` | Average interest rates on Treasury securities | v2 |
| `interest_expense` | Monthly interest expense on the national debt | v2 |
| `auctions` | Treasury security auction results | v1 |
| `exchange_rates` | Treasury Reporting Rates of Exchange | v1 |
| `savings_bonds` | U.S. Savings Bonds issuances and redemptions | v1 |
| `mts_receipts_outlays` | Monthly Treasury Statement — receipts & outlays | v1 |
| `mts_outlays_by_agency` | Monthly Treasury Statement — outlays by agency | v1 |
| `mts_budget_comparison` | Monthly Treasury Statement — budget comparison | v1 |
| `dts_operating_cash` | Daily Treasury Statement — operating cash | v1 |
| `top_by_state` | Treasury Offset Program by state | v1 |
| `top_federal` | Treasury Offset Program — federal agencies | v1 |

```python
# Discover all endpoints at runtime
for name, info in TreasuryClient.list_endpoints().items():
    print(f"{name:<25}  {info.description}")
```

## API Reference

### `TreasuryClient`

```python
TreasuryClient(
    timeout: int = 30,
    max_retries: int = 3,
    backoff_factor: float = 0.5,
)
```

**Generic methods**

| Method | Returns |
|--------|---------|
| `get(endpoint, *, fields, filters, sort, page_number, page_size)` | `APIResponse` |
| `iter_pages(endpoint, *, fields, filters, sort, page_size)` | `Generator[APIResponse]` |
| `get_all(endpoint, *, fields, filters, sort, page_size, limit)` | `List[Dict]` |
| `list_endpoints()` | `Dict[str, EndpointInfo]` |

**Typed convenience methods**

| Method | Model |
|--------|-------|
| `get_public_debt(*, start_date, end_date, limit)` | `DebtRecord` |
| `get_avg_interest_rates(*, security_type, start_date, limit)` | `InterestRateRecord` |
| `get_auctions(*, security_type, start_date, end_date, limit)` | `AuctionRecord` |
| `get_exchange_rates(*, country_currency, start_date, limit)` | `ExchangeRateRecord` |
| `get_interest_expense(*, start_date, limit)` | `InterestExpenseRecord` |
| `get_savings_bonds(*, series, limit)` | `SavingsBondsRecord` |
| `get_dts_operating_cash(*, start_date, account_type, limit)` | `DtsOperatingCashRecord` |
| `get_top_collections_by_state(*, state, limit)` | `TopByStateRecord` |

### `APIResponse`

| Attribute / Method | Description |
|--------------------|-------------|
| `.data` | `List[Dict]` — raw records |
| `.meta.total_count` | Total records matching the query |
| `.meta.total_pages` | Total pages at the current page size |
| `.meta.labels` | Human-readable field labels |
| `.links.has_next` | `True` if more pages exist |
| `.to_dataframe()` | Convert to pandas `DataFrame` |
| `.to_models(ModelClass)` | Deserialize into Pydantic models |

## Examples

See the [`examples/`](examples/) directory:

| File | Description |
|------|-------------|
| `basic_usage.py` | Quick tour of the main convenience methods |
| `debt_analysis.py` | Year-over-year debt growth analysis |
| `auction_analysis.py` | Bid-to-cover ratio statistics by security term |
| `exchange_rates.py` | Compare rates across major currencies |
| `pandas_export.py` | Export to pandas DataFrame |

```bash
python examples/basic_usage.py
python examples/debt_analysis.py 2023
python examples/auction_analysis.py 2024
```

## Development

```bash
git clone https://github.com/user/fiscaldata-treasury-api.git
cd fiscaldata-treasury-api
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
```

Run with coverage:

```bash
pytest --cov=core --cov-report=term-missing
```

Lint and format:

```bash
ruff check core tests
ruff format core tests
mypy core
```

## Publishing to PyPI

```bash
pip install build twine
python -m build
twine upload dist/*
```

## License

[MIT](LICENSE) © Charles-Emmanuel Teuf
