Healthcare API¶
The Healthcare API is a service that enables secure storage, processing, and machine learning for healthcare data. The HealthcareBase
and HealthcareFHIR
classes in gcp-pilot provide high-level interfaces for interacting with Google Cloud Healthcare API, with a focus on FHIR (Fast Healthcare Interoperability Resources) data.
Installation¶
To use the Healthcare API functionality, you need to install gcp-pilot with the healthcare extra:
Usage¶
Initialization¶
from gcp_pilot.healthcare import HealthcareFHIR
healthcare = HealthcareFHIR() # (1)!
healthcare = HealthcareFHIR(project_id="my-project") # (2)!
healthcare = HealthcareFHIR(location="us-central1") # (3)!
healthcare = HealthcareFHIR(impersonate_account="service-account@project-id.iam.gserviceaccount.com") # (4)!
- Initialize with default credentials
- Initialize with specific project
- Initialize with specific location
- Initialize with service account impersonation
Region Availability
The Healthcare API is only available in specific regions. If you specify a region that is not supported, the API will default to the multi-region "us".
Managing Datasets¶
Listing Datasets¶
datasets = healthcare.list_datasets( # (1)!
project_id="my-project", # (2)!
location="us-central1", # (3)!
)
for dataset in datasets:
print(f"Dataset: {dataset['name']}")
- List all datasets in a project
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Getting a Dataset¶
dataset = healthcare.get_dataset( # (1)!
name="my-dataset",
project_id="my-project", # (2)!
location="us-central1", # (3)!
)
print(f"Dataset: {dataset['name']}")
- Get information about a specific dataset
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Creating a Dataset¶
dataset = healthcare.create_dataset( # (1)!
name="my-dataset",
project_id="my-project", # (2)!
location="us-central1", # (3)!
)
print(f"Dataset created: {dataset['name']}")
- Create a new dataset
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Deleting a Dataset¶
healthcare.delete_dataset( # (1)!
name="my-dataset",
project_id="my-project", # (2)!
location="us-central1", # (3)!
)
- Delete a dataset
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Managing FHIR Stores¶
Listing FHIR Stores¶
stores = healthcare.list_stores( # (1)!
dataset_name="my-dataset",
project_id="my-project", # (2)!
location="us-central1", # (3)!
)
for store in stores:
print(f"Store: {store['name']}")
- List all FHIR stores in a dataset
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Getting a FHIR Store¶
store = healthcare.get_store( # (1)!
name="my-store",
dataset_name="my-dataset",
project_id="my-project", # (2)!
location="us-central1", # (3)!
)
print(f"Store: {store['name']}")
- Get information about a specific FHIR store
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Creating a FHIR Store¶
store = healthcare.create_store( # (1)!
name="my-store",
dataset_name="my-dataset",
labels={"environment": "production"}, # (2)!
enable_upsert=True, # (3)!
notify_pubsub_topic="my-topic", # (4)!
notify_pubsub_full_resource=False, # (5)!
notify_pubsub_deletion=True, # (6)!
export_to_bigquery_dataset="my-bq-dataset", # (7)!
project_id="my-project", # (8)!
location="us-central1", # (9)!
version="R4", # (10)!
)
print(f"Store created: {store['name']}")
- Create a new FHIR store
- Optional: labels to apply to the store
- Optional: if True, enables update-as-create semantics
- Optional: Pub/Sub topic for notifications
- Optional: if True, sends the full resource in notifications
- Optional: if True, sends notifications for deletions
- Optional: BigQuery dataset for streaming exports
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
- Optional: FHIR version, defaults to "R4"
Updating a FHIR Store¶
store = healthcare.update_store( # (1)!
name="my-store",
dataset_name="my-dataset",
labels={"environment": "staging"}, # (2)!
notify_pubsub_topic="my-new-topic", # (3)!
notify_pubsub_full_resource=True, # (4)!
notify_pubsub_deletion=True, # (5)!
export_to_bigquery_dataset="my-new-bq-dataset", # (6)!
project_id="my-project", # (7)!
location="us-central1", # (8)!
)
print(f"Store updated: {store['name']}")
- Update an existing FHIR store
- Optional: new labels to apply to the store
- Optional: new Pub/Sub topic for notifications
- Optional: if True, sends the full resource in notifications
- Optional: if True, sends notifications for deletions
- Optional: new BigQuery dataset for streaming exports
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Deleting a FHIR Store¶
healthcare.delete_store( # (1)!
name="my-store",
dataset_name="my-dataset",
project_id="my-project", # (2)!
location="us-central1", # (3)!
)
- Delete a FHIR store
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Managing FHIR Resources¶
Listing Resources¶
from fhir.resources.patient import Patient
patients = healthcare.list_resources( # (1)!
resource_type=Patient,
store_name="my-store",
dataset_name="my-dataset",
project_id="my-project", # (2)!
location="us-central1", # (3)!
query={"name": "John"}, # (4)!
limit=100, # (5)!
cursor=None, # (6)!
)
if patients:
for patient in patients: # (7)!
print(f"Name: {patient.name[0].given[0]} {patient.name[0].family}")
else:
print("No patients found")
- List all FHIR resources of a specific type in a store
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
- Optional: query parameters to filter resources
- Optional: maximum number of resources to return per page
- Optional: cursor for pagination
- Iterate through all patients
Getting a Resource¶
from fhir.resources.patient import Patient
patient = healthcare.get_resource( # (1)!
resource_id="patient-id",
resource_type=Patient,
store_name="my-store",
dataset_name="my-dataset",
project_id="my-project", # (2)!
location="us-central1", # (3)!
)
print(f"Patient: {patient.id}")
if patient and patient.name and patient.name[0].given and patient.name[0].family: # (4)!
print(f"Name: {patient.name[0].given[0]} {patient.name[0].family}")
- Get a specific FHIR resource
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
- Get the first patient
Creating a Resource¶
from fhir.resources.patient import Patient
patient = Patient.construct(
name=[{"given": ["John"], "family": "Doe"}],
gender="male",
birthDate="1990-01-01",
) # (1)!
created_patient = healthcare.create_resource( # (2)!
resource=patient,
store_name="my-store",
dataset_name="my-dataset",
project_id="my-project", # (3)!
location="us-central1", # (4)!
)
print(f"Patient created: {created_patient.id}")
- Create a Patient resource using the fhir.resources library
- Create a new FHIR resource
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Updating a Resource¶
patient.name[0].family = "Smith" # (1)!
updated_patient = healthcare.update_resource( # (2)!
resource=patient,
store_name="my-store",
dataset_name="my-dataset",
project_id="my-project", # (3)!
location="us-central1", # (4)!
)
print(f"Patient updated: {updated_patient.id}")
- Modify the Patient resource
- Update an existing FHIR resource (full update)
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Patch Updating a Resource¶
patch = [
{"op": "replace", "path": "/birthDate", "value": "1991-01-01"},
{"op": "add", "path": "/telecom/-", "value": {"system": "phone", "value": "555-555-5555"}}
] # (1)!
updated_patient = healthcare.patch_resource( # (2)!
resource_id="patient-id",
resource_type=Patient,
patch=patch,
store_name="my-store",
dataset_name="my-dataset",
project_id="my-project", # (3)!
location="us-central1", # (4)!
)
print(f"Patient patched: {updated_patient.id}")
- Create a JSON patch
- Patch an existing FHIR resource
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Conditional Patch Updating a Resource¶
patch = [
{"op": "replace", "path": "/birthDate", "value": "1992-01-01"}
] # (1)!
updated_patient = healthcare.patch_resource_conditional( # (2)!
resource_type=Patient,
patch=patch,
store_name="my-store",
dataset_name="my-dataset",
query={"identifier": "http://example.org/fhir/ids|12345"}, # (3)!
project_id="my-project", # (4)!
location="us-central1", # (5)!
)
print(f"Patient conditionally patched: {updated_patient.id}")
- Create a JSON patch
- Conditionally patch an existing FHIR resource
- Optional: query to find existing resource
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Upserting a Resource¶
patient = Patient.construct(
id="patient-id",
name=[{"given": ["John"], "family": "Doe"}],
gender="male",
birthDate="1990-01-01",
) # (1)!
patient = healthcare.upsert_resource( # (2)!
resource=patient,
store_name="my-store",
dataset_name="my-dataset",
query={"identifier": "http://example.org/fhir/ids|12345"}, # (3)!
project_id="my-project", # (4)!
location="us-central1", # (5)!
)
print(f"Patient created or updated: {patient.id}")
- Create a Patient resource
- Create or update a FHIR resource (upsert)
- Optional: query to find existing resource
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Deleting a Resource¶
healthcare.delete_resource( # (1)!
resource_id="patient-id",
resource_type=Patient,
store_name="my-store",
dataset_name="my-dataset",
project_id="my-project", # (2)!
location="us-central1", # (3)!
)
- Delete a FHIR resource
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Resource History¶
history = healthcare.get_resource_history( # (1)!
resource_id="patient-id",
resource_type=Patient,
store_name="my-store",
dataset_name="my-dataset",
project_id="my-project", # (2)!
location="us-central1", # (3)!
since="2023-01-01T00:00:00Z", # (4)!
limit=10, # (5)!
)
for version in history: # (6)!
print(f"Version: {version.id}")
if version.name and version.name[0].given and version.name[0].family:
print(f"Name: {version.name[0].given[0]} {version.name[0].family}")
- Get the history of a Patient resource
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
- Optional: only return versions since this timestamp
- Optional: limit the number of versions returned
- Iterate through versions
Validating Resources¶
try: # (1)!
healthcare.validate_resource(
resource=patient, # (2)!
store_name="my-store",
dataset_name="my-dataset",
project_id="my-project", # (3)!
location="us-central1", # (4)!
)
print("Resource is valid")
except exceptions.InvalidInput as e:
print(f"Validation errors: {e}")
- Validate a Patient resource
- The FHIR resource object to validate
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Importing and Exporting Resources¶
Exporting Resources¶
export_info = healthcare.export_resources( # (1)!
output_gcs_uri="gs://my-bucket/fhir-export/",
store_name="my-store",
dataset_name="my-dataset",
project_id="my-project", # (2)!
location="us-central1", # (3)!
resource_names=["Patient", "Observation"], # (4)!
)
print(f"Export operation ID: {export_info['operation_id']}")
operation = healthcare.get_operation(export_info['operation_id']) # (5)!
print(f"Operation status: {operation['metadata']['state']}")
- Export FHIR resources to Google Cloud Storage
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
- Optional: specific resource types to export
- Check the status of the export operation
Importing Resources¶
import_operation = healthcare.import_resources( # (1)!
source_gcs_uri="gs://my-bucket/fhir-import/",
store_name="my-store",
dataset_name="my-dataset",
project_id="my-project", # (2)!
location="us-central1", # (3)!
)
print(f"Import operation: {import_operation['name']}")
- Import FHIR resources from Google Cloud Storage
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Natural Language Processing¶
entities = healthcare.analyze_entities( # (1)!
content="Patient has a history of hypertension and type 2 diabetes.",
use_idc10=True, # (2)!
use_snomed=True, # (3)!
location="us-central1", # (4)!
project_id="my-project", # (5)!
fhir_output=True, # (6)!
)
print(f"Entities: {entities}")
- Analyze clinical text for entities
- Optional: if True, includes ICD-10 codes
- Optional: if True, includes SNOMED CT codes
- Optional: defaults to the default location
- Optional: defaults to the project associated with credentials
- Optional: if True, returns results as FHIR resources
Configuring Search¶
search_config = {
"searchParameters": [
{
"name": "patient-name",
"definition": "Patient.name",
"type": "string"
}
]
} # (1)!
search_config = healthcare.configure_search( # (2)!
config=search_config,
store_name="my-store",
dataset_name="my-dataset",
validate_only=False, # (3)!
project_id="my-project", # (4)!
location="us-central1", # (5)!
)
print(f"Search configuration: {search_config}")
- Define the search configuration
- Configure search parameters for a FHIR store
- Optional: if True, validates the configuration without applying it
- Optional: defaults to the project associated with credentials
- Optional: defaults to the default location
Error Handling¶
The Healthcare classes handle common errors and convert them to more specific exceptions:
from gcp_pilot import exceptions
try:
healthcare.get_dataset(name="non-existent-dataset")
except exceptions.NotFound:
print("Dataset not found")
try:
healthcare.create_dataset(name="existing-dataset") # This assumes exists_ok=False or not provided
except exceptions.AlreadyExists:
print("Dataset already exists")
try:
healthcare.validate_resource(resource=invalid_patient_resource) # (1)!
except exceptions.InvalidInput as e:
print(f"Validation errors: {e}")
- Example: an invalid FHIR resource object
Working with Service Account Impersonation¶
Service account impersonation allows you to act as a service account without having its key file. This is a more secure approach than downloading and storing service account keys.
healthcare = HealthcareFHIR(impersonate_account="service-account@project-id.iam.gserviceaccount.com") # (1)!
datasets = healthcare.list_datasets() # (2)!
- Initialize with service account impersonation
- Now all operations will be performed as the impersonated service account
For more information on service account impersonation, see the Authentication documentation.
Best Practices for Healthcare API
Here are some best practices for working with the Healthcare API:
- Use appropriate regions: Choose a region that complies with your data residency requirements and is close to your users.
- Implement proper access controls: Use IAM to restrict access to healthcare datasets and FHIR stores.
- Enable audit logging: Set up audit logging to track access to sensitive healthcare data.
- Use FHIR validation: Validate resources before storing them to ensure data quality.
- Configure notifications: Set up Pub/Sub notifications for important events like resource creation and deletion.
- Stream to BigQuery: Enable streaming to BigQuery for real-time analytics on healthcare data.
- Use conditional operations: Use conditional operations to avoid race conditions when updating resources.
- Implement proper error handling: Handle errors appropriately, especially for validation and precondition failures.
- Regularly export data: Set up regular exports to Google Cloud Storage for backup and disaster recovery.
- Monitor API usage: Set up monitoring and alerting for API usage to detect and respond to issues quickly.