Skip to main content

PyPI Python Versions Code Coverage License Conventional Commits

MOSAIC Client

The mosaic_client library provides wrappers around the SOAP (Simple Object Access Protocol) interfaces of E-PIX and gPAS by the THS Greifswald. The main entrypoints are mosaic_client.EPIXClient and mosaic_client.GPASClient, which are classes that simply take the URLs to the WSDL endpoints of their respective services and expose functions to interact with these services. Both client classes are implemented as Zeep clients while validation is leveraged by marshmallow.

Installation

To install the client, Python 3.11 or higher is required.

pip install mosaic-python-client

Getting started

Both E-PIX and gPAS client can be either instantiated by passing the WSDL URLs as strings or by passing your own zeep.Client instance. This section briefly demonstrates the usage of both clients. For more information, have a look at the clients available methods and the respective docstrings.

E-PIX client

As a very first step, we need to instantiate the client. EPIXClient expects a WSDL URL for the regular E-PIX service which enables operations like requesting an MPI (Master Patient Index) or deactivating/deleting identities and a WSDL URL for the management service which leverages the management of domains.

from mosaic_client import EPIXClient

epix = EPIXClient(
    client="http://localhost:8081/epix/epixService?wsdl",
    management_client="http://localhost:8081/epix/epixManagementService?wsdl",
)

To be able to request an MPI, we first need to create a data domain where the identity we want an MPI for is saved. We name that new data domain default. Note that E-PIX comes with a data source named dummy_safe_source and an identifier domain named MPI by default.

from mosaic_client import EPIXClient
from mosaic_client.epix import Domain

epix = EPIXClient(
    client="http://localhost:8081/epix/epixService?wsdl",
    management_client="http://localhost:8081/epix/epixManagementService?wsdl",
)

epix.add_domain(
    domain=Domain(
        name="default",
        label="default",
        mpi_domain=epix.get_identifier_domain(identifier_domain_name="MPI"),
        safe_source=epix.get_source(source_name="dummy_safe_source"),
    )
)

Now, it is possible to request an MPI for an identity. The default configuration of a data domain assumes that first and last name, gender and birthdate are required for new identities.

from dataclasses import asdict
import datetime
import json
from mosaic_client import EPIXClient
from mosaic_client.epix import Identity

epix = EPIXClient(
    client="http://localhost:8081/epix/epixService?wsdl",
    management_client="http://localhost:8081/epix/epixManagementService?wsdl",
)

mpi_response = epix.request_mpi(
    domain_name="default",
    source_name="dummy_safe_source",
    identity=Identity(
        first_name="Foo",
        last_name="Bar",
        gender="f",
        birth_date=datetime.datetime(1970, 1, 1, tzinfo=datetime.UTC),
    ),
)

print(json.dumps(asdict(mpi_response), indent=2, default=str))
{
  "match_status": "NO_MATCH",
  "person": {
    "deactivated": false,
    "mpi_id": {
      "value": "1001000000011",
      "identifier_domain": {
        "name": "MPI",
        "label": "MPI",
        "oid": "1.2.276.0.76.3.1.132.1.1.1",
        "description": null,
        "entry_date": "2026-09-29 15:57:00.492000+02:00",
        "update_date": "2026-09-29 15:57:00.492000+02:00"
      },
      "entry_date": "2026-09-29 15:57:43.496000+02:00",
      "description": "generated MPI id",
      "fresh": false
    },
    "person_created": "2026-09-29 15:57:43.496000+02:00",
    "person_id": 1,
    "person_last_edited": "2026-09-29 15:57:43.496000+02:00",
    "other_identities": [],
    "reference_identity": {
      "birth_date": "1970-01-01 01:00:00+01:00",
      "birth_place": null,
      "civil_status": null,
      "degree": null,
      "external_date": null,
      "first_name": "Foo",
      "gender": "F",
      "identifiers": [],
      "last_name": "Bar",
      "middle_name": null,
      "mother_tongue": null,
      "mothers_maiden_name": null,
      "nationality": null,
      "vital_status": null,
      "death_date": null,
      "prefix": null,
      "race": null,
      "religion": null,
      "suffix": null,
      "value_1": null,
      "value_2": null,
      "value_3": null,
      "value_4": null,
      "value_5": null,
      "value_6": null,
      "value_7": null,
      "value_8": null,
      "value_9": null,
      "value_10": null,
      "contacts": [],
      "deactivated": false,
      "identity_created": "2026-09-29 15:57:43.496000+02:00",
      "identity_id": 1,
      "identity_last_edited": "2026-09-29 15:57:43.496000+02:00",
      "identity_version": 1,
      "person_id": 1,
      "source": {
        "name": "dummy_safe_source",
        "description": "dummy because of the default-property \"safe_source\" in table domain",
        "label": "dummy_safe_source",
        "entry_date": "2026-09-29 15:57:00.531000+02:00",
        "update_date": "2026-09-29 15:57:00.531000+02:00"
      }
    },
    "domain_name": "default"
  },
  "mpi_error_code": null
}

