Skip to content

Commit 49eeadd

Browse files
wilsonfreitasclaude
andcommitted
Migrate from Poetry to uv
Replace Poetry with uv for dependency management and build tooling: - Rewrite pyproject.toml with PEP 621 project table and PEP 735 dependency-groups - Switch build backend from poetry-core to hatchling - Update CI workflows to use astral-sh/setup-uv action - Update CLAUDE.md with uv commands - Delete poetry.lock, requirements.txt, docs/requirements.txt - Add .coverage, coverage.xml, .mypy_cache, *.pyc, .ipynb_checkpoints to .gitignore Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5bd5087 commit 49eeadd

12 files changed

Lines changed: 3565 additions & 3973 deletions

File tree

.github/workflows/lint.yml

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,17 @@ jobs:
99
steps:
1010
- uses: actions/checkout@v4
1111

12-
- name: Set up Python 3.10
13-
uses: actions/setup-python@v5
14-
with:
15-
python-version: "3.10"
12+
- name: Install uv
13+
uses: astral-sh/setup-uv@v5
1614

17-
- name: Install Poetry
18-
run: pip install poetry
15+
- name: Set up Python 3.10
16+
run: uv python install 3.10
1917

2018
- name: Install dependencies
21-
run: poetry install --with dev
19+
run: uv sync --group dev
2220

2321
- name: Check formatting
24-
run: poetry run black --check bcb/ tests/
22+
run: uv run black --check bcb/ tests/
2523

2624
- name: Type check
27-
run: poetry run mypy bcb/
25+
run: uv run mypy bcb/

.github/workflows/sphinx.yml

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,30 @@ jobs:
1212
runs-on: ubuntu-latest
1313
steps:
1414
- uses: actions/checkout@v4
15-
15+
16+
- name: Install uv
17+
uses: astral-sh/setup-uv@v5
18+
1619
- name: Set up Python 3.10
17-
uses: actions/setup-python@v4
18-
with:
19-
python-version: '3.10'
20-
20+
run: uv python install 3.10
21+
2122
- name: Install dependencies
22-
run: |
23-
python -m pip install --upgrade pip
24-
pip install poetry
25-
poetry install --with docs
26-
23+
run: uv sync --group docs
24+
2725
- name: Build docs
2826
run: |
2927
cd docs
30-
poetry run sphinx-build -b html . _build/html
31-
28+
uv run sphinx-build -b html . _build/html
29+
3230
- name: Upload artifacts
3331
uses: actions/upload-artifact@v4
3432
with:
3533
name: html-docs
3634
path: docs/_build/html/
37-
35+
3836
- name: Deploy
3937
uses: peaceiris/actions-gh-pages@v4
4038
if: github.ref == 'refs/heads/main'
4139
with:
4240
github_token: ${{ secrets.GITHUB_TOKEN }}
43-
publish_dir: docs/_build/html
41+
publish_dir: docs/_build/html

.github/workflows/test.yml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,17 @@ jobs:
1212
steps:
1313
- uses: actions/checkout@v4
1414

15-
- name: Set up Python ${{ matrix.python-version }}
16-
uses: actions/setup-python@v5
17-
with:
18-
python-version: ${{ matrix.python-version }}
15+
- name: Install uv
16+
uses: astral-sh/setup-uv@v5
1917

20-
- name: Install Poetry
21-
run: pip install poetry
18+
- name: Set up Python ${{ matrix.python-version }}
19+
run: uv python install ${{ matrix.python-version }}
2220

2321
- name: Install dependencies
24-
run: poetry install --with test,dev
22+
run: uv sync --group test --group dev
2523

2624
- name: Run tests
27-
run: poetry run pytest --cov=bcb --cov-report=xml -m "not integration"
25+
run: uv run pytest --cov=bcb --cov-report=xml -m "not integration"
2826

