Skip to main content

Reflex custom component wrapping @tryvital/vital-link and integrating the Junction (Vital) health data SDK

Project description

CI PyPI Python License: MIT Docs

reflex-junction

A Reflex custom component for integrating Junction (Vital) health data into your application. Connect wearables and health platforms (Oura, Fitbit, Apple Health, Garmin, etc.) with a few lines of Python.

Features

  • Health Data Summaries — Sleep, activity, workouts, body composition, meals, profile
  • Vitals Timeseries — Heart rate, HRV, SpO2, glucose, blood pressure, respiratory rate, steps, calories
  • Lab Testing — Test panels, orders, biomarker results with range indicators
  • Link Widget — React component wrapping @tryvital/vital-link for provider connection UI
  • Webhooks — Svix signature verification, typed event models, event routing
  • Introspection — Resource status, historical pull tracking, provider listing
  • Chart-Ready — Computed vars formatted for rx.recharts (line, bar, composed charts)
  • Visual Demo — 9-page demo app with sidebar nav, dark theme, and real data visualizations
  • Typed Models — Python dataclasses for all data types (no dict[str, Any])
  • Multi-region — US and EU sandbox/production environments

Installation

pip install reflex-junction

Or with your preferred package manager:

uv add reflex-junction
poetry add reflex-junction

Quick Start

1. Get an API key

Sign up at tryvital.io and grab your API key from the dashboard.

2. Wrap your app

import os
import reflex as rx
import reflex_junction as junction

app = rx.App()

junction.wrap_app(
    app,
    api_key=os.environ["JUNCTION_API_KEY"],
    environment="sandbox",  # or "production"
    register_user_state=True,
)

3. Use Junction state in your pages

def health_dashboard() -> rx.Component:
    return rx.container(
        rx.heading("Health Dashboard"),
        rx.text(f"Connected: {junction.JunctionState.has_connections}"),
        # Sleep scores chart
        rx.recharts.line_chart(
            rx.recharts.line(data_key="score"),
            rx.recharts.x_axis(data_key="date"),
            data=junction.JunctionUser.chart_sleep_scores,
        ),
        # Heart rate timeseries
        rx.recharts.line_chart(
            rx.recharts.line(data_key="bpm", stroke="#ef4444"),
            rx.recharts.x_axis(data_key="timestamp"),
            data=junction.JunctionUser.chart_heartrate,
        ),
    )

4. Add the Link widget

from reflex_junction import junction_link_button

def connect_page() -> rx.Component:
    return rx.container(
        junction_link_button(
            "Connect a Provider",
            link_token=junction.JunctionState.link_token,
            env="sandbox",
            on_success=junction.JunctionState.get_connected_providers,
        ),
    )

Data Types

Health Summaries (Phase 1)

Model Description Key Fields
SleepSummary Sleep sessions score, duration, stages, HR, HRV
ActivitySummary Daily activity steps, calories, distance, intensity
WorkoutSummary Workout sessions sport, duration, calories, HR
BodyMeasurement Body composition weight, BMI, fat%, muscle%
ProfileData User profile height, birth_date, gender
MealSummary Nutrition entries calories, protein, carbs, fat

Vitals Timeseries (Phase 2)

Method Data Key Unit
fetch_heartrate() bpm bpm
fetch_hrv() hrv ms
fetch_blood_oxygen() SpO2 %
fetch_glucose() glucose mg/dL
fetch_blood_pressure() systolic/diastolic mmHg
fetch_steps_timeseries() steps steps
fetch_calories_timeseries() calories kcal
fetch_respiratory_rate() rate breaths/min
fetch_vital(metric, ...) Generic escape hatch for 50+ metrics

Lab Testing (Phase 5)

Model Description
LabTest Test panel with markers
LabOrder Placed order with status
BiomarkerResult Result with range indicators

Webhook Events (Phase 4)

Model Prefix Example
ConnectionEvent connection.* Provider connected/disconnected
DataEvent historical.*, daily.* New health data available
WebhookEvent Base class Any event type

Webhook Support

junction.wrap_app(
    app,
    api_key=os.environ["JUNCTION_API_KEY"],
    register_webhooks=True,
    webhook_secret=os.environ["JUNCTION_WEBHOOK_SECRET"],
    webhook_prefix="/junction",  # POST /junction/webhooks
)

Webhooks use Svix signature verification. Invalid signatures are rejected with 401.

Running the Demo

The repo includes a 9-page demo app in junction_demo/.

uv sync --dev
cd junction_demo
export JUNCTION_API_KEY=sk_us_...
uv run reflex init
uv run reflex run

Pages: Dashboard, Sleep, Activity, Workouts, Body, Vitals, Labs, Providers, Settings.

Environment Options

Environment Description
sandbox US sandbox (default)
production US production
sandbox_eu EU sandbox
production_eu EU production

API Reference

State Classes

Class Description
JunctionState Core state — user creation, provider management, Link tokens
JunctionUser Extended state — health data, vitals, labs, introspection

Components

Component Description
JunctionLink / junction_link Declarative VitalLink button (requires public key)
JunctionLinkButton / junction_link_button Token-based Link widget (uses useVitalLink hook)

Functions

Function Description
wrap_app(app, api_key, ...) One-line app integration with optional webhooks
junction_provider(*children, api_key, ...) Component wrapper for page-level integration
on_load(handlers) Wrap page on_load handlers to wait for Junction init
register_on_auth_change_handler(handler) Register handler to fire after Junction initializes
create_webhook_router(prefix, secret) Create a standalone FastAPI webhook router
register_webhook_api(app, secret, prefix) Register webhook endpoint on a Reflex app

See the full documentation for detailed guides.

Contributing

task install          # Install dev dependencies + pre-commit
task test             # Run lint + typecheck + pytest
task run              # Run the demo app
task run-docs         # Serve docs locally at localhost:9000

License

MIT — Copyright (c) 2025 Syntropy Health

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

reflex_junction-0.2.0.tar.gz (181.3 kB view details)

Uploaded Source

Built Distribution

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

reflex_junction-0.2.0-py3-none-any.whl (20.6 kB view details)

Uploaded Python 3

File details

Details for the file reflex_junction-0.2.0.tar.gz.

File metadata

  • Download URL: reflex_junction-0.2.0.tar.gz
  • Upload date:
  • Size: 181.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.14 {"installer":{"name":"uv","version":"0.9.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for reflex_junction-0.2.0.tar.gz
Algorithm Hash digest
SHA256 210dc312ce48dfe3cb5d869dd6af4efa94c0387da598e77a1c1da633d67f91d0
MD5 4482f0252fe55d5b8be50da664f04a29
BLAKE2b-256 84c1a117c1487e364de242d495f05015e22a63ecbf6c765f19891d20a80423f2

See more details on using hashes here.

File details

Details for the file reflex_junction-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: reflex_junction-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 20.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.14 {"installer":{"name":"uv","version":"0.9.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for reflex_junction-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9edd632c9b6824fd5609f2ecf597e8bee40f905bcd01b570d9fb609b8ca02cbf
MD5 872563c2e61b9b4b9ddd8879f9d0178a
BLAKE2b-256 f7271846fa4e437bd577d642519e18b92dc30b94095a98e9c55d4272c752dc40

See more details on using hashes here.

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