Skip to main content

Python client for the Human Crash Baselines API.

Project description

humanbaselines

CI PyPI docs

Python client for the Human Crash Baselines API: typed access to human-driver crash-rate baselines by region, route, and filter.

It wraps the /v1 REST API: construct a client with your key, call typed methods, get typed results back (no hand-built JSON, no remembering the auth header).

Install

pip install humanbaselines

Or install the latest from source:

pip install "git+https://github.com/valgorithmic/humanbaselines.git"
# or, from a checkout:
pip install .

Quickstart

from humanbaselines import HumanBaselines

hb = HumanBaselines(api_key="hbk_...")          # or set HUMANBASELINES_API_KEY

# Geofence crash rate (kwargs are validated client-side):
r = hb.compute(county="travis", outcome="police_reported", ego_vehicle=["cars", "light_trucks"])
print(r.rate, r.rate_low, r.rate_high)          # 4.055 4.0 4.1
print(r.N, r.D_miles, len(r.cells))             # 24617.0 6.07e9 1795

# Discover valid filters + defaults at runtime:
for f in hb.filters().modes["geofence"]:
    print(f.id, "→", [o.id for o in f.options], "default:", f.default)

# Which regions / modes are available:
hb.regions()

Filters

Pass filters three ways - keyword args (simplest), a typed Selections model, or a plain dict. All are validated before the request, so a bad value fails fast locally:

from humanbaselines import GeofenceSelections, Outcome

hb.compute(outcome="fatal", road_type=["interstate"])           # kwargs
hb.compute(selections=GeofenceSelections(outcome=Outcome.fatal)) # typed model
hb.compute(selections={"outcome": "fatal"})                      # dict

Omitted filters fall back to the API's defaults (these reproduce the web UI's headline numbers).

Binding a baseline definition

The filter selections are really a methodological definition - what counts as a crash and what you're baselining against. Bind that definition to the client once and every call inherits it; per-call args override individual fields:

hb = HumanBaselines(api_key="hbk_...", config={
    "county": "travis",
    "outcome": "fatal",
    "ego_vehicle": ["cars", "light_trucks"],
})

hb.compute().rate                  # uses the bound definition
hb.compute(weather=["rain"]).rate  # override just one field for this call

hb.config()                        # full effective config (bound + every default)
hb.changes()                       # only the settings that differ from the defaults

config(mode="geofence") and changes(mode="geofence") take an optional mode (each mode exposes different fields). config() is the complete definition a compute call would use; changes() is just your deviations from the defaults.

The bound config is validated when you create the client (unknown fields or bad values raise immediately). It applies to all modes - each compute mode uses the subset of fields it understands (e.g. road_type only affects geofence, ci_method only affects route/depot), so you can keep one definition across modes.

Derive variants immutably, and version definitions as JSON:

strict = hb.with_config(under_reporting="adjusted")   # new client; hb is unchanged

hb.save_config("odd_fatal_cars.json")        # full config snapshot (check into a repo, share, diff)

# Load it back - pass the path straight to the constructor:
hb2 = HumanBaselines(api_key="hbk_...", config="odd_fatal_cars.json")
# (HumanBaselines.from_config(path, api_key=...) is an equivalent, explicit alias.)

Route & depot modes

Available for route/depot-capable regions - travis and ca_az_interstates (check hb.regions()). Route/depot count Class-8 combination trucks, so ego_vehicle defaults to ["combination"] in these modes.

hb.compute_route(segment_ids=[("I-35", 250), ("I-35", 251)], ego_vehicle=["combination"])

hb.compute_depot_route(
    depot_a=(30.25, -97.75),     # (lat, lon)
    depot_b=(30.40, -97.70),
    ci_method="fay_feuer",
)

Errors

Non-2xx responses raise typed exceptions you can catch:

from humanbaselines import AuthenticationError, ValidationError, ServiceUnavailableError

try:
    hb.compute(outcome="fatal")
except AuthenticationError:        # 401 - bad/missing key
    ...
except ValidationError as e:       # 422 - e.errors has the field-level detail
    print(e.errors)
except ServiceUnavailableError:    # 503 - service warming up (auto-retried first)
    ...

All inherit from HumanBaselinesError. The base APIError carries .status_code and .body.

Configuration

arg default notes
api_key $HUMANBASELINES_API_KEY sent as X-API-Key
base_url https://humanbaselines.com proxies /v1/*; use the Cloud Run URL for /health
timeout 30 seconds per request
max_retries 2 exponential backoff on 502/503/504 (handles cold-start warm-up)

HumanBaselines is also a context manager (with HumanBaselines(...) as hb:).

Notes

  • The typed models in _generated.py are generated from the server's OpenAPI schema - the server's Pydantic models are the single source of truth, so the client can't drift from the API. GET /v1/filters is the authoritative runtime source for valid values and defaults.
  • Interactive API docs: the /docs page on the API host.

Development

pip install -e '.[dev]'
pytest -q                                  # mocked tests
HUMANBASELINES_API_KEY=hbk_... pytest -q    # also runs the live smoke test
python -m build                            # build wheel + sdist into dist/

Regenerating models after an API change

src/humanbaselines/_generated.py is generated - never hand-edit it. When the API contract changes, regenerate from the live OpenAPI schema:

python scripts/regenerate_models.py
# point at a different host (e.g. local dev server):
python scripts/regenerate_models.py --url http://localhost:8000

This fetches <host>/openapi.json (default https://humanbaselines.com) and runs datamodel-code-generator. Output is deterministic (no timestamps), so a clean git diff means the client is in sync with the API.

Releases are automated: a version bump in the upstream app dispatches a release here, which tags v<version> and publishes to PyPI via Trusted Publishing.

License

Apache-2.0 © Valgorithmic, Inc. (d.b.a. Valgo)

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

humanbaselines-0.1.2.tar.gz (21.5 kB view details)

Uploaded Source

Built Distribution

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

humanbaselines-0.1.2-py3-none-any.whl (18.2 kB view details)

Uploaded Python 3

File details

Details for the file humanbaselines-0.1.2.tar.gz.

File metadata

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

File hashes

Hashes for humanbaselines-0.1.2.tar.gz
Algorithm Hash digest
SHA256 e61c20789ebe773adc8373f4ed2858ea5845c53d517106e1ba517d95e0ebf338
MD5 2ed864ac98fd36048cf10d0d575d70d3
BLAKE2b-256 b9925ab06424c16894a8046f271769362d1cb72f32f18f8ced6a6b11de09ca87

See more details on using hashes here.

Provenance

The following attestation bundles were made for humanbaselines-0.1.2.tar.gz:

Publisher: release.yml on valgorithmic/humanbaselines

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

File details

Details for the file humanbaselines-0.1.2-py3-none-any.whl.

File metadata

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

File hashes

Hashes for humanbaselines-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6bf031f6ee06f3425ec3f6beb1e5e48e19fdd0014a5acb70ba342a7531b35a3d
MD5 35dd4d44c1fcbc5fb59b7a5ecfa364d4
BLAKE2b-256 7ab214e6ac528758b065c3fd63e70778d9bec3e557d9d43206723f6a358e09f9

See more details on using hashes here.

Provenance

The following attestation bundles were made for humanbaselines-0.1.2-py3-none-any.whl:

Publisher: release.yml on valgorithmic/humanbaselines

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