2927
- name: Upload coverage
3028
uses: codecov/codecov-action@v4

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
venv
22
__pycache__
3-
*.__pycache__
3+
*.pyc
44
.vscode
55
.pytest_cache
6+
.mypy_cache
7+
.coverage
8+
coverage.xml
69
*.code-workspace
710
*.egg-info
11+
.ipynb_checkpoints
812
build
913
dist
1014
*checkpoint.ipynb

CLAUDE.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,41 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
88

99
## Python Environment
1010

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.
11+
**This project uses uv exclusively.** All Python commands must be run via `uv run`. Never invoke `python`, `pytest`, `black`, or any other Python tool directly.
1212

1313
```bash
14-
poetry run python ...
15-
poetry run pytest ...
16-
poetry run black ...
14+
uv run python ...
15+
uv run pytest ...
16+
uv run black ...
1717
```
1818

1919
## Commands
2020

2121
### Setup
2222
```bash
23-
pip install poetry
24-
poetry install # install all dependency groups
25-
poetry install --with test # install with test dependencies only
23+
curl -LsSf https://astral.sh/uv/install.sh | sh # install uv
24+
uv sync # install all dependency groups
25+
uv sync --group test # install with test dependencies only
2626
```
2727

2828
### Running Tests
2929
```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
30+
uv run pytest # run all tests
31+
uv run pytest tests/test_utils.py # run a single test file
32+
uv run pytest tests/test_currency.py::test_currency_id # run a single test
3333
```
3434

3535
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.
3636

3737
### Linting / Formatting
3838
```bash
39-
poetry run pycodestyle bcb/ # lint with pycodestyle
40-
poetry run black bcb/ # format with black
39+
uv run pycodestyle bcb/ # lint with pycodestyle
40+
uv run black bcb/ # format with black
4141
```
4242

4343
### Docs
4444
```bash
45-
cd docs && make html SPHINXBUILD="poetry run sphinx-build"
45+
cd docs && uv run sphinx-build -b html . _build/html
4646
```
4747

4848
## Architecture
@@ -56,9 +56,9 @@ Fetches time series from the BCB's SGS (Sistema Gerenciador de Séries Temporais
5656
- `bcb/sgs/regional_economy.py` — wrapper for regional non-performing loan series with pre-mapped SGS codes by state/region
5757

5858
### `bcb.currency` — Currency Exchange Rates
59-
Scrapes the BCB PTAX website for daily bid/ask exchange rates. Uses `requests` + `lxml` for HTML parsing.
59+
Scrapes the BCB PTAX website for daily bid/ask exchange rates. Uses `httpx` + `lxml` for HTML parsing.
6060

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.
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.
6262

6363
### `bcb.odata` — OData APIs
6464
A generic OData client plus named wrappers for specific BCB OData services (hosted at `olinda.bcb.gov.br`).
@@ -76,5 +76,5 @@ A generic OData client plus named wrappers for specific BCB OData services (host
7676

7777
- **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`.
7878
- **`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.
79+
- **All network calls** use `httpx` (sync) with `follow_redirects=True`. The OData metadata fetch happens lazily on first `BaseODataAPI` instantiation.
8080
- **`@mark.flaky`**: flaky tests use the `flaky` library with `max_runs` retries to handle transient API failures.

bcb/odata/framework.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
from bcb.exceptions import ODataError
1111

12-
1312
# Edm.Boolean
1413
# Edm.Byte
1514
# Edm.Date
@@ -78,12 +77,10 @@ def describe(self) -> None:
7877
props = ", ".join(
7978
[f"{prop.name}<{prop.ftype}>" for prop in self.entity.properties.values()]
8079
)
81-
print(
82-
f"""
80+
print(f"""
8381
EntitySet (Endpoint): {self.name}
8482
EntityType: {self.entity_type}
85-
Properties: {props}"""
86-
)
83+
Properties: {props}""")
8784

8885
def __repr__(self) -> str:
8986
return f"<EntitySet {self.name}>"

docs/requirements.txt

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)