# medelement-mis

Typed Python SDK for Medelement MIS API.

## Public Interface

Top-level imports are stable and intended for package consumers:

```python
from medelement_mis import (
    MedelementClient,
    MedelementConfig,
    Environment,
    Gender,
    ColorCode,
    SOCIAL_STATUSES,
    CONCESSIONS,
)
```

Main API resources exposed by `MedelementClient`:

- `client.patients`
  - `search(...)`
  - `get_by_iin(iin)`
  - `create(...)`
  - `get(patient_code)`
  - `update(...)`
- `client.receptions`
  - `create(...)`
  - `search(...)`
  - `search_pd(...)`
  - `get(reception_code)`
  - `reschedule(...)`
  - `remove(reception_code)`
- `client.specialists`
  - `list()`
- `client.timetable`
  - `get_timetable(...)`
  - `get_specialist_receptions(...)`
- `client.nomenclatures`
  - `list(...)`

Reference catalogs from docs:

- `SOCIAL_STATUSES` (from `docs/api/social_status.md`)
- `CONCESSIONS` (from `docs/api/concessions.md`)

## Quick Start

```python
from medelement_mis import MedelementClient, MedelementConfig

config = MedelementConfig(
    user_id="your_user_id",
    password="your_password",
    integrator_key="your_integrator_key",
    base_url="https://api.medelement.com/v1",
)

with MedelementClient(config=config) as client:
    patients = client.patients.search(lastname="Ivanov")
    for patient in patients:
        print(patient.profile_code, patient.lastname, patient.name)

    patients_by_iin = client.patients.get_by_iin("651004450150")
    for patient in patients_by_iin:
        print(patient.profile_code, patient.iin)
```

## Error Handling

```python
from httpx import TimeoutException, TransportError
from medelement_mis import APIError, AuthenticationError, MedelementClient, MedelementConfig, NotFoundError

config = MedelementConfig()

try:
    with MedelementClient(config=config) as client:
        patient = client.patients.get(123)
except NotFoundError:
    print("Patient not found")
except AuthenticationError:
    print("Check Basic auth credentials and X-Integrator-Key")
except APIError as exc:
    print(f"API returned an error: {exc}")
except (TimeoutException, TransportError) as exc:
    print(f"Network error after retries: {exc}")
```

HTTP `401`, `403`, `404`, and `422` responses are normalized into SDK exceptions.
Network timeouts and transport failures are retried for idempotent requests (`GET`, `HEAD`, `OPTIONS`) and then bubble up as `httpx` exceptions if all retries fail.

## Logging

The SDK logs request and response lines at `DEBUG` level via the `medelement_mis` logger:

```python
import logging

logging.basicConfig(level=logging.DEBUG)
logging.getLogger("medelement_mis").setLevel(logging.DEBUG)
```

This logs method, URL, and status code, but does not log authentication headers.

## API Naming Notes

Most request models use snake_case field names. Some timetable endpoints use camelCase aliases because the upstream Medelement API requires that exact payload shape, for example `specialistCode`, `beginDatetime`, and `companyCabinetCode` in `get_receptions_short`.
