ehvd
Python client for the eHealth Verzeichnisdienst (eHVD) — the public SOAP webservice of Austria's BRZ that lists healthcare providers ("GDA") registered under § 9/10 GTelG 2012.
The client wraps the official SOAP interface (GetGdaDescriptors,
GetGdaSearch) with a pythonic API, returns typed dataclasses, maps the
documented fault codes 6001–6006 to exceptions, and ships an optional Django
integration.
Status
Alpha. The public endpoint requires registration at BMSGPK and per-IP
firewall whitelisting at BRZ — without both, every request is blocked at
the WAF. See docs/access.md for the full process
(ID Austria, application contents, source IP, support contacts). During
development most users work against a locally cached WSDL or a mocked
zeep client.
Install
pip install ehvd # core
pip install "ehvd[django]" # with Django factory
Requirements: Python ≥ 3.10, zeep, requests.
Quick start
from ehvd import EhvdClient
client = EhvdClient() # uses the public production WSDL
# 1) Lookup by OID
gda = client.get_by_id("1.2.40.0.34.99.10.1.1.2.27095")
# 2) Lookup by GDA-specific identifier
gda = client.get_by_arzt_nr("12345") # ÖÄK-Arztnummer
gda = client.get_by_hospital_nr("987") # KA-Nr
gda = client.get_by_ambulatory_nr("321") # Ambu-Nr
gda = client.get_by_vpnr("555") # VPNR
gda = client.get_by_gbr_id("ABC1") # GBR-ID
if gda:
print(gda.display_name)
for addr in gda.addresses:
print(addr.zip, addr.city, addr.street_name, addr.street_number)
# 3) Search
hits = client.search(
surname="Mueller*",
city="Wien",
max_results=50,
)
for hit in hits:
print(hit.id.id, hit.display_name, hit.status.ehvd_status)
get_by_id returns None when the service reports 6002 (no compliance found).
search raises EhvdTooManyResultsError when the
result set would exceed max_results.
Errors
The service returns SOAP 1.2 faults with the numeric codes from Servicehandbuch 4.1; the client maps them onto typed exceptions:
| Code | Exception |
|---|---|
| 6001 | EhvdInvalidContentError |
| 6002 | EhvdNoComplianceError (converted to None for single-record lookups) |
| 6003 | EhvdGeneralError |
| 6004 | EhvdAttributeNotFoundError |
| 6005 | EhvdTooManyResultsError |
| 6006 | EhvdNotAllowedError |
Local input validation (length limits, illegal wildcard, missing surname,
max_results range) raises EhvdValidationError before hitting the wire.
Django integration
# settings.py
INSTALLED_APPS = [..., "ehvd.django"]
EHVD = {
"WSDL_URL": "https://ehvdws.gesundheit.gv.at/ehvd.wsdl",
"TIMEOUT": 10,
# optional mutual TLS:
"CLIENT_CERT": ("/path/cert.pem", "/path/key.pem"),
"CA_BUNDLE": "/path/ca.pem",
}
from ehvd.django import get_client
def my_view(request):
gda = get_client().get_by_arzt_nr(request.GET["arzt_nr"])
...
get_client() caches a single client per process. Call
ehvd.django.reset_client() after changing settings (e.g. in tests).
Transport configuration
For mutual TLS, custom proxies, timeouts or session re-use, instantiate
zeep.Client yourself and pass it in:
from requests import Session
from zeep import Client as ZeepClient
from zeep.transports import Transport
session = Session()
session.cert = ("/path/cert.pem", "/path/key.pem")
zeep_client = ZeepClient(
"https://ehvdws.gesundheit.gv.at/ehvd.wsdl",
transport=Transport(session=session, timeout=10),
)
client = EhvdClient(zeep_client=zeep_client)
Development
git clone git@gitlab.com:nerdocs/ehvd.git
cd ehvd
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,django]"
pytest
ruff check .
The package uses a src-layout (src/ehvd/) so that tests always exercise
the installed package rather than the working copy.
Layout
See docs/architecture.md for the structural
overview. Reference material is in docs/:
docs/architecture.md— module map, src-layout rationaledocs/usage.md— end-to-end usage walkthroughdocs/protocol.md— SOAP fields & error codes (from Servicehandbuch)docs/access.md— Antrag, ID Austria & IP-Freischaltung beim BRZdocs/django.md— Django integration details
For AI agents working in this repository: read CLAUDE.md first.
License
MIT — see LICENSE.
Sources
- eHVD Webservice Handbuch (Servicehandbuch), BRZ, v2.2, 2023-11-14
- §§ 9, 10 GTelG 2012
- IHE HPD profile
Metadata
Release files for ehvd 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| ehvd-0.1.0.tar.gz | 89.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ehvd-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 104.1 kB
Release files / ehvd-0.1.0.tar.gz
| Download URL | ehvd-0.1.0.tar.gz |
|---|---|
| Size | 89.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
974922be34ab18f0c870a5b52e8659ab5c452866076d8af3f9c95a457d9aec35
|
|
BLAKE2b-256 checksum How to use checksums |
d9508cf414ca1b44d77012b176f0555cde25aeb3c4fb3749a629cf011b4786ab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / ehvd-0.1.0-py3-none-any.whl
| Download URL | ehvd-0.1.0-py3-none-any.whl |
|---|---|
| Size | 14.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
caa7f233031e488f7d666baa01483348ff36e61d84a8c4a3d19281ee64438ae3
|
|
BLAKE2b-256 checksum How to use checksums |
46c3793a82f0210e9352b19216882bcd001d76d9da5e19cebf3f57a6f4f5077d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Security for ehvd 0.1.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.