FHIR Client for Python
fhirpy is an asynchronous and synchronous FHIR client for Python 3. This library provides a high-level API for performing CRUD operations and complex searches over FHIR resources. It is actively maintained by beda.software, with version 2.2.0 released on October 7, 2025, and generally follows a regular release cadence.
Warnings
- gotcha Always explicitly specify the `fhir_version` when initializing `FHIRClient` (e.g., '4.0.0'). The FHIR standard evolves, and specifying the correct version ensures compatibility with your FHIR server and prevents unexpected behavior due to differing FHIR specifications.
- gotcha Choose between `AsyncFHIRClient` and `SyncFHIRClient` based on your application's architecture. Mixing async and sync calls or using the wrong client type in an async/sync context can lead to unexpected blocking behavior or errors.
- gotcha When fetching resources, `fetch()` and `fetch_all()` methods do not return included resources. If you need to retrieve all included resources as well, use the `fetch_raw()` method.
- breaking While not directly a `fhirpy` change, the `fhir.resources` library (often used with `fhirpy` for data models) removed the `resource_type` attribute from its base FHIR class in version 7, in favor of a `get_resource_type()` method. This might affect code directly accessing `resource_type` on `fhir.resources` objects.
Install
-
pip install fhirpy -
pip install git+https://github.com/beda-software/fhir-py.git
Imports
- AsyncFHIRClient
from fhirpy import AsyncFHIRClient
- SyncFHIRClient
from fhirpy import SyncFHIRClient
- FHIRResource
from fhirpy.base.resource import FHIRResource
Quickstart
import asyncio
import os
from fhirpy import AsyncFHIRClient, SyncFHIRClient
# Replace with your FHIR server URL
FHIR_SERVER_URL = os.environ.get('FHIR_SERVER_URL', 'http://hapi.fhir.org/baseR4')
# --- Async Client Example ---
async def async_example():
async_client = AsyncFHIRClient(FHIR_SERVER_URL, fhir_version='4.0.0')
# Create a Patient resource
patient = await async_client.resource('Patient', **{
'resourceType': 'Patient',
'gender': 'female',
'name': [{'family': 'Doe', 'given': ['Jane']}]
})
await patient.save()
print(f"Async: Created Patient with ID: {patient.id}")
# Read the Patient resource
read_patient = await async_client.resources('Patient').get(id=patient.id)
print(f"Async: Read Patient: {read_patient.serialize()['name'][0]['given'][0]} {read_patient.serialize()['name'][0]['family']}")
# Search for all Patients
patients_search = async_client.resources('Patient').search(gender='female')
all_patients = await patients_search.fetch_all()
print(f"Async: Found {len(all_patients)} female patients.")
# Delete the created Patient
await read_patient.delete()
print(f"Async: Deleted Patient with ID: {patient.id}")
# --- Sync Client Example ---
def sync_example():
sync_client = SyncFHIRClient(FHIR_SERVER_URL, fhir_version='4.0.0')
# Create a Patient resource
patient = sync_client.resource('Patient', **{
'resourceType': 'Patient',
'gender': 'male',
'name': [{'family': 'Smith', 'given': ['John']}]
})
patient.save()
print(f"Sync: Created Patient with ID: {patient.id}")
# Read the Patient resource
read_patient = sync_client.resources('Patient').get(id=patient.id)
print(f"Sync: Read Patient: {read_patient.serialize()['name'][0]['given'][0]} {read_patient.serialize()['name'][0]['family']}")
# Search for all Patients
patients_search = sync_client.resources('Patient').search(gender='male')
all_patients = patients_search.fetch_all()
print(f"Sync: Found {len(all_patients)} male patients.")
# Delete the created Patient
read_patient.delete()
print(f"Sync: Deleted Patient with ID: {patient.id}")
if __name__ == '__main__':
print("Running Async Example...")
asyncio.run(async_example())
print("\nRunning Sync Example...")
sync_example()