Skip to main content

Hub-Equity Python SDK: programmatic access to XBRL / iXBRL financial data (SEC EDGAR + ESEF Europe) via the public REST API.

Project description

hub-equity: Python SDK

Typed Python client for the Hub-Equity financial-data API: machine-readable XBRL / iXBRL from primary filings, SEC EDGAR (US) and ESEF (Europe), normalized into canonical financial concepts, with the provenance preserved.

What sets the data apart, and what this SDK exposes:

  • Source-linked. Every value carries the filing it came from (form_type, filing_date, a viewer URL). You can trace any number back to the filer's document, not a black box that silently rewrites as-filed history.
  • Point-in-time. Query a metric as it was known on a date (get_metric_as_of): filings filed after the cutoff are excluded. No lookahead bias for backtests.
  • XBRL-native. Calculation linkbase (with filer weights and verifier-corrected weights), dimensional structure, and the raw filer-declared facts, not just flattened labels.
  • Restatement-aware. Per-concept deltas across 10-K/A amendments.
  • Cross-issuer, calendar-aligned. compare matches periods by calendar year (Bloomberg / FactSet convention), so Apple (Sep FYE) and a Dec-FYE peer line up.

The SDK is a thin, typed wrapper over the public REST API: it ships no data and no secrets; you bring your own API key. Full API reference: https://docs.hub-equity.com.

Maturity. The data engine and public REST API behind this SDK run in production and power Hub-Equity's own chat. This PyPI package is a newly published client for that API; the surface is stable (SemVer 1.0), but as a distributed package it is fresh, hence the Beta classifier.

Install

pip install hub-equity
# Optional pandas helpers:
pip install 'hub-equity[pandas]'

Python 3.10+. Runtime deps: httpx, pydantic.

Authentication

from hub_equity import HubEquity

# Explicit key
client = HubEquity(api_key="hubq_live_...")

# Or set HUBEQUITY_API_KEY env var (recommended for notebooks)
client = HubEquity()

# Or no key: anonymous freemium access (lower rate limits, premium endpoints gated)
client = HubEquity(api_key="")

Get a key at https://hub-equity.com/settings/api-keys (shown once, store it securely). Set HUBEQUITY_API_URL to point the client at a non-default host (defaults to https://api.hub-equity.com).

Entity arguments accept a ticker (e.g. "AAPL") or a Hub-Equity UUID on every entities/{id}/... method. The one exception is compare, which takes UUIDs only (resolve a ticker via the entity detail endpoint or the web app first).

Quickstart

from hub_equity import HubEquity

with HubEquity() as client:
    rev = client.get_metric_history("AAPL", "REVENUE", years=5)
    print(f"{rev.entity_name}: {rev.hub_label} (CAGR {rev.cagr_pct:.1f}%)")
    for p in rev.points:
        print(f"  FY{p.fiscal_year}: {p.value:,.0f} {p.currency}"
              f"  ({p.yoy_growth_pct:+.1f}% YoY)  ← {p.source.form_type} {p.source.filing_date}")
        # p.source.viewer_url / p.source.external_url -> trace back to the filing

Methods

Area Method Returns
Time-series get_metric_history(entity, code, *, years=5, period_type='FY') MetricHistory: values + YoY + CAGR
Point-in-time get_metric_as_of(entity, code, as_of, *, years=5, period_type='FY') AsOfResponse: series as known on a date
Compare compare(entity_ids, hub_concept_codes, fiscal_year, fiscal_period_type='FY') CompareEntitiesResult: N×M matrix
Calc linkbase get_calculation_sections(filing_id) CalculationSectionsResponse: calc roles
get_calculation_tree(filing_id, link_role) CalculationTree: edges + weights
Dimensions get_entity_dimensions(entity) EntityDimensionsResponse: axes + members
Raw facts get_filing_facts(filing_id, *, section, concept, is_extension, limit, offset) RawFactsResponse
Restatements get_restatement_diff(entity, *, fiscal_year, hub_concept_code, min_diff_pct=0.01, kind) AmendmentDiffResult
Quality get_filing_quality_grade(filing_id) QualityGradeResponse: A-F + 4 drivers
Concepts search_concepts(q, *, taxonomy, category, limit, offset, cursor) ConceptSearchResponse
iter_concepts(q, *, taxonomy, category, page_size=100) generator of ConceptSummary
get_concept(hub_concept_code) ConceptDetail: forward catalog entry (label, description, category, taxonomy scope)

Every method returns a typed pydantic model (autocomplete + validation), with extra="allow" so a newer API never breaks an older SDK.

