Every source.
One contract.
Hermes acquires, normalizes, validates and serves structured and unstructured data through one interface. Financial feeds, government portals and files, all speaking the same canonical schema.
10
Built-in connectors
SEC, FRED, IMF, World Bank, GDELT, market data, sanctions
7
Canonical schema domains
economic, market, financial, geopolitical, entity, document, security
3
Dataframe ecosystems
Polars, Arrow and Pandas over one columnar core
1
Shared cache and retry layer
Inherited by every connector from a single base class
Seven stages. One interface.
Every dataset moves through the same pipeline, whatever it started as. Scroll or select a stage. Each one is a single module with a single job.
Source
hermes/connectors/base.py
Declare the source once
Every connector subclasses a single base and inherits caching, retry and provenance. No source gets bespoke plumbing.
- cache
- parquet-backed
- shared across all 10 connectors
- 01Source
Source
hermes/connectors/base.py
Declare the source once
Every connector subclasses a single base and inherits caching, retry and provenance. No source gets bespoke plumbing.
- cache
- parquet-backed
- shared across all 10 connectors
- 02Acquire
Acquire
hermes/api/acquire.py
One call, any source
hr.fetch() routes to the right connector, retries transient failures and returns a Dataset. fetch_raw() bypasses the pipeline when you need the payload untouched.
- retry with backoff
- raw passthrough available
- Dataset return type
- 03Parse
Parse
hermes/parsing
Structures arrive consistent
JSON, CSV, XML and tabular payloads land in a Polars frame with inferred types and the source's own metadata retained.
- json, csv, xml
- polars frame out
- source metadata kept
- 04Normalize
Normalize
hermes/normalization/engine.py
Rules, not rewrites
A composable rule chain maps inconsistent source fields onto versioned canonical schemas. Ask for a report and you get every change it made, per record.
- rule chain
- per-record diff report
- streams or batches
- 05Validate
Validate
hermes/validation
Fail loudly, early
Schemas are registered and versioned. Validation runs against the registry, so a broken contract surfaces at the boundary instead of three layers downstream.
- versioned registry
- typed errors
- runs pre-serve
- 06Store
Store
hermes/storage
Columnar by default
Datasets save to Parquet with a stable on-disk format, so a dataset written today loads identically in every later version.
- parquet
- arrow interchange
- stable format
- 07Serve
Serve
hermes/export
Hand it to your stack
Clean conversion to Polars, Arrow or Pandas, plus export for the formats your warehouse already reads. No wrapper objects in the way.
- polars, arrow, pandas
- warehouse export
- no lock-in
Normalized output
| country | indicator | value | date |
|---|---|---|---|
| USA | NY.GDP.MKTP.CD | 27438.6 | 2024-01-01 |
| DEU | NY.GDP.MKTP.CD | 4523.9 | 2024-01-01 |
| JPN | NY.GDP.MKTP.CD | 4226.8 | 2024-01-01 |
| GBR | NY.GDP.MKTP.CD | 3340.0 | 2024-01-01 |
Entity resolution
Hover a node
The whole call
import hermes as hr
gdp = hr.fetch("world_bank", indicator="NY.GDP.MKTP.CD")
clean = hr.normalize(gdp, report=True)Built for scale. Designed for reliability.
Four capabilities, each a module you can adopt on its own. Nothing here is a wrapper around someone else's product.
Multi-source acquisition
Ten connectors for financial APIs, government portals and local files, all sharing one caching and retry layer.
- SEC · FRED · IMF · World Bank
- GDELT · Binance · Finnhub
- Parquet-backed cache
Schema normalization
Inconsistent source formats are normalized onto versioned canonical schemas, so every dataset speaks the same language.
- 7 schema domains
- Composable rule chain
- Per-record diff report
Entity resolution
Resolve companies, countries and securities across every identifier form they appear under: tickers, CIKs, ISINs, LEIs and plain names.
- Canonical HRM identifiers
- Alias registry
- Cross-source matching
Scalable storage
Parquet-backed caching, Dataset save and export, and clean interchange with the dataframe stack you already run.
- Stable on-disk format
- Polars · Arrow · Pandas
- Rust core
One library, one CLI, one contract.
The same pipeline from Python or from a shell. Nothing to learn twice, and no wrapper object between you and the data.
import hermes as hr
# cached, parsed and schema-validated in one call
gdp = hr.fetch("world_bank", indicator="NY.GDP.MKTP.CD")
report = hr.profile(gdp) # types, nulls, ranges
clean = hr.normalize(gdp, report=True) # canonical economic schemaDocumented end to end.
Ten connector guides, seven schema domains, the full Python API and every CLI command, with runnable examples.
Introduction
Introduction
Hermes provides a unified interface for acquiring, processing and serving data — from financial feeds to public datasets — with validation, normalization and provenance tracking.
pip install hermes-pltStart with the docs.
Install it, point it at a source, and get a validated dataset. That is the whole onboarding.