Skip to main content

Convert wearable health data from vendor schemas to Open mHealth schemas

Project description

omh-shim

Convert wearable health data from vendor schemas to Open mHealth schemas.

Status

v1.0 — initial public release. Public API is stable; converter coverage will continue to expand.

Install

pip install git+https://github.com/jupyterhealth/omh-shim.git@v1.0.1

Usage

Timestamp-based data types (one reading at a known instant):

from omh_shim import convert

omh_record = convert(
    source="ow_normalized",
    data_type="heart_rate",
    sample={
        "timestamp": "2026-04-09T08:30:00+00:00",
        "type": "heart_rate",
        "value": 72,
        "unit": "bpm",
        "source": {"source_name": "Oura Ring", "device_model": "Oura Gen 3"},
    },
)

Daily data types (step_count, physical_activity, sleep_duration, oxygen_saturation) aggregate over a calendar day, so they REQUIRE an explicit timezone so the day boundaries reflect the user's local day rather than silently assuming UTC:

from datetime import UTC
from zoneinfo import ZoneInfo

# UTC-anchored upstream data
convert(
    source="oura_raw",
    data_type="step_count",
    sample={"day": "2026-04-09", "steps": 8432},
    tz=UTC,
)

# User's local timezone
convert(
    source="oura_raw",
    data_type="step_count",
    sample={"day": "2026-04-09", "steps": 8432},
    tz=ZoneInfo("America/Los_Angeles"),
)

Every conversion returns the full IEEE 1752.1 data-point envelope — {"header": ..., "body": ...} — with UUID, schema_id components, creation timestamp, modality, and external_datasheets auto-populated from the sample's source metadata (a nested source dict, or the device implied by source for raw feeds like oura_raw):

convert(
    source="oura_raw",
    data_type="heart_rate",
    sample={"bpm": 72, "source": "rest", "timestamp": "2026-04-09T03:15:00+00:00"},
)
# Returns:
# {
#   "header": {
#     "uuid": "...",
#     "schema_id": {"namespace": "omh", "name": "heart-rate", "version": "2.0"},
#     "source_creation_date_time": "...",
#     "modality": "sensed",
#     "external_datasheets": [{"datasheet_type": "manufacturer", "datasheet_reference": "Oura Ring"}]
#   },
#   "body": {
#     "heart_rate": {"value": 72.0, "unit": "beats/min"},
#     "effective_time_frame": {"date_time": "2026-04-09T03:15:00Z"}
#   }
# }

convert raises ConversionError for unknown (source, data_type) pairs, invalid sample shapes, naive (timezone-less) datetimes, or a missing tz for daily data types. It raises ValidationError if the converter output fails schema validation.

Supported sources and data types

source data_type values
oura_raw heart_rate, heart_rate_variability, oxygen_saturation, step_count, sleep_duration, sleep_episode, physical_activity
ow_normalized heart_rate, heart_rate_variability, oxygen_saturation, step_count, sleep_duration, sleep_episode, physical_activity

Note: heart_rate_variability targets the local placeholder schema local:heart-rate-variability:1.0 (Open mHealth has not published a canonical HRV schema as of 2026-04). The local: namespace is deliberate — downstream consumers should not assume OMH-standard interoperability for HRV records.

Served schemas without a converter

omh-shim also vendors clinical OMH body schemas — blood pressure, blood glucose, body temperature, body weight, forced expiratory volume in 1 second (FEV1), forced vital capacity (FVC), respiratory rate, and RR interval — that have no convert() converter. They exist so consumers can serve and validate OMH bodies offline from a single pinned source:

from omh_shim import known_ids, load_schema

"omh:blood-pressure:4.0" in known_ids()    # True
schema = load_schema("omh:blood-glucose:4.0")  # vendored JSON schema, all $refs resolvable offline

These are tracked as SERVED_NO_CONVERTER in tests/test_schema_coverage.py (the authoritative list) and refreshed alongside the converter schemas by tools/refresh_schemas.py.

Adding a new source

See docs/adding-a-source.md for a step-by-step guide to adding a new device source (converter functions, test fixtures, documentation).

Mapping references

Credits

omh_shim/sources/oura_raw.py ports converter mapping logic with permission from dicristea/oura-clinical-workbench. See AUTHORS.md.

License

MIT. 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

omh_shim-1.3.0.tar.gz (37.4 kB view details)

Uploaded Source

Built Distribution

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

omh_shim-1.3.0-py3-none-any.whl (55.3 kB view details)

Uploaded Python 3

File details

Details for the file omh_shim-1.3.0.tar.gz.

File metadata

  • Download URL: omh_shim-1.3.0.tar.gz
  • Upload date:
  • Size: 37.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for omh_shim-1.3.0.tar.gz
Algorithm Hash digest
SHA256 2577736c4f7c61299ba2cef8df74e6ecf1868abf1e9f46e2a4b48b19fd8317f0
MD5 1f1e101c3fbf6b3aecdbc0118cac5a65
BLAKE2b-256 785654dcca25e4a723a961ba1b54ee6b9b26f3ddb3b29d97c14def9113e1e06f

See more details on using hashes here.

Provenance

The following attestation bundles were made for omh_shim-1.3.0.tar.gz:

Publisher: release.yaml on jupyterhealth/omh-shim

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

File details

Details for the file omh_shim-1.3.0-py3-none-any.whl.

File metadata

  • Download URL: omh_shim-1.3.0-py3-none-any.whl
  • Upload date:
  • Size: 55.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for omh_shim-1.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 03b83ba1f7231882d9fd89d6d971ec94ac97eb877024f0ff11fe6627e71fb76f
MD5 86be3d46efa28369869158089b4894af
BLAKE2b-256 6e5695eeb31688a902183922e82717a0b91da0712802b65ab0466636a3cc69e5

See more details on using hashes here.

Provenance

The following attestation bundles were made for omh_shim-1.3.0-py3-none-any.whl:

Publisher: release.yaml on jupyterhealth/omh-shim

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