Point-in-time: no lookahead bias

# What did Apple's FY2022 revenue look like as known on 2023-01-15,
# before any later 10-K/A restated it?
snap = client.get_metric_as_of("AAPL", "REVENUE", as_of="2023-01-15", years=3)
for p in snap.points:
    print(f"FY{p.fiscal_year}: {p.value:,.0f} {p.currency}"
          f"  (from {p.form_type} filed {p.filing_date})")

Compare issuers (calendar-year aligned, premium)

# compare takes UUIDs; resolve tickers first (entity detail endpoint / web app).
matrix = client.compare(
    entity_ids=["<apple-uuid>", "<msft-uuid>"],
    hub_concept_codes=["REVENUE", "NET_INCOME"],
    fiscal_year=2024,
)
for row in matrix.rows:
    cell = row.cells.get("REVENUE")
    if cell:
        print(f"{row.name} ({row.ticker}): {cell.value:,.0f} {cell.currency}"
              f"  [{cell.extraction_method}]")

Audit a number to its filing

# Filing-level quality pre-screen
grade = client.get_filing_quality_grade("<filing-uuid>")
print(grade.letter_grade, grade.overall_score)
for d in grade.drivers:
    print(f"  {d.name}: {d.score:.2f} (w={d.weight})")

# then drill to the raw filer-declared facts (qname, unit, decimals, dimensions).
facts = client.get_filing_facts("<filing-uuid>", concept="Revenue", limit=50)
for f in facts.facts:
    print(f.concept_qname, f.value_numeric, f.unit, f.dimensions)

pandas

import pandas as pd

hist = client.get_metric_history("MSFT", "REVENUE", years=10)
df = pd.DataFrame([p.model_dump() for p in hist.points])
df["source_form"] = [p.source.form_type for p in hist.points]

Reliability

  • Retries 429 (rate limit) + 5xx (server) with exponential backoff (3 retries, base 1 s, cap 10 s); honors Retry-After when present.
  • After exhausting retries on 429, raises RateLimitError (subclass of HubEquityError) with the last retry_after attached.
  • Other 4xx raise HubEquityError immediately (no retries), with .status_code.
from hub_equity import HubEquity, HubEquityError, RateLimitError

with HubEquity() as client:
    try:
        rev = client.get_metric_history("AAPL", "REVENUE")
    except RateLimitError as exc:
        print(f"Rate-limited, retry after {exc.retry_after}s")
    except HubEquityError as exc:
        print(f"{exc.status_code}: {exc}")

Rate limits

Plan Per minute Per day
Free / anon 60 5 000
Pro 300 100 000
Enterprise 1 000 500 000

Bucketed per API key (per JWT user, or per IP for anonymous callers). Premium endpoints (compare, point-in-time) require a Pro/Enterprise key.

Versioning

Semantic versioning. The 1.x surface is stable: no breaking change to an existing method or model without a major bump. Pin a version in production (hub-equity==1.0.0). Response models use extra="allow", so additive API changes ship in minor releases without breaking older SDK installs.

License

Apache-2.0. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hub_equity-1.0.0.tar.gz (25.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hub_equity-1.0.0-py3-none-any.whl (18.8 kB view details)

Uploaded Python 3

File details

Details for the file hub_equity-1.0.0.tar.gz.

File metadata

  • Download URL: hub_equity-1.0.0.tar.gz
  • Upload date:
  • Size: 25.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for hub_equity-1.0.0.tar.gz
Algorithm Hash digest
SHA256 4f4d2bba28d9008cb53154a87485d21b10e1b3a8d065df0acc045dc365157383
MD5 a28a9a88d2195ee3c1c7079aca216e7a
BLAKE2b-256 79c8dabe49b990e00151d7b758a45ef893825bae1bdc0dacd718ed388dad50f3

See more details on using hashes here.

Provenance

The following attestation bundles were made for hub_equity-1.0.0.tar.gz:

Publisher: publish-sdk.yml on GLaine1/Hub-Equity_MVP

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hub_equity-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: hub_equity-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 18.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for hub_equity-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e256d1b272b11ee7939cd1ec78b100147272378f662aef9e8c90b592274a0d60
MD5 1cf42c44093b5f5fcef23d1d5ef42db5
BLAKE2b-256 7a29daa240a87aa8e4de7e246bdc77b7f1972436fccefb57359da8c6d620ffa6

See more details on using hashes here.

Provenance

The following attestation bundles were made for hub_equity-1.0.0-py3-none-any.whl:

Publisher: publish-sdk.yml on GLaine1/Hub-Equity_MVP

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page