Circadify

Camera & Input

Capture vitals in Python from a webcam, a video file, or your own frames, all returning the same VitalSigns.

The Python SDK is a full capture-capable client: it runs MediaPipe face detection and ROI extraction on-device, then sends only the cropped tensor to the server for inference. Raw video never leaves the device. You can feed that pipeline from three interchangeable sources — a webcam, a video file, or your own frames — and every one returns the same VitalSigns result.

Input sources

Pick the source that fits your environment. All three need the camera extra (pip install "circadify[camera]") for on-device MediaPipe; measure_vitals (and check_camera_access) open a camera device, while measure_from_video and measure_from_frames never do.

Open a live webcam, run the readiness gate, then capture. camera_index=0 is the default device.

from circadify import CircadifyClient
 
with CircadifyClient(api_key="ck_test_your_key_here") as client:
    result = client.measure_vitals(camera_index=0)
    print(result.heart_rate, result.confidence)
python
Note

Read the API key from the environment — never hardcode it. Use CircadifyClient(api_key=os.environ["CIRCADIFY_API_KEY"]) with a ck_test_ (sandbox, zero quota) or ck_live_ key.

Camera permissions & availability

measure_vitals and check_camera_access open a camera device, so OS-level permissions apply to the webcam path (the macOS TCC prompt fires on the first of either call). measure_from_video and measure_from_frames never open a camera:

PlatformWhat to expect
macOSThe system TCC dialog prompts for camera access on the first capture. Grant it under System Settings -> Privacy & Security -> Camera.
LinuxThe device must exist at /dev/video0 (or another index) and be readable via v4l. Ensure your user is in the video group.
WindowsCamera access must be enabled under Settings -> Privacy & security -> Camera for desktop apps.

Probe a device before a webcam scan with check_camera_access(camera_index=0), which returns a bool:

import os
from circadify import CircadifyClient
 
client = CircadifyClient(api_key=os.environ["CIRCADIFY_API_KEY"])
 
if client.check_camera_access(camera_index=0):
    result = client.measure_vitals(camera_index=0)
else:
    print("No usable camera — fall back to a video file or frames.")
python
Tip

measure_from_video and measure_from_frames need no camera permission and no camera device — the key advantage of the Python SDK. Use them for headless servers, CI, batch jobs, or any host without a webcam.

If the camera extra is missing, the capture methods raise MissingDependencyError (code MISSING_DEPENDENCY). A camera that exists but cannot be opened raises CameraError (code CAMERA_ERROR).

Frame quality

Whatever the source, the model needs enough good frames. Capture targets ~30 fps and requires MIN_CAPTURE_FRAMES=150 usable frames before it produces a result. Aim for:

  • Even lighting — avoid backlight and harsh shadows on the face.
  • Steady framing — keep the face centered and in shot for the whole capture.
  • Face visible — no occlusions, large turns, or tilts.
  • Minimal motion — hold still; motion blur drops frames.

The on_quality callback receives a QualityState with face_detected, brightness, motion, yaw_deg, pitch_deg, is_good, and reasons — a tuple drawn from no_face, face_out_of_frame, too_dark, too_bright, too_much_motion, face_turned, face_tilted. Use those reasons to coach the subject in real time:

def on_quality(q):
    if not q.is_good:
        print("Adjust:", ", ".join(q.reasons))
 
client = CircadifyClient(api_key=os.environ["CIRCADIFY_API_KEY"], on_quality=on_quality)
python
Caution

If too few usable frames are collected (too much motion or no face detected), capture raises CaptureFailedError (code CAPTURE_FAILED, retryable). The SDK never fabricates vitals — retry with better lighting and framing, or supply more quality frames to measure_from_frames.

Next Steps

  • Face-Glow Overlay — Draw the thermal glow on your frames with render_face_glow.
  • Methods — Full signatures for every capture path.
  • Configuration — Tune callbacks, timeouts, and capture duration.
  • Error Handling — Catch CaptureFailedError, CameraError, and more.