Skip to article frontmatterSkip to article content

System Architecture

JupyterHealth System Architecture

JupyterHealth is a modular ecosystem of interconnected components that enable patients to collect, control, and share their health data with researchers or clinicians. Users of JupyterHealth might include researchers or clinicians (or even patients) looking to combine patient-generated data with clinical data. This document explains the architecture of each component and how they work together to support patient-centered health data exchange.

System Overview

The JupyterHealth ecosystem enables patients to share health data from personal medical devices with research studies through consent-based access control.

High-Level Data Flow

Key Points:

Component Architecture

1. CommonHealth Android App

Purpose: Patient-facing mobile application for collecting health data from personal medical devices and uploading to JupyterHealth Exchange

Role in System:

CommonHealth serves as a data collection and consent management client for patients:

  1. Device Integration: Connects to personal health devices and manufacturer APIs (glucose meters, continuous glucose monitors, fitness trackers, smart rings) as well as FHIR based APIs for clinical and insurance data

  2. Data Standardization: Normalizes device data to Open mHealth (IEEE 1752) format

  3. FHIR Compatibility: Packages standardized data as FHIR Observations for upload to JHE

  4. Consent Management: Patient interface for enrolling in studies and managing data sharing consent

  5. Secure Communication: Encrypted uploads to JHE via REST API

Data Flow Example:

Device Data → OMH Format → FHIR Observation → JupyterHealth Exchange

Note: CommonHealth is developed by The Commons Project Foundation. For technical integration details, contact The Commons Project.

2. JupyterHealth Exchange (Backend API)

Technology: Django, Django REST Framework, PostgreSQL

Purpose: Central data exchange hub managing patient data, consent, and research access

Key Responsibilities:

Architecture Layers:

Core Models:

Key Features:

API Endpoints:

Admin API:

FHIR API:

3. Jupyter-SMART-on-FHIR Extension

Technology: Python, Jupyter, OAuth 2.0

Purpose: Enable researchers to authenticate with JHE from Jupyter notebooks

Key Responsibilities:

Workflow:

:class: dark:hidden

```{mermaid}
%%{init: {'theme':'default'}}%%
sequenceDiagram
    participant R as Researcher
    participant J as Jupyter Notebook
    participant JHE as JupyterHealth Exchange
    participant OAuth as OAuth Provider

    R->>J: Start SMART on FHIR auth
    J->>OAuth: Redirect to authorization endpoint
    OAuth->>R: Login prompt
    R->>OAuth: Authenticate
    OAuth->>J: Authorization code
    J->>OAuth: Exchange code for token
    OAuth->>J: Access token
    J->>JHE: FHIR API request with token
    JHE->>J: Return consented data
```
:class: hidden dark:block

```{mermaid}
%%{init: {'theme':'dark'}}%%
sequenceDiagram
    participant R as Researcher
    participant J as Jupyter Notebook
    participant JHE as JupyterHealth Exchange
    participant OAuth as OAuth Provider

    R->>J: Start SMART on FHIR auth
    J->>OAuth: Redirect to authorization endpoint
    OAuth->>R: Login prompt
    R->>OAuth: Authenticate
    OAuth->>J: Authorization code
    J->>OAuth: Exchange code for token
    OAuth->>J: Access token
    J->>JHE: FHIR API request with token
    JHE->>J: Return consented data
```

Configuration:

Use Cases:

Deployment Architecture

Local Development Deployment

For local development and testing, JupyterHealth Exchange can be run using Django’s built-in development server:

Setup Steps:

  1. Set up Python environment (Python >= 3.10)

  2. Install dependencies: pipenv sync (or pip install -r requirements.txt)

  3. Create PostgreSQL database

  4. Copy dot_env_example.txt to .env and update database credentials

  5. Load environment: pipenv shell

  6. Run migrations: python manage.py migrate

  7. Seed database: python manage.py seed

  8. Start server: python manage.py runserver

  9. Access at http://localhost:8000 with credentials mary@example.com / Jhe1234!

Note: The Django development server should only be used for local development, not production deployments.

Production Deployment (Fly.io)

The current JupyterHealth Exchange production deployment runs on Fly.io:

Infrastructure Details:

ComponentTechnologyConfiguration
PlatformFly.ioPrimary region: Newark (ewr)
ApplicationDocker containerGunicorn with 2 workers, WhiteNoise for static files
ComputeFly.io VM1GB RAM, 1 shared vCPU
DatabaseFly PostgresManaged PostgreSQL with automated backups
HTTPSFly ProxyAutomatic TLS certificates, forced HTTPS
ScalingAuto-scalingMin 1 machine, auto-stop/start on traffic
DeploymentGitHub ActionsAutomated deploy on push to main branch

Deployment Workflow:

  1. Code pushed to GitHub main branch

  2. GitHub Actions workflow triggered

  3. .env file created from GitHub repository secrets

  4. Docker image built with embedded .env file

  5. Image deployed to Fly.io

  6. Database migrations run automatically (python manage.py migrate)

  7. New container started with zero downtime

Environment Configuration:

Alternative Deployment Options:

For self-hosted or enterprise deployments, JHE can be deployed to:

The Dockerfile and gunicorn configuration support any container runtime or cloud platform.

Component Dependencies

Technology Stack Summary

ComponentLanguageFrameworkDatabaseKey Libraries
CommonHealth (PHR-Android)KotlinAndroid SDKRoom + SQLCipherHAPI FHIR, AppAuth
JupyterHealth ExchangePythonDjango 5.2PostgreSQLfhir.resources, DRF
Jupyter ExtensionPythonJupyterN/Arequests-oauthlib

External Dependencies

FHIR Libraries:

OAuth/Authentication:

Database:

Standards Compliance:

Interoperability Standards

FHIR (Fast Healthcare Interoperability Resources)

JupyterHealth uses FHIR as the primary data exchange format:

FHIR Version:

FHIR Resources Implemented in JHE:

JHE focuses specifically on device-generated observations rather than comprehensive EHR data.

Learn More