Local FHIR-based Personal Health Record
Project description
medgemma-vault
A local-first personal health record backed by FHIR R4 and SQLite. All data stays on your machine in a single database file at ~/.medgemma/vault.db. Records are stored as validated FHIR R4 JSON, making them portable and interoperable with any FHIR-compatible system.
The optional medgemma AI engine can be added for natural-language queries against your records, but the vault works standalone as a pure health record store.
Features
- FHIR R4 compliant — every record is a validated FHIR resource (Patient, Observation, MedicationStatement, Condition, AllergyIntolerance, Procedure, DocumentReference)
- SQLite storage — single-file database with WAL mode, no server required
- CLI interface — manage records, import data, and export FHIR Bundles from the terminal
- Apple Health import — stream-parse large
export.xmlfiles with memory-efficientiterparse - CSV and JSON import — bring in data from spreadsheets or existing FHIR Bundles
- Document storage — attach images, PDFs, and other files as FHIR DocumentReferences with content-hash deduplication
- FHIR Bundle export — export your entire record as a standard FHIR Bundle JSON
- Optional AI queries — ask natural-language questions about your health data (requires medgemma)
Requirements
- Python 3.10+
Installation
# Clone the repository
git clone git@github.com:chibokocl/medgemma-vault.git
cd medgemma-vault
# Install in editable mode
pip install -e .
# Or with AI features (requires medgemma)
pip install -e ".[ai]"
# Or with development dependencies
pip install -e ".[dev]"
Quick start
1. Initialise the vault
Create the database and set up your patient profile:
medgemma-vault init --given-name Jane --family-name Doe
You can also provide optional flags:
medgemma-vault init \
--given-name Jane \
--family-name Doe \
--birth-date 1990-05-15 \
--gender female
If you omit --given-name or --family-name, the CLI will prompt you interactively.
2. Add records
# Vital signs
medgemma-vault add vitals --type weight --value 68.5
medgemma-vault add vitals --type heart_rate --value 72
medgemma-vault add vitals --type blood_pressure_systolic --value 120
medgemma-vault add vitals --type blood_glucose --value 95 --date 2024-06-01
# Medications
medgemma-vault add medication --name Metformin --dosage "500mg twice daily"
medgemma-vault add medication --name Aspirin --dosage "100mg daily" --status active
# Conditions
medgemma-vault add condition --name "Type 2 Diabetes"
medgemma-vault add condition --name "Seasonal allergies" --status active
# Clinical notes
medgemma-vault add note --text "Felt dizzy after lunch, resolved after 30 minutes"
# Documents (images, PDFs, etc.)
medgemma-vault add document chest-xray.png -d "Chest X-ray 2024"
medgemma-vault add document blood-work.pdf -d "Annual blood work results"
3. View records
# List all records
medgemma-vault list
# Filter by resource type
medgemma-vault list --type Observation
medgemma-vault list --type MedicationStatement
# Filter by date
medgemma-vault list --since 2024-01-01
# Limit results
medgemma-vault list --type Observation --limit 10
# Show full FHIR JSON for a specific record
medgemma-vault show <resource-id>
# Summary counts
medgemma-vault stats
4. Export
# Print FHIR Bundle to stdout
medgemma-vault export
# Save to file
medgemma-vault export -o my-records.json
The export produces a standard FHIR Bundle of type collection containing all resources in your vault.
Importing data
Apple Health
Export your data from the Apple Health app on iPhone (Health > profile picture > Export All Health Data), then:
medgemma-vault import apple-health export.xml
The adapter uses streaming XML parsing (iterparse with elem.clear()) so it can handle large export files without loading them entirely into memory. Units are automatically converted (e.g. lbs to kg, Fahrenheit to Celsius).
Supported Apple Health types:
| Apple Health Identifier | Mapped vital type |
|---|---|
HKQuantityTypeIdentifierBodyMass |
weight |
HKQuantityTypeIdentifierHeight |
height |
HKQuantityTypeIdentifierHeartRate |
heart_rate |
HKQuantityTypeIdentifierBloodPressureSystolic |
blood_pressure_systolic |
HKQuantityTypeIdentifierBloodPressureDiastolic |
blood_pressure_diastolic |
HKQuantityTypeIdentifierBodyTemperature |
temperature |
HKQuantityTypeIdentifierRespiratoryRate |
respiratory_rate |
HKQuantityTypeIdentifierOxygenSaturation |
oxygen_saturation |
HKQuantityTypeIdentifierBodyMassIndex |
bmi |
HKQuantityTypeIdentifierBloodGlucose |
blood_glucose |
CSV
medgemma-vault import csv vitals.csv
Expected CSV format:
type,value,date
weight,72.5,2024-06-01
heart_rate,68,2024-06-02
blood_glucose,95,2024-06-03
The type column must be one of the supported vital types (see table below). Rows with unknown types or invalid values are skipped.
JSON / FHIR Bundle
medgemma-vault import json records.json
Accepts either a single FHIR resource or a FHIR Bundle. Resources are validated against the FHIR R4B schema before being stored.
Supported vital types
These can be used with medgemma-vault add vitals --type <type>:
| Type | LOINC Code | Display | Unit |
|---|---|---|---|
weight |
29463-7 | Body weight | kg |
height |
8302-2 | Body height | cm |
heart_rate |
8867-4 | Heart rate | beats/minute |
blood_pressure_systolic |
8480-6 | Systolic blood pressure | mmHg |
blood_pressure_diastolic |
8462-4 | Diastolic blood pressure | mmHg |
temperature |
8310-5 | Body temperature | C |
respiratory_rate |
9279-1 | Respiratory rate | breaths/minute |
oxygen_saturation |
2708-6 | Oxygen saturation | % |
bmi |
39156-5 | Body mass index | kg/m2 |
blood_glucose |
2339-0 | Glucose [Mass/volume] in Blood | mg/dL |
CLI reference
| Command | Description |
|---|---|
medgemma-vault init |
Create DB and patient profile (prompts for name) |
medgemma-vault add vitals --type <type> --value <n> |
Add a vital sign observation |
medgemma-vault add medication --name <name> [--dosage <text>] |
Add a medication statement |
medgemma-vault add condition --name <name> |
Add a condition |
medgemma-vault add note --text <text> |
Add a clinical note |
medgemma-vault add document <file> [-d <description>] |
Upload an image or PDF |
medgemma-vault import apple-health <file> |
Import Apple Health export.xml |
medgemma-vault import csv <file> |
Import observations from CSV |
medgemma-vault import json <file> |
Import FHIR JSON or Bundle |
medgemma-vault list [--type <type>] [--since <date>] |
List records |
medgemma-vault show <id> |
Show full FHIR JSON for a record |
medgemma-vault export [-o <file>] |
Export all records as a FHIR Bundle |
medgemma-vault stats |
Show summary counts by resource type |
medgemma-vault ask "<question>" |
AI query (requires medgemma) |
Architecture
medgemma-vault/
├── pyproject.toml
├── src/medgemma_vault/
│ ├── __init__.py
│ ├── __main__.py # python -m medgemma_vault
│ ├── _version.py # 0.1.0
│ ├── config.py # paths, LOINC codes, Apple Health mapping
│ ├── db.py # SQLite connection, schema, low-level CRUD
│ ├── store.py # VaultStore facade (high-level CRUD)
│ ├── models.py # FHIR R4B resource builders + validation
│ ├── cli.py # Click CLI commands
│ ├── agent.py # optional medgemma AI integration
│ └── adapters/
│ ├── base.py # BaseAdapter ABC
│ ├── apple_health.py # Apple Health XML adapter
│ ├── csv_import.py # CSV adapter
│ ├── json_import.py # JSON/FHIR Bundle adapter
│ └── document.py # image/PDF adapter
└── tests/
├── conftest.py
├── test_config.py
├── test_db.py
├── test_models.py
├── test_store.py
├── test_cli.py
└── test_adapters/
├── test_apple_health.py
├── test_csv_import.py
└── test_document.py
Data flow
CLI / Adapter
│
▼
VaultStore (store.py — high-level facade)
│
├──► models.py (build + validate FHIR resources)
│
▼
db.py (SQLite CRUD)
│
▼
~/.medgemma/vault.db
Database schema
The SQLite database has three tables:
resources — one row per FHIR resource, data stored as JSON:
id(TEXT PK) — FHIR resource ID (UUID)resource_type(TEXT) — e.g. "Patient", "Observation"patient_id(TEXT) — reference to the owning Patientrecorded_date(TEXT) — effective/recorded date for filteringsource(TEXT) — origin of the record ("manual", "apple_health", "csv", etc.)data(TEXT) — full FHIR resource as JSONcreated_at,updated_at(TEXT) — ISO timestamps
documents — file metadata linked to DocumentReference resources:
id(TEXT PK)resource_id(TEXT FK) — referencesresources.idfile_path,mime_type,sha256,file_size
meta — key-value store for schema version tracking.
Storage locations
| Path | Description |
|---|---|
~/.medgemma/vault.db |
SQLite database |
~/.medgemma/documents/ |
Uploaded document files (content-hash prefixed) |
Override the base directory by setting the MEDGEMMA_VAULT_DIR environment variable:
export MEDGEMMA_VAULT_DIR=/path/to/custom/vault
Development
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
# Run a specific test file
pytest tests/test_store.py -v
# Run with output
pytest tests/ -v -s
Dependencies
| Package | Version | Purpose |
|---|---|---|
| fhir.resources | >=7.0.0 | FHIR R4B data models and validation |
| click | >=8.0 | CLI framework |
| medgemma | optional | AI-powered health queries ([ai] extra) |
| pytest | >=7.0 | Testing ([dev] extra) |
| pytest-mock | any | Test mocking ([dev] extra) |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file medgemma_vault-0.1.0.tar.gz.
File metadata
- Download URL: medgemma_vault-0.1.0.tar.gz
- Upload date:
- Size: 19.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ec048d7ddc7ddbcaf0ee661af2ee5e7b510e04484c36fa67a999b1f3b39faa3
|
|
| MD5 |
ac8eeade46c686d2f65858c4a1125992
|
|
| BLAKE2b-256 |
39fad7570afeee8b13c08eee560149c133c0ec700512b144b10a7a61eae69b00
|
File details
Details for the file medgemma_vault-0.1.0-py3-none-any.whl.
File metadata
- Download URL: medgemma_vault-0.1.0-py3-none-any.whl
- Upload date:
- Size: 21.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d424f27f5f5ba974a819e257a8b6e4b74cd3552d46512914838fb295a9f8a33
|
|
| MD5 |
38cae75f3459b32bf233656332e4a4d8
|
|
| BLAKE2b-256 |
8ecc44e2ede819b6475d76d02b1dc3834e406463bc0cf9b683be6c26200c28aa
|