Skip to main content
The Olira Python SDK (olira on PyPI) is the supported way to send health logs, manage patients, run historical data ingestion jobs, mint patient tokens, and read patient state from your backend. Method-by-method reference with parameters, responses, REST equivalents, and examples lives under the category groups in the sidebar. For bulk backfill workflows (JSONL upload, job confirmation, replay), see the historical backfill guide.

Installation

pip install olira
Requires Python 3.11+. The package ships py.typed for type checkers.

Authentication

Use an API key with the OAuth scopes required for each operation (see Authentication). Set OLIRA_API_KEY or pass api_key= explicitly.
ScopeUsed for
sdk:event-loglog, log_batch, log_fhir
api:manage-patientsPatient CRUD, batch create, and cohort management
sdk:patient-tokenget_patient_token
sdk:state-readStable data, event modules, views, logs, events, memories, log query builder
sdk:historical-ingestHistorical ingestion jobs (create_ingestion_job, confirm_ingestion_job, etc.)

Base URL

The default HTTP origin is https://app-api.prod.olira.ai/app-api. Override base_url= on init() or on OliraClient / AsyncOliraClient only when your integration uses a custom gateway or another non-default endpoint.

Module singleton: init, flush

Most examples use the module-level singleton:
import olira

olira.init(api_key="YOUR_API_KEY")
# … olira.log(...), olira.create_patient(...), etc.
olira.flush()  # optional: block until queued logs are sent

olira.init(...)

ParameterTypeDefaultDescription
api_keystr | Noneenv OLIRA_API_KEYSecret key; required after env fallback
service_namestr | NoneNoneIncluded in log context
base_urlstrhttps://app-api.prod.olira.ai/app-apiHTTP origin; override when required
batch_sizeint50Background batch size
flush_intervalfloat1.5Seconds between background flushes
max_queue_sizeint10000Max queued events
timeoutfloat5.0HTTP timeout (seconds)
max_retriesint3Retries for transient failures
on_errorstr | Callable"drop"Queue behavior on send failure ("drop" or callback)
async_flushboolTrueWhen True, background worker batches log(); when False, each batch sends synchronously
Raises OliraError if no API key is available.

olira.flush()

Blocks until queued logs are flushed (or fails after worker policy). Raises OliraError if init() was never called.

OliraClient (sync, dependency injection)

Use when you need multiple keys, explicit lifecycle, or tests:
from olira import OliraClient

client = OliraClient(api_key="YOUR_API_KEY")
try:
    client.log(log_type=..., patient_id="...", payload={})
    patient = client.create_patient(email="a@b.com")
finally:
    client.close()
Constructor accepts the same tuning knobs as init() (batch_size, flush_interval, on_error, async_flush, etc.). Methods mirror module-level functions (log, log_batch, patients, token, state-read).

AsyncOliraClient

Async variant with identical method names, prefixed with async/await:
from olira import AsyncOliraClient, OliraLogType

async def main():
    async with AsyncOliraClient(api_key="YOUR_API_KEY") as client:
        await client.log(
            log_type=OliraLogType.SYMPTOM_REPORT,
            patient_id="...",
            payload={},
        )
        await client.flush()
        # await client.create_patient(...)  # etc.

# asyncio.run(main())
Differences from sync: no on_error / async_flush on the constructor; you must enter async with (or equivalent) before calling API methods, otherwise ValidationError is raised. Use await client.aclose() if not using a context manager.

Error hierarchy

ExceptionMeaning
OliraErrorBase class; configuration errors (e.g. missing init)
AuthErrorHTTP 401 / 403
ValidationErrorHTTP 400 / 404 / 422 or client-side validation (e.g. PII in patient_id, payload too large)
RateLimitErrorHTTP 429; attribute retry_after (seconds)
ServerErrorHTTP 409 or 5xx after retries; attribute status_code when applicable
NetworkErrorConnection / timeout after retries

Models and helpers (overview)

