brasa
A template-driven ETL engine: download, parse, transform and query datasets described by YAML templates. The official templates — brasa-templates — cover Brazilian market and economic data (B3, ANBIMA, CVM, BCB).
Installation
Install from PyPI as brasa-core (the import name and the command are brasa),
then run brasa init to choose a data directory and get the templates:
pip install brasa-core
brasa init
Until 0.4.0 the distribution was called brasa-marketdata; since 0.5.0 it is
brasa-core, and the templates live in brasa-templates instead of the package.
Or directly from GitHub (latest main):
pip install git+https://github.com/wilsonfreitas/brasa.git
With uv:
uv add brasa-core
uv add git+https://github.com/wilsonfreitas/brasa.git
Data directory (brasa init / BRASA_DATA_PATH)
brasa stores everything — raw downloads, parsed parquet, and the metadata DB — under a single brasa home. On a fresh install, configure it once:
brasa init
This suggests a platform default (e.g. ~/.local/share/brasa on Linux),
lets you confirm or type another path, and persists the choice in
~/.config/brasa/config.toml. It also sets up your templates: it clones the
official brasa-templates
repo into <data path>/templates (use --templates <url|path> for a fork or
a folder you already have). Get template updates later with
brasa update-templates. Non-interactive variants:
brasa init --data-path /data/brasa # explicit path, no prompt
brasa init --yes # accept the default, no prompt
The BRASA_DATA_PATH environment variable, when set, always takes
precedence over the config file — useful for CI, containers, tests, and
one-off overrides. Commands that read or write data fail with a clear
error until one of the two is configured; template introspection commands
(list-templates, deps, graph) work without any configuration.
Templates can live in your own template folders too (BRASA_TEMPLATE_PATH
or template_path in the config file). Templates are code — they can run
Python — so only add folders you trust; see
Template folders.
Changelog
Deterministic Download Status Codes
Every download attempt is now classified with a single, unambiguous status code
persisted in the download_trials table:
| Symbol | Name | Trigger |
|---|---|---|
. |
PASSED | Successful download |
F |
FAILED | Expected failure (DownloadException) |
E |
ERROR | Unexpected exception |
S |
SKIPPED | Skipped (cache hit / invalid / duplicated) |
D |
DUPLICATED | Raw folder already exists |
I |
INVALID | Content validation failure |
W |
WARNING | Success with warnings |
DB migration: Existing caches are upgraded automatically on startup.
Legacy downloaded=1 rows become PASSED; downloaded=0 become FAILED.
(The standalone migration script has been removed after being applied; it is
recoverable from git history if ever needed.)
See docs/USER_GUIDE.md for full details.
Import Local Files (import_marketdata / brasa import)
Files with no download URL — a one-off vendor file, a manually-provided upload,
or a corrected file for backfill — can now be imported using the same
validate → gzip → checksum-dedup → parse → store engine as download. Only
the acquisition step changes: bytes are read from disk instead of HTTP.
# Backfill a single date into a template that normally downloads via HTTP
brasa import b3-cotahist-daily --path /data/backfill/COTAHIST_D02012024.TXT --arg refdate=2024-01-02
# Bulk import one file per business day using a date pattern
brasa import my-daily-template --path '/data/prices/%Y-%m-%d.csv' --arg refdate=@2026-06-01:2026-06-30
from brasa import import_marketdata
import_marketdata("b3-cotahist-daily", path="/data/backfill/COTAHIST_D02012024.TXT", refdate="2024-01-02")
See docs/CLI.md, docs/API_REFERENCE.md, and docs/TEMPLATES.md for full details.
Publishing to PyPI
brasa is built with hatchling and published manually
under the distribution name brasa-core (the PyPI name brasa was already
taken by an unrelated project; import brasa is unaffected; until 0.4.0 the
name was brasa-marketdata). The SQL DDL ships inside the package
(brasa/files/sql/); templates do not — they live in brasa-templates.
-
Bump
versioninpyproject.toml. -
Build the wheel and sdist:
uv buildDistributions are written to
dist/. -
(Optional) Verify the wheel ships the SQL files and no templates:
BRASA_BUILD_TEST=1 uv run pytest tests/test_packaging_wheel.py -v
-
(Optional) Smoke-test in a clean environment:
python -m venv /tmp/brasa-smoke /tmp/brasa-smoke/bin/pip install dist/brasa_core-*.whl /tmp/brasa-smoke/bin/brasa --version
-
Publish:
# TestPyPI dry-run first (recommended) uv publish --publish-url https://test.pypi.org/legacy/ --token "$TEST_PYPI_TOKEN" # Production uv publish --token "$UV_PUBLISH_TOKEN"
A PyPI API token can be supplied via
--token, theUV_PUBLISH_TOKENenvironment variable, or~/.pypirc.
Metadata
Release files for brasa-core 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| brasa_core-0.5.0.tar.gz | 154.6 kB | Without provenance | Details for brasa_core-0.5.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| brasa_core-0.5.0-py3-none-any.whl | Python 3 | none | any | Details for brasa_core-0.5.0-py3-none-any.whl |
Total release size: 337.8 kB
Release files / brasa_core-0.5.0.tar.gz
| Download URL | brasa_core-0.5.0.tar.gz |
|---|---|
| Size | 154.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8d0d8df5d9d777edd849f1b9dab2d5d9d5e6f0cd069ea099cb620678559569fb
|
|
BLAKE2b-256 checksum How to use checksums |
f67deb2c4a236b65311ad00fddf6a64cda3326b749a2c38aaacb650348063d61
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / brasa_core-0.5.0-py3-none-any.whl
| Download URL | brasa_core-0.5.0-py3-none-any.whl |
|---|---|
| Size | 183.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1366fc2760dff2439af0362f568b5e1ea3f5452d4319a641b8177bac1fba86fa
|
|
BLAKE2b-256 checksum How to use checksums |
3849bd230ed72877870aca47b37c3758acc4c430fdb24907a1ce8352dd9f9caa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for brasa-core 0.5.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.