Skip to main content

Async Python client for the Austrian eHealth Codierservice API (FHIR R5 ConceptMap).

Project description

ehcsapi

Async Python client for the eHealth Codierservice API (Austrian eHealth, FHIR R5 ConceptMap).

The service maps free-text diagnoses to coded concepts (SNOMED CT, ICD-10, Orphanet). The typical flow is:

  1. create a search episode once,
  2. call find_diagnoses(...) repeatedly while the user types (type-ahead),
  3. call get_codes(...) for the selected diagnosis to obtain the SNOMED/ICD-10 codes,
  4. drop the episode.

The client is async-only (built on httpx.AsyncClient) so it fits naturally into a Django ASGI type-ahead view, where in-flight requests can be cancelled as the user keeps typing.

Installation

uv add ehcsapi          # or: pip install ehcsapi

Requires Python ≥ 3.11. Depends on httpx and cryptography.

Authentication (mutual TLS)

The service requires a client certificate. The operator recommends loading the certificate once at startup and keeping it in memory for the lifetime of the process. This client supports exactly that — pass a pre-built ssl.SSLContext, or in-memory certificate bytes, or a file path:

import ehcsapi

# Recommended: build the context once at startup (e.g. from your central cert service) and reuse it.
ctx = ehcsapi.build_ssl_context(cert_bytes, password="…")   # bytes (PEM or PKCS#12) or a path
client = ehcsapi.AsyncClient("com.example.myapp", ssl_context=ctx)

# Or let the client build it from a path / bytes:
client = ehcsapi.AsyncClient("com.example.myapp", cert="/path/to/client.p12", cert_password="…")

The base URL defaults to production (ehcsapi.PRODUCTION_BASE_URL). For the test system use ehcsapi.TEST_BASE_URL (https://csapi-t.ehealth.gv.at):

client = ehcsapi.AsyncClient("com.example.myapp", base_url=ehcsapi.TEST_BASE_URL, cert=cert)

Usage

Type-ahead (one episode, many keystrokes)

async with ehcsapi.AsyncClient("com.example.myapp", ssl_context=ctx) as cs:
    async with cs.search_episode() as episode:        # POST on enter, DELETE on exit
        hits = await episode.find_diagnoses("influ")  # -> list[Diagnosis]
        codes = await episode.get_codes(hits[0])      # search terms reused from the Diagnosis
        print(codes.icd10)                            # [Coding(code='J11.1', display='Grippe …')]

In a stateless Django view you usually create the episode once, keep its id in the session, and reconstruct a handle per request without a new POST:

episode = cs.episode(request.session["episode_id"])   # existing episode, no round-trip
hits = await episode.find_diagnoses(query)

One-shot lookup

async with ehcsapi.AsyncClient("com.example.myapp", ssl_context=ctx) as cs:
    hits = await cs.find_diagnoses("influenza")        # opens + drops an ad-hoc episode

API surface

Method Endpoint
startup_probe() HEAD /startupprobe
version() / dataset_version() / application_version() GET /version[...]
create_episode() / create_episode_v2() / search_episode() POST .../searchepisode
episode(id) resume an existing episode (no request)
delete_episode(id) / delete_episode_v2(id) DELETE .../searchepisode/{id}
SearchEpisode.find_diagnoses(...) GET .../conceptmap?_query=findDiagnoses
SearchEpisode.get_codes(...) GET .../conceptmap?_query=getCodeByElementId
emit_x(n) / emit_random(n) diagnostic GET /emit/...

Errors raise a CodierserviceError subclass: BadRequestError (400), ForbiddenError (403), SearchEpisodeExpiredError (410 — create a fresh episode), or TransportError for network failures.

Test run against the test system

A runnable smoke script and an opt-in live test hit csapi-t:

# one-off manual run
CSAPI_CLIENT_TLS_CERT_PATH=/path/to/client.p12 CSAPI_CLIENT_TLS_CERT_PASSWORD= \
    python examples/smoke.py influenza

# opt-in pytest
EHCSAPI_LIVE=1 CSAPI_CLIENT_TLS_CERT_PATH=/path/to/client.p12 CSAPI_CLIENT_TLS_CERT_PASSWORD= \
    uv run pytest -m live

The reference OpenAPI document is in docs/openapi.json.

Development

uv sync
uv run pytest          # unit tests, no network
uv run ruff check
uv run mypy src

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ehcsapi-0.2.0.tar.gz (53.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ehcsapi-0.2.0-py3-none-any.whl (13.6 kB view details)

Uploaded Python 3

File details

Details for the file ehcsapi-0.2.0.tar.gz.

File metadata

  • Download URL: ehcsapi-0.2.0.tar.gz
  • Upload date:
  • Size: 53.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for ehcsapi-0.2.0.tar.gz
Algorithm Hash digest
SHA256 09a0a01b201cdd62273ff66a02bd0ad9b5f935261db2edbbc83634eba1c4ed45
MD5 51e9dbf35e6fdb51f730e60ed26a9a6f
BLAKE2b-256 214b3efd28a2b26bf832ac33acd92c49bb86cc2dfc499d5337706174f93ea37f

See more details on using hashes here.

File details

Details for the file ehcsapi-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: ehcsapi-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 13.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for ehcsapi-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b4ba01c9aaa1ab54d49f7eee665959660a772088bae5727c2bb94d2281ba9901
MD5 091cd9f756f28a020a60843d55a7d48f
BLAKE2b-256 219778c11b649186a8dc34467ef5e6cce6fc1e10f93d7571b1ed93f046110f63

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page