gPAS client

As before, we first need to instantiate the client. GPASClient expects a WSDL URL for the regular gPAS service which enables operations like creating pseudonyms and a WSDL URL for the domain service which leverages the management of domains.

from mosaic_client import GPASClient

gpas = GPASClient(
    client="http://localhost:8080/gpas/gpasService?wsdl",
    domain_client="http://localhost:8080/gpas/DomainService?wsdl",
)

To be able to create pseudonyms, we first need to create a new domain since pseudonyms are organized in domains. We name that new domain default.

from mosaic_client import GPASClient
from mosaic_client.gpas import Domain

gpas = GPASClient(
    client="http://localhost:8080/gpas/gpasService?wsdl",
    domain_client="http://localhost:8080/gpas/DomainService?wsdl",
)

gpas.add_domain(domain=Domain(name="default", label="default"))

Now, we are able to create a new pseudonym for the value value123.

from mosaic_client import GPASClient

gpas = GPASClient(
    client="http://localhost:8080/gpas/gpasService?wsdl",
    domain_client="http://localhost:8080/gpas/DomainService?wsdl",
)

pseudonym = gpas.get_or_create_pseudonyms_for(domain_name="default", value="value123")

print(f"Pseudonym: {pseudonym.pseudonym}")
Pseudonym: 199799437

Running tests

This library implements its tests via pytest. In order to run integration tests, a running instance of E-PIX and gPAS are needed. The first option is to spin up the services independently and direct pytest to it. Have a look at the provided docker compose file ./tests/docker/docker-compose.yml for a quick solution. For more sophisticated deployments, please read the documentation of E-PIX and gPAS. Alternatively, pytest can start Docker test-containers for the duration of the test run. Since containers are started and stopped for each run individually, such a test run takes more time.

The following table shows all available options to configure pytest.

Environment variable Description Default
PYTEST_USE_TESTCONTAINERS Whether pytest should use test-containers or not 0
PYTEST_EPIX_WSDL_URL1) WSDL URL for the E-PIX service
PYTEST_EPIX_MANAGEMENT_WSDL_URL1) WSDL URL for the E-PIX management service
PYTEST_EPIX_IMAGE_TAG2) E-PIX image tag that is used for the test-container latest
PYTEST_GPAS_WSDL_URL1) WSDL URL for the gPAS service
PYTEST_GPAS_DOMAIN_WSDL_URL1) WSDL URL for the gPAS domain service
PYTEST_GPAS_IMAGE_TAG2) gPAS image tag that is used for the test-container latest

1) Only needed, if PYTEST_USE_TESTCONTAINERS is set to 0.
2) Only used, if PYTEST_USE_TESTCONTAINERS is set to 1.

It is possible to define these variables in a .env.test file. The .env.example file provides a template. You can copy the content of .env.example to directly get started with pytest using test-containers.

cp .env.example .env.test

License

MIT.

Metadata

Release files for mosaic-python-client 0.3.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 mosaic-python-client 0.3.0
File Size Uploaded
mosaic_python_client-0.3.0.tar.gz 25.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mosaic-python-client 0.3.0
File Interpreter ABI Platform
mosaic_python_client-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 51.5 kB

Release files / mosaic_python_client-0.3.0.tar.gz

Download URL mosaic_python_client-0.3.0.tar.gz
Size 25.1 kB
Tags Source
SHA-256 checksum
How to use checksums
8cfd45532a462d3a277fa9d1e2ed5e0af3d512ba6fdf1a113541e2cfe48d1872
BLAKE2b-256 checksum
How to use checksums
64b4a306c3814e3ea0269ff167a6cd1f1c70ecd6b6249a47c1bf900f57d7dc89
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / mosaic_python_client-0.3.0-py3-none-any.whl

Download URL mosaic_python_client-0.3.0-py3-none-any.whl
Size 26.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6526c757395795de26feeb93df7c3c8b9adee98f3be7e0ebb2507bd08d259b98
BLAKE2b-256 checksum
How to use checksums
de92e1249b0a1d243a595a19005a8f5b2b4e06e2d2cd19fbe6d6e4902157ddcc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

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