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 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-arm64Quickstart (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:
lib_pathargument inShenaiSDK(...)SHENAI_SDK_LIBenvironment variable (file or directory)SHENAI_SDK_DIRenvironment variable (directory)shenai_sdk/lib/(packaged alongside the module)ctypes.util.find_library("ShenaiSDK")
export SHENAI_SDK_LIB=/path/to/libShenaiSDK.soInitialization 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 towidth * 3timestamp_ns: optional, default0
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()