Full field lists for request/response types appear next to each method in the sidebar reference.
SymbolRole
OliraLogTypeEnum of catalog log types; see the log types catalog for payloads
OliraTraceobject_type + object_id for correlating logs
LogSpecDataclass for log_batch() rows (log_type, patient_id, payload, trace, timestamp, idempotency_key, metadata)
EsasItem, LabResultItem, PerformingLab, TimePeriodOptional typed helpers for structured payloads (e.g. labs, ESAS)
ExternalIdentifier, CreatePatientRequest, UpdatePatientRequestPatient APIs
BatchResult, BatchErrorBatch log and batch patient outcomes
Patient, PatientListResult, PatientBatchResult, PatientTokenResponses
State-read modelsStableDataResult, EventStateModuleSummary, ViewMeta, ViewBlocksListResult, ViewResult, ViewBlockResult, LogsResult, EventsResult, MemoriesResult, etc.
LogQueryResultResult of LogQuery.execute(). Iterable (for row in result), indexable (result[0]), len(result), .as_logs() → list[LogEntry] for no-projection queries. Fields: count, rows, patient_id, organization_id.
LogQuery / AsyncLogQueryFluent builder returned by client.logs(patient_id) / client.population_logs(patient_ids). Chain filter/projection/aggregation methods and call a terminal (.execute(), .count(), .single(), .maybe_single()).
F(field)Expression helper for .or_() / .and_() sub-conditions: F("payload.score").gt(6) returns a condition dict the builder understands.
Ingestion modelsIngestRecord, IngestLogSpec, IngestionJob, IngestionJobListResult, IngestionErrorSummary

Examples

Runnable scripts in the examples/ directory of the SDK repo:
FileWhat it covers
00_quickstart.pyinit(), create a patient, log an event, flush
01_patient_management.pyFull patient lifecycle
02_event_logging.pylog(), log_batch(), traces, idempotency
03_fhir_ingestion.pylog_fhir() with Condition, MedicationRequest, Appointment; error handling
04_historical_ingestion.pyFile upload, polling, confirm/cancel flow
05_logs_only_workflow.pyHistorical ingestion when patients already exist in the org
06_read_patient_state.pyStable data, event modules, views, logs, memories
07_patient_token.pyMint token, MCP Bearer forwarding, refresh helper
06 and 07 require a patient with data: run 00 or 02 first and use the printed patient id.

FHIR ingestion (log_fhir)

Use log_fhir() (scope sdk:event-log, POST /v1/fhir/resource) to submit a single FHIR R4 resource. Olira maps it through the same FHIR absorber used by Epic/Cerner integrations. Full parameters, examples, and error cases are under Logs → Log FHIR resource in the sidebar.
FHIR resourceTypeOlira event type(s)
Observationvitals_measurement, lab_results, genomic_variant, clinical_measurement, functional_class, clinical_finding, social_determinants, treatment_response_assessment
Patientdemographics
Appointment, Encountercare_encounter
Conditioncondition
MedicationRequest, MedicationStatement, MedicationAdministrationmedication_list_update
AllergyIntoleranceallergy_intolerance
CarePlanclinical_plan_item, treatment_phase
CareTeamcare_team
DiagnosticReportlab_results, imaging_result, procedure_result, unstructured_report
DocumentReferenceclinical_note, unstructured_report
Procedureprocedure
Immunizationimmunization
FamilyMemberHistoryfamily_history
Goalcare_goal
Coverageinsurance
RelatedPersonemergency_contact
Not supported (zero events): QuestionnaireResponse, ImagingStudy, ServiceRequest, Task, AdverseEvent, Device, EpisodeOfCare, ClinicalImpression, MolecularSequence, standalone Binary. Support for additional FHIR resource types is added continuously. Single-resource limit: Each log_fhir() call accepts one FHIR resource. Linked resources in the same payload are not resolved together (for example, lab Observations referenced from a DiagnosticReport). Use historical ingestion or an EHR integration for multi-resource imports.

Cohorts

Cohorts are named patient groups scoped to your organization. Use them to assign summary types to a defined set of patients without touching individual records. Method-by-method reference lives under Cohorts in the sidebar; all methods require the api:manage-patients scope.

Version

Import __version__ from olira, or check the package metadata on PyPI for the release number.