Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kynasmith.dev/llms.txt

Use this file to discover all available pages before exploring further.

Python SDK

Use the Python SDK for server-side integrations, local video replay, and local camera workflows. If you are still evaluating the product, start with the guided guest Workbench demo or the public catalog. This page is the integration path once you are ready to run your own backend workflow.

Step 1: Install

pip install kynasmith
Requires Python 3.12 or newer. Install the media extra for local pose detection: pip install "kynasmith[media]".

Step 2: Initialize the client

from kynasmith import KynasmithClient

client = KynasmithClient(
    api_key="ks_key_123:secret_123",
)
The SDK infers your project from the API key.

Step 3: Create and release a MoveSpec

Define a MoveSpec using YAML that describes the movement you want to detect, then validate it, version it, and release it:
from kynasmith.models import MoveSpecCreate, MoveSpecDraftUpdate

# Create a new MoveSpec
movespec = client.movespecs.create(
    MoveSpecCreate(name="Squat counter")
)

# Update the draft with a valid MoveSpec YAML definition
client.movespecs.update_draft(
    movespec.movespec_id,
    MoveSpecDraftUpdate(yaml_source="""
name: squat
version: "1.0"
detection:
  type: repetition
  movement:
    name: squat
    phases:
      - name: standing
        criteria:
          - joint: knee
            angle_min: 160
            angle_max: 180
      - name: bottom
        criteria:
          - joint: knee
            angle_min: 60
            angle_max: 100
    sequence:
      - standing
      - bottom
      - standing
"""),
)

# Validate the draft
validation = client.movespecs.validate_draft(movespec.movespec_id)
assert validation.ok is True

# Snapshot to an immutable version and release it
version = client.movespecs.create_version(movespec.movespec_id)
client.movespecs.release_version(
    movespec.movespec_id,
    version.movespec_version_id,
)
See MoveSpec for the full YAML authoring guide.

Step 4: Replay a video

from kynasmith.models import DetectionSessionCreate

result = client.process_video(
    DetectionSessionCreate(
        movespec_version_id=version.movespec_version_id,
        mode="replay",
    ),
    video_path="squat-demo.mp4",
)

print(f"Accepted frames: {result.accepted_frames_total}")
print(f"Completed events: {result.completed_event_counts}")
Replace squat-demo.mp4 with the path to your own video file. If you are working inside this repo, the deterministic squat replay fixture lives at activities_golden_set/videos/squat.mp4.
Raw video stays local. The SDK extracts pose landmarks with MediaPipe and sends only pose frames to Kynasmith.

Step 5: Run a live camera session

live_result = client.start_camera(
    DetectionSessionCreate(
        movespec_version_id=version.movespec_version_id,
        mode="live",
    ),
    camera_index=0,
    max_frames=300,
)
start_camera() captures up to max_frames camera frames, finalizes the session, and returns the result.

Manual session control

Use the lower-level session helpers when you need full control over realtime flow:
session = client.detection.create_session(
    DetectionSessionCreate(
        movespec_version_id=version.movespec_version_id,
        mode="live",
    )
)

with client.detection.connect_session(session) as realtime:
    for event in realtime.iter_events():
        print(event.type)

Separate credential fields

client = KynasmithClient(
    api_key_id="key_123",
    api_key_secret="secret_123",
)

Service account authentication

client = KynasmithClient(
    service_account_id="svc_123",
    service_account_secret="svc_secret_123",
)

Pre-minted access token

client = KynasmithClient(
    access_token="ks_at_...",
)
When using a static access token, you are responsible for refresh and rotation.

Explicit project ID

When your credential is scoped to multiple projects, pass project_id in request payloads:
result = client.process_video(
    DetectionSessionCreate(
        project_id="proj_456",
        movespec_version_id=version.movespec_version_id,
        mode="replay",
    ),
    video_path="squat-demo.mp4",
)

Typed errors

The Python SDK raises typed exceptions for structured error handling:
  • AuthError — authentication failures (invalid or expired credentials)
  • AuthorizationError — permission or scope errors
  • CompatibilityError — SDK version is not compatible (update your SDK)
  • SessionStateError — session lifecycle violations
  • ValidationError — request or MoveSpec validation failures
  • RateLimitError — rate limit exceeded (HTTP 429)

Limitations

  • Synchronous only: The SDK is fully synchronous. In async frameworks, wrap SDK calls with asyncio.to_thread() to avoid blocking the event loop:
    import asyncio
    
    result = await asyncio.to_thread(
        client.process_video,
        DetectionSessionCreate(
            movespec_version_id=version.movespec_version_id,
            mode="replay",
        ),
        "squat-demo.mp4",
    )
    
  • First-run model download: The first detector run downloads the default MediaPipe .task model (~100 MB) into the local cache. Pass model_path to use a pre-downloaded model.

Environment notes

  • Python 3.12 or newer required
  • Default install includes mediapipe and opencv-python-headless
  • Tested compatibility line: mediapipe==0.10.32
  • Default model asset: pose_landmarker_full/float16/1/pose_landmarker_full.task