Skip to main content

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(region="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()

A region is one served area: a county (travis), a group of them (sf is San Francisco, San Mateo and Santa Clara), a municipality (boston, cambridge, worcester), or a multi-state corridor (interstates). hb.regions() is the live list — it grows.

region used to be called county, which was wrong for most of those. The old name still works everywhere it did before: county= on every compute call, counties= on compute_batch, and "county" in a saved config. Both go on the wire, so a pinned older client and a current one behave the same.

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. Two are worth knowing, because they are the defaults rather than the widest setting:

  • in_transport="in_transport" drops vehicles that were parked when struck.
  • desk_reports="exclude" drops crashes the driver reported at a police station instead of an officer attending. Only a source that marks the channel has any to drop, which today means Chicago, and excluding them is what makes its rate mean the same thing as another region's. Pass desk_reports="include_all" to count them, and expect that region's numbers to jump.

Validation is client-side, so a filter the installed client predates is rejected locally even when the API supports it. Upgrade the package if a filter you can see in hb.filters() is refused here.

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={
    "region": "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 - 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.
  • Batch results are keyed by region. Until the models are regenerated against a deployed API that emits it, read .county on a BatchItemResult; the server sends both.

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)

Release files for humanbaselines 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for humanbaselines 0.2.0
File Size Uploaded
humanbaselines-0.2.0.tar.gz 25.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for humanbaselines 0.2.0
File Interpreter ABI Platform
humanbaselines-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 46.3 kB

Release files / humanbaselines-0.2.0.tar.gz

Download URL humanbaselines-0.2.0.tar.gz
Size 25.4 kB
Tags Source
SHA-256 checksum
How to use checksums
304c16fc796c6a4dbe8e876da01e8a08c56a37fa2bbf2c337693717995e83d14
BLAKE2b-256 checksum
How to use checksums
9a90c00a2fe0ba135fce53b3734a4fc486ad9533efb1870aa227e1a755c03b7a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 11, 2026.

Transparency log

Release files / humanbaselines-0.2.0-py3-none-any.whl

Download URL humanbaselines-0.2.0-py3-none-any.whl
Size 20.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
faf067cb125b5e2c7f23c00a11cc4713bf65b330b84bc0304a162b880cb963f2
BLAKE2b-256 checksum
How to use checksums
b510c79fb8ad479aee40dada9b527d9dfe6e3b885855b14c4b2d35e0c5829ba1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 11, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page