Skip to main content

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.

Metadata

Release files for ehcsapi 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ehcsapi 0.2.0
File Size Uploaded Provenance
ehcsapi-0.2.0.tar.gz 53.9 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ehcsapi 0.2.0
File Interpreter ABI Platform
ehcsapi-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 67.4 kB

Release files / ehcsapi-0.2.0.tar.gz

Download URL ehcsapi-0.2.0.tar.gz
Size 53.9 kB
Tags Source
SHA-256 checksum
How to use checksums
09a0a01b201cdd62273ff66a02bd0ad9b5f935261db2edbbc83634eba1c4ed45
BLAKE2b-256 checksum
How to use checksums
214b3efd28a2b26bf832ac33acd92c49bb86cc2dfc499d5337706174f93ea37f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.2.0 CPython/3.11.15

Release files / ehcsapi-0.2.0-py3-none-any.whl

Download URL ehcsapi-0.2.0-py3-none-any.whl
Size 13.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b4ba01c9aaa1ab54d49f7eee665959660a772088bae5727c2bb94d2281ba9901
BLAKE2b-256 checksum
How to use checksums
219778c11b649186a8dc34467ef5e6cce6fc1e10f93d7571b1ed93f046110f63
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.2.0 CPython/3.11.15

Security for ehcsapi 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page