parsimony-bls
US Bureau of Labor Statistics connector — CPI, PPI, employment (CES/CPS/QCEW), unemployment (LAUS), JOLTS, ECI, productivity, import/export prices, and more, as numeric time series.
Part of the parsimony-connectors monorepo. Distributed standalone on PyPI as parsimony-bls.
Connectors
| Name | Kind | Description |
|---|---|---|
bls_fetch |
connector | Fetch observations for any series_id via the BLS Public Data API. Reaches the entire universe by id. |
enumerate_bls_surveys |
enumerator | Tier-1 feed: one row per BLS survey (program). |
enumerate_bls_series |
connector | Tier-2 feed: one row per series in one survey, from its authoritative .series flat file. |
bls_surveys_search |
connector | Discover surveys and read their dimension manifests. |
bls_series_search |
connector | Search one survey's series (literal title query= and/or exact filter=). |
Why two tiers
BLS's full universe is far too large to embed — the per-survey .series flat
files total ~15.6 GB (tens of millions of series; the injury/illness demographic
microdata surveys alone are ~12 GB). So discovery is two-tier, mirroring
parsimony-sdmx (survey ≈ SDMX dataflow; a survey's dimension code tables ≈ a
DSD's codelists; a BLS series_id ≈ a composed series key):
- Tier 1 —
bls_surveys(always built, complete): one entity per survey, with a compactdimensionsmanifest (each dimension's codes + labels) for the surveys that have a series catalog. - Tier 2 —
bls_series_<survey>(built for the headline surveys, lazy-buildable for any indexable survey): one entity per series with a resolved title and per-dimension columns for exactfilter=(and label fields for discovery).
Every series stays fetchable by id via bls_fetch regardless of catalog
coverage — the boundary is discovery, not access. The GB-scale microdata tail is
reachable by constructing an id from the tier-1 manifest and fetching it.
Note on dimension labels. Each series carries its dimension codes plus a resolved label. For most surveys every label resolves (CU/CE/JT/SM = 100%), but a few have irregular code-table naming where some codes fall back to the raw code (e.g. LA ≈ 60%, WP ≈ 70%). Literal title
query=andbls_fetchare unaffected; exactfilter=on those dimensions still matches the stored code.
Install
pip install parsimony-bls
Pulls in a compatible parsimony and curl_cffi automatically. curl_cffi is a
hard dependency: the bulk flat-file host (download.bls.gov) is Akamai
bot-managed and only a real Chrome TLS handshake passes — the data API host
(api.bls.gov) uses plain HTTPS.
Configuration
No key required. An optional registrationkey raises the daily quota (25 → 500
queries/day) and request size; set it via the BLS_API_KEY environment variable
or bind it: load(api_key=...).
bls_surveys_search / bls_series_search read published catalog snapshots
(default root hf://parsimony-dev/bls). Override with PARSIMONY_BLS_CATALOG_URL
or catalog_root= at call time; missing snapshots are built on demand from the
live flat files and cached in an LRU.
Quick start
from parsimony_bls import CONNECTORS
# 1. find the survey + read its dimension manifest
surveys = CONNECTORS["bls_surveys_search"](query="consumer price index")
# 2. search that survey's series — query ranks titles; filter= pins exact codes
hits = CONNECTORS["bls_series_search"](
survey="CU",
query="gasoline all types",
filter={"item_code": "SETB01"}, # from the surveys_search dimensions manifest
)
series_id = hits.raw.iloc[0]["series_id"] # e.g. "CUUR0000SETB01"
# 3. fetch observations (years optional — defaults to recent window within BLS cap)
result = CONNECTORS["bls_fetch"](series_id=series_id)
print(result.raw.head())
For multi-plugin composition (autoloads everything installed):
from parsimony import discover
connectors = discover.load_all()
Catalog building
scripts/build_catalog.py builds tier-2 series catalogs for the headline surveys,
collects their dimension manifests, then builds the tier-1 surveys catalog with
those manifests attached:
# headline allowlist → local + remote, per-namespace subdirs
uv run python packages/bls/scripts/build_catalog.py \
--save-root /tmp/parsimony-catalogs/bls --push-root hf://parsimony-dev/bls
# one survey only
uv run python packages/bls/scripts/build_catalog.py --survey CU --save-root /tmp/bls
Provider
- Homepage: https://www.bls.gov
- API docs: https://www.bls.gov/developers/
- Bulk flat files: https://download.bls.gov/pub/time.series/
License
See LICENSE.
Metadata
Release files for parsimony-bls 0.0.2
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 | |
|---|---|---|---|---|
| parsimony_bls-0.0.2.tar.gz | 26.1 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| parsimony_bls-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 56.7 kB
Release files / parsimony_bls-0.0.2.tar.gz
| Download URL | parsimony_bls-0.0.2.tar.gz |
|---|---|
| Size | 26.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
52ca3229253637a1407df69c8ecc8e966927b0f8450f0e2d3e917cd9b7cf8b7a
|
|
BLAKE2b-256 checksum How to use checksums |
9c42d9de2632f16232b0917b70e134e64e2d707ec02c30d4cbb4d78378abb1fc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.
Transparency logRelease files / parsimony_bls-0.0.2-py3-none-any.whl
| Download URL | parsimony_bls-0.0.2-py3-none-any.whl |
|---|---|
| Size | 30.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7417d38feb2888ad973dbbc4aad28cd95729498b6862771e36fcabb109740b79
|
|
BLAKE2b-256 checksum How to use checksums |
b07a864c8f9b70869b841efdf4e1c73884595e4c1f554600855c30e651211c22
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.
Transparency logSecurity for parsimony-bls 0.0.2
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for parsimony_bls-0.0.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.
Transparency logA 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.