|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +**python-bcb** is a Python interface to the Brazilian Central Bank (Banco Central do Brasil) open data APIs. It provides access to time series data, exchange rates, market expectations, and financial institution data. |
| 8 | + |
| 9 | +## Python Environment |
| 10 | + |
| 11 | +**This project uses Poetry exclusively.** All Python commands must be run via `poetry run` or inside `poetry shell`. Never invoke `python`, `pytest`, `black`, or any other Python tool directly. |
| 12 | + |
| 13 | +```bash |
| 14 | +poetry run python ... |
| 15 | +poetry run pytest ... |
| 16 | +poetry run black ... |
| 17 | +``` |
| 18 | + |
| 19 | +## Commands |
| 20 | + |
| 21 | +### Setup |
| 22 | +```bash |
| 23 | +pip install poetry |
| 24 | +poetry install # install all dependency groups |
| 25 | +poetry install --with test # install with test dependencies only |
| 26 | +``` |
| 27 | + |
| 28 | +### Running Tests |
| 29 | +```bash |
| 30 | +poetry run pytest # run all tests |
| 31 | +poetry run pytest tests/test_utils.py # run a single test file |
| 32 | +poetry run pytest tests/test_currency.py::test_currency_id # run a single test |
| 33 | +``` |
| 34 | + |
| 35 | +Note: Many tests make live HTTP requests to BCB APIs. Tests marked with `@mark.flaky` may fail intermittently due to network issues or API availability. |
| 36 | + |
| 37 | +### Linting / Formatting |
| 38 | +```bash |
| 39 | +poetry run pycodestyle bcb/ # lint with pycodestyle |
| 40 | +poetry run black bcb/ # format with black |
| 41 | +``` |
| 42 | + |
| 43 | +### Docs |
| 44 | +```bash |
| 45 | +cd docs && make html SPHINXBUILD="poetry run sphinx-build" |
| 46 | +``` |
| 47 | + |
| 48 | +## Architecture |
| 49 | + |
| 50 | +The package is organized into three main API modules under `bcb/`: |
| 51 | + |
| 52 | +### `bcb.sgs` — SGS Time Series |
| 53 | +Fetches time series from the BCB's SGS (Sistema Gerenciador de Séries Temporais) JSON API. The main entry point is `sgs.get(codes, start, end, last, multi, freq)`. Codes can be `int`, `list`, `tuple`, or `dict` for named series. Returns pandas DataFrames with DatetimeIndex or PeriodIndex. |
| 54 | + |
| 55 | +- `bcb/sgs/__init__.py` — `get()` and `get_json()` functions + `SGSCode` class |
| 56 | +- `bcb/sgs/regional_economy.py` — wrapper for regional non-performing loan series with pre-mapped SGS codes by state/region |
| 57 | + |
| 58 | +### `bcb.currency` — Currency Exchange Rates |
| 59 | +Scrapes the BCB PTAX website for daily bid/ask exchange rates. Uses `requests` + `lxml` for HTML parsing. |
| 60 | + |
| 61 | +- `bcb/currency.py` — `get(symbols, start, end, side, groupby)` returns multi-indexed DataFrames. Module-level `CACHE` dict avoids redundant HTTP requests within a session. |
| 62 | + |
| 63 | +### `bcb.odata` — OData APIs |
| 64 | +A generic OData client plus named wrappers for specific BCB OData services (hosted at `olinda.bcb.gov.br`). |
| 65 | + |
| 66 | +- `bcb/odata/framework.py` — Core OData machinery: `ODataService` fetches and parses the `$metadata` XML document (via `lxml`) to discover entity sets, functions, and properties. `ODataQuery` builds and executes queries with chainable methods (`.filter()`, `.orderby()`, `.select()`, `.limit()`, `.skip()`). `ODataProperty` instances support Python comparison operators to create `ODataPropertyFilter` objects. |
| 67 | +- `bcb/odata/api.py` — `BaseODataAPI` base class and concrete named classes (`Expectativas`, `PTAX`, `IFDATA`, `TaxaJuros`, `MercadoImobiliario`, `SPI`, etc.). Each subclass just sets `BASE_URL`. The `Endpoint` class (with `EndpointMeta` metaclass) exposes entity properties as attributes, enabling `endpoint.PropertyName >= value` filter syntax. `EndpointQuery.collect()` post-processes date columns into `pd.Timestamp`. |
| 68 | +- `bcb/__init__.py` — re-exports all OData API classes at the top level (e.g., `from bcb import PTAX`). |
| 69 | + |
| 70 | +### `bcb.utils` |
| 71 | +- `Date` class: normalizes `str`, `datetime`, `date` inputs. Accepts `"today"`/`"now"` strings. |
| 72 | +- `BRAZILIAN_REGIONS` / `BRAZILIAN_STATES` constants for geographic lookups. |
| 73 | +- `DateInput` type alias used throughout the codebase. |
| 74 | + |
| 75 | +## Key Patterns |
| 76 | + |
| 77 | +- **OData query building**: `api.get_endpoint("EntityName")` returns an `Endpoint`. Call `.get(Property >= value, limit=100)` for one-shot queries, or `.query()` for a chainable `EndpointQuery`. |
| 78 | +- **`ODataAPI` for unlisted services**: Pass any valid OData URL directly to `ODataAPI(url)` to access BCB APIs not yet wrapped. |
| 79 | +- **All network calls** use either `requests` (SGS, currency) or `httpx` (OData). The OData metadata fetch happens lazily on first `BaseODataAPI` instantiation. |
| 80 | +- **`@mark.flaky`**: flaky tests use the `flaky` library with `max_runs` retries to handle transient API failures. |
0 commit comments