Python client for the ASPIRE Virtual Clinic REST API — multi-turn conversations with LLM-based simulated patient agents.
Project description
virtual-clinic
Python client for the ASPIRE Virtual Clinic REST API — multi-turn conversations with LLM-based simulated patient agents powered by Synthea-generated electronic health records.
Installation
pip install virtual-clinic
Or install from source (for development):
# From the repo root
cd packages/client
uv pip install -e .
Quick Start
from virtual_clinic import VirtualClinic
client = VirtualClinic(
base_url="https://virtual-clinic-api.vercel.app",
token="your-jwt-token", # provided by workshop organizers
)
# 1. List available patients (requires admin token)
patients = client.patients.list(page=1, limit=10)
for p in patients.data:
print(f"{p.first} {p.last} — {p.gender}, born {p.birth_date}")
print(f"Page {patients.pagination.page} of {patients.pagination.total_pages}")
# 2. Inspect a patient's full EHR
detail = client.patients.get(patients.data[0].id)
print(f"Active conditions: {detail.summary.active_conditions}")
print(f"Active medications: {detail.summary.active_medications}")
print(f"Allergies: {detail.summary.allergies}")
# 3. Start a diagnostic conversation
convo = client.conversations.create(
patient_id=patients.data[0].id,
task_type="diagnosis",
)
print(f"Conversation {convo.id} started with {convo.patient_name}")
# 4. Interview the simulated patient
reply = client.conversations.send_message(
convo.id,
content="Hello, what brings you in today?",
)
print(f"Patient: {reply.content}")
# Continue the conversation...
reply = client.conversations.send_message(
convo.id,
content="How long have you been experiencing these symptoms?",
)
print(f"Patient: {reply.content}")
# 5. Review the full conversation history
history = client.conversations.get(convo.id)
for msg in history.messages:
print(f"[{msg.role}] {msg.content[:80]}...")
# 6. Clean up
client.close()
Context Manager
The client supports the context manager protocol for automatic cleanup:
with VirtualClinic(base_url="...", token="...") as client:
health = client.health()
print(health.status, health.database)
API Reference
VirtualClinic(*, base_url, token, timeout=60.0)
The main client. All parameters are keyword-only.
| Parameter | Type | Default | Description |
|---|---|---|---|
base_url |
str |
"https://virtual-clinic-api.vercel.app" |
API base URL |
token |
str |
(required) | JWT bearer token |
timeout |
float |
60.0 |
Request timeout in seconds |
Health
client.health() -> HealthStatus
Check API health (public, no auth required).
Patients (admin token required)
client.patients.list(*, page=1, limit=20) -> PaginatedResponse[PatientSummary]
client.patients.get(patient_id: str) -> PatientDetail
Conversations
client.conversations.list(*, page=1, limit=20, patient_id=None, task_type=None) -> PaginatedResponse[ConversationSummary]
client.conversations.create(*, patient_id, task_type, metadata=None) -> CreatedConversation
client.conversations.get(conversation_id: str) -> ConversationWithMessages
client.conversations.send_message(conversation_id: str, *, content: str) -> AssistantMessage
Task Types
| Value | Description |
|---|---|
"diagnosis" |
Interview the patient to propose a diagnosis |
"treatment" |
Interview the patient to predict the treatment plan |
"event" |
Interview the patient to estimate probability of a clinical event |
Error Handling
All API errors raise typed exceptions:
from virtual_clinic import (
VirtualClinicError, # base class — catch-all
AuthenticationError, # 401 — invalid or missing token
ForbiddenError, # 403 — insufficient permissions
NotFoundError, # 404 — resource not found
ValidationError, # 400 — invalid request
ServerError, # 5xx — server error
ConnectionError, # network/DNS/timeout failure
)
try:
patient = client.patients.get("nonexistent-uuid")
except NotFoundError as e:
print(f"Patient not found: {e.message}")
except AuthenticationError:
print("Check your token!")
except VirtualClinicError as e:
print(f"Something went wrong: {e.message}")
API error exceptions expose these attributes:
| Attribute | Type | Description |
|---|---|---|
status_code |
int |
HTTP status code |
message |
str |
Error message from the API |
details |
dict | None |
Validation error details (if any) |
body |
dict | None |
Raw response body |
Models
All API responses are returned as Pydantic v2 models with full type hints. This gives you autocomplete in IDEs, runtime validation, and easy serialization:
# Convert to dict
patient_dict = patient.model_dump()
# Convert to JSON string
patient_json = patient.model_dump_json()
# Access fields with autocomplete
print(detail.summary.active_conditions)
print(detail.patient.first, detail.patient.last)
Requirements
- Python >= 3.10
httpx >= 0.27pydantic >= 2.0
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 virtual_clinic-0.1.0.tar.gz.
File metadata
- Download URL: virtual_clinic-0.1.0.tar.gz
- Upload date:
- Size: 8.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a5377fb4a31a834ee2e1e20c419c82c1c4e87c63947371ed2510c55a8b2f5e5
|
|
| MD5 |
e5fa721f7cc358d502c3e94283938c34
|
|
| BLAKE2b-256 |
e76f75ac7291a8745e3399e319a25079fc05962ad173ddde80cab7d426dc7685
|
Provenance
The following attestation bundles were made for virtual_clinic-0.1.0.tar.gz:
Publisher:
publish.yml on mims-harvard/medical-ai-workshop
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
virtual_clinic-0.1.0.tar.gz -
Subject digest:
0a5377fb4a31a834ee2e1e20c419c82c1c4e87c63947371ed2510c55a8b2f5e5 - Sigstore transparency entry: 953235190
- Sigstore integration time:
-
Permalink:
mims-harvard/medical-ai-workshop@42c66106cb395175764d0ae27fd9a85a6e22da0b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/mims-harvard
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@42c66106cb395175764d0ae27fd9a85a6e22da0b -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file virtual_clinic-0.1.0-py3-none-any.whl.
File metadata
- Download URL: virtual_clinic-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
471ff7ba57a44b8045284e14afbf709ad54d003be618651d3776792f346ad935
|
|
| MD5 |
99019830d7b01fcb63a162e6f2c907cc
|
|
| BLAKE2b-256 |
da2f41205c97d857e8814182af76d373374db38bcc9270de2be4da7774efcffe
|
Provenance
The following attestation bundles were made for virtual_clinic-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on mims-harvard/medical-ai-workshop
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
virtual_clinic-0.1.0-py3-none-any.whl -
Subject digest:
471ff7ba57a44b8045284e14afbf709ad54d003be618651d3776792f346ad935 - Sigstore transparency entry: 953235191
- Sigstore integration time:
-
Permalink:
mims-harvard/medical-ai-workshop@42c66106cb395175764d0ae27fd9a85a6e22da0b -
Branch / Tag:
refs/heads/main - Owner: https://github.com/mims-harvard
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@42c66106cb395175764d0ae27fd9a85a6e22da0b -
Trigger Event:
workflow_dispatch
-
Statement type: