> ## Documentation Index
> Fetch the complete documentation index at: https://docs.olira.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK

> Install and configure the Olira Python SDK: authentication, clients, error handling, models, and cohort management.

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](/send-data/historical-backfill).

## Installation

```bash theme={null}
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](/authentication)). Set `OLIRA_API_KEY` or pass `api_key=` explicitly.

| Scope                   | Used for                                                                          |
| ----------------------- | --------------------------------------------------------------------------------- |
| `sdk:event-log`         | `log`, `log_batch`, `log_fhir`                                                    |
| `api:manage-patients`   | Patient CRUD, batch create, and cohort management                                 |
| `sdk:patient-token`     | `get_patient_token`                                                               |
| `sdk:state-read`        | Stable data, event modules, views, logs, events, memories, log query builder      |
| `sdk:historical-ingest` | Historical 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:

```python theme={null}
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(...)`

| Parameter        | Type              | Default                                 | Description                                                                                  |
| ---------------- | ----------------- | --------------------------------------- | -------------------------------------------------------------------------------------------- |
| `api_key`        | `str \| None`     | env `OLIRA_API_KEY`                     | Secret key; required after env fallback                                                      |
| `service_name`   | `str \| None`     | `None`                                  | Included in log context                                                                      |
| `base_url`       | `str`             | `https://app-api.prod.olira.ai/app-api` | HTTP origin; override when required                                                          |
| `batch_size`     | `int`             | `50`                                    | Background batch size                                                                        |
| `flush_interval` | `float`           | `1.5`                                   | Seconds between background flushes                                                           |
| `max_queue_size` | `int`             | `10000`                                 | Max queued events                                                                            |
| `timeout`        | `float`           | `5.0`                                   | HTTP timeout (seconds)                                                                       |
| `max_retries`    | `int`             | `3`                                     | Retries for transient failures                                                               |
| `on_error`       | `str \| Callable` | `"drop"`                                | Queue behavior on send failure (`"drop"` or callback)                                        |
| `async_flush`    | `bool`            | `True`                                  | When `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:

```python theme={null}
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`:

```python theme={null}
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

| Exception         | Meaning                                                                                      |
| ----------------- | -------------------------------------------------------------------------------------------- |
| `OliraError`      | Base class; configuration errors (e.g. missing `init`)                                       |
| `AuthError`       | HTTP 401 / 403                                                                               |
| `ValidationError` | HTTP 400 / 404 / 422 or client-side validation (e.g. PII in `patient_id`, payload too large) |
| `RateLimitError`  | HTTP 429; attribute `retry_after` (seconds)                                                  |
| `ServerError`     | HTTP 409 or 5xx after retries; attribute `status_code` when applicable                       |
| `NetworkError`    | Connection / timeout after retries                                                           |

## Models and helpers (overview)

Full field lists for request/response types appear next to each method in the sidebar reference.

| Symbol                                                               | Role                                                                                                                                                                                                                       |
| -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OliraLogType`                                                       | Enum of catalog log types; see the [log types catalog](/reference/log-types/symptom-reports) for payloads                                                                                                                  |
| `OliraTrace`                                                         | `object_type` + `object_id` for correlating logs                                                                                                                                                                           |
| `LogSpec`                                                            | Dataclass for `log_batch()` rows (`log_type`, `patient_id`, `payload`, `trace`, `timestamp`, `idempotency_key`, `metadata`)                                                                                                |
| `EsasItem`, `LabResultItem`, `PerformingLab`, `TimePeriod`           | Optional typed helpers for structured payloads (e.g. labs, ESAS)                                                                                                                                                           |
| `ExternalIdentifier`, `CreatePatientRequest`, `UpdatePatientRequest` | Patient APIs                                                                                                                                                                                                               |
| `BatchResult`, `BatchError`                                          | Batch log and batch patient outcomes                                                                                                                                                                                       |
| `Patient`, `PatientListResult`, `PatientBatchResult`, `PatientToken` | Responses                                                                                                                                                                                                                  |
| State-read models                                                    | `StableDataResult`, `EventStateModuleSummary`, `ViewMeta`, `ViewBlocksListResult`, `ViewResult`, `ViewBlockResult`, `LogsResult`, `EventsResult`, `MemoriesResult`, etc.                                                   |
| `LogQueryResult`                                                     | Result 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` / `AsyncLogQuery`                                         | Fluent 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 models                                                     | `IngestRecord`, `IngestLogSpec`, `IngestionJob`, `IngestionJobListResult`, `IngestionErrorSummary`                                                                                                                         |

## Examples

Runnable scripts in the [`examples/`](https://github.com/olira-ai/olira/tree/main/examples) directory of the SDK repo:

| File                         | What it covers                                                              |
| ---------------------------- | --------------------------------------------------------------------------- |
| `00_quickstart.py`           | `init()`, create a patient, log an event, flush                             |
| `01_patient_management.py`   | Full patient lifecycle                                                      |
| `02_event_logging.py`        | `log()`, `log_batch()`, traces, idempotency                                 |
| `03_fhir_ingestion.py`       | `log_fhir()` with Condition, MedicationRequest, Appointment; error handling |
| `04_historical_ingestion.py` | File upload, polling, confirm/cancel flow                                   |
| `05_logs_only_workflow.py`   | Historical ingestion when patients already exist in the org                 |
| `06_read_patient_state.py`   | Stable data, event modules, views, logs, memories                           |
| `07_patient_token.py`        | Mint 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](/send-data/absorbers) used by Epic/Cerner integrations. Full parameters, examples, and error cases are under **Logs → Log FHIR resource** in the sidebar.

| FHIR `resourceType`                                                    | Olira event type(s)                                                                                                                                                            |
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Observation`                                                          | `vitals_measurement`, `lab_results`, `genomic_variant`, `clinical_measurement`, `functional_class`, `clinical_finding`, `social_determinants`, `treatment_response_assessment` |
| `Patient`                                                              | `demographics`                                                                                                                                                                 |
| `Appointment`, `Encounter`                                             | `care_encounter`                                                                                                                                                               |
| `Condition`                                                            | `condition`                                                                                                                                                                    |
| `MedicationRequest`, `MedicationStatement`, `MedicationAdministration` | `medication_list_update`                                                                                                                                                       |
| `AllergyIntolerance`                                                   | `allergy_intolerance`                                                                                                                                                          |
| `CarePlan`                                                             | `clinical_plan_item`, `treatment_phase`                                                                                                                                        |
| `CareTeam`                                                             | `care_team`                                                                                                                                                                    |
| `DiagnosticReport`                                                     | `lab_results`, `imaging_result`, `procedure_result`, `unstructured_report`                                                                                                     |
| `DocumentReference`                                                    | `clinical_note`, `unstructured_report`                                                                                                                                         |
| `Procedure`                                                            | `procedure`                                                                                                                                                                    |
| `Immunization`                                                         | `immunization`                                                                                                                                                                 |
| `FamilyMemberHistory`                                                  | `family_history`                                                                                                                                                               |
| `Goal`                                                                 | `care_goal`                                                                                                                                                                    |
| `Coverage`                                                             | `insurance`                                                                                                                                                                    |
| `RelatedPerson`                                                        | `emergency_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.
