PlatformsLinux (Headless Python, beta)

Linux (Headless Python SDK)

⚠️

This Linux headless Python SDK is in beta. The API and behavior may still change.

This SDK is headless. There is no embedded UI or camera handling. You must capture frames, submit them to the SDK, and provide your own user guidance.

This SDK targets arm64 Linux and provides a Python wrapper over the headless C SDK built with ctypes. It has feature parity with the C API.

Download

See the Customer Portal for SDK downloads.

See system requirements for runtime dependencies.

Install

Unzip the package and add it to PYTHONPATH, or copy shenai_sdk/ into your project:

export PYTHONPATH=/path/to/shenai-sdk-python-linux-arm64

Quickstart (minimal flow)

from shenai_sdk import (
    ShenaiSDK,
    MeasurementPreset,
    PrecisionMode,
    OperatingMode,
    MeasurementState,
)
 
with ShenaiSDK(api_key="YOUR_API_KEY_OR_TOKEN", offline=False) as sdk:
    print("Version:", sdk.get_version())
    sdk.precision_mode = PrecisionMode.STRICT
    sdk.measurement_preset = MeasurementPreset.ONE_MINUTE_ALL_METRICS
 
    sdk.operating_mode = OperatingMode.MEASURE
 
    while True:
        frame = get_next_frame()  # BGR24 bytes
        if frame is None:
            break
 
        sdk.submit_frame(frame, width=1280, height=720)
 
        state = sdk.get_measurement_state()
        if state in (MeasurementState.FINISHED, MeasurementState.FAILED):
            break
 
    results = sdk.get_measurement_results()
    if results:
        print("HR:", results.heart_rate_bpm)
 
sdk.destroy_runtime()

Replace get_next_frame() with your camera or video capture pipeline.

Library discovery

The wrapper searches for libShenaiSDK.so in this order:

  1. lib_path argument in ShenaiSDK(...)
  2. SHENAI_SDK_LIB environment variable (file or directory)
  3. SHENAI_SDK_DIR environment variable (directory)
  4. shenai_sdk/lib/ (packaged alongside the module)
  5. ctypes.util.find_library("ShenaiSDK")
export SHENAI_SDK_LIB=/path/to/libShenaiSDK.so

Initialization and configuration

The Python wrapper mirrors the C API:

from shenai_sdk import (
    ShenaiSDK,
    CustomMeasurementConfig,
    Metric,
    PrecisionMode,
    MeasurementPreset,
)
 
sdk = ShenaiSDK(api_key="YOUR_API_KEY_OR_TOKEN", offline=True)
sdk.precision_mode = PrecisionMode.RELAXED
sdk.measurement_preset = MeasurementPreset.ONE_MINUTE_ALL_METRICS
 
sdk.apply_sdk_config(load_config_json())
print(sdk.get_sdk_config_string())
 
cfg = CustomMeasurementConfig(duration_seconds=30.0, instant_metrics=[Metric.HEART_RATE])
sdk.set_custom_measurement_config(cfg)
cfg = sdk.get_custom_measurement_config()

Frame input

submit_frame accepts BGR frames:

  • pixel_format: PixelFormat.BGR24 (8-bit, 3 channels, B-G-R order)
  • stride_bytes: defaults to width * 3
  • timestamp_ns: optional, default 0
from shenai_sdk import PixelFormat
 
sdk.submit_frame(frame, width=width, height=height, pixel_format=PixelFormat.BGR24)

Operating mode and state

from shenai_sdk import OperatingMode
 
sdk.operating_mode = OperatingMode.POSITIONING
sdk.operating_mode = OperatingMode.MEASURE
 
mode = sdk.operating_mode
state = sdk.get_measurement_state()
progress = sdk.get_progress_percent()
 
face_state = sdk.get_face_state()
bbox = sdk.get_face_bbox()
pose = sdk.get_face_pose()

Realtime metrics and heartbeats

metrics = sdk.get_realtime_metrics(30.0)
hr_10s = sdk.get_heart_rate_10s()
hr_4s = sdk.get_heart_rate_4s()
heartbeats = sdk.get_realtime_heartbeats(30.0)

Results, history, and health risks

results = sdk.get_measurement_results()
results_with_hb = sdk.get_measurement_results_with_heartbeats()
history = sdk.get_measurement_results_history()
 
risks = sdk.get_health_risks()

MeasurementResults includes optional fields for blood pressure confidence, weight, and height in addition to the standard metrics.

Raw data, reports, and FHIR

sdk.recording_enabled = True
signal_quality = sdk.get_current_signal_quality_metric()
bad_signal_seconds = sdk.get_total_bad_signal_seconds()
 
png = sdk.get_face_texture_png()
quality_png = sdk.get_signal_quality_map_png()
meta_png = sdk.get_meta_prediction_image_png()
ppg = sdk.get_full_ppg_signal()
 
sdk.request_measurement_results_pdf_url()
pdf_url = sdk.get_measurement_results_pdf_url()
 
sdk.request_measurement_results_pdf_bytes()
pdf_bytes = sdk.get_measurement_results_pdf_bytes()
 
fhir_json = sdk.get_result_as_fhir_observation()

Metadata and debug helpers

version = sdk.get_version()
initialized = sdk.is_initialized
plan = sdk.get_pricing_plan()
 
trace_id = sdk.get_trace_id()
measurement_id = sdk.get_measurement_id()

Cleanup

Call close() (or use the context manager) to deinitialize, and call destroy_runtime() once after the final deinitialize to tear down the SDK runtime:

sdk.close()
sdk.destroy_runtime()
;