# This file was auto-generated by Fern from our API Definition.

import datetime as dt
import typing
from json.decoder import JSONDecodeError

from .......core.api_error import ApiError
from .......core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from .......core.datetime_utils import serialize_datetime
from .......core.jsonable_encoder import jsonable_encoder
from .......core.pydantic_utilities import pydantic_v1
from .......core.request_options import RequestOptions
from ....common.errors.not_found_error import NotFoundError
from ....common.errors.version_conflict_error import VersionConflictError
from ....common.types.not_found_error_body import NotFoundErrorBody
from ....common.types.page_token import PageToken
from ....common.types.patient_id import PatientId
from ....common.types.sort_direction import SortDirection
from ....common.types.version_conflict_error_body import VersionConflictErrorBody
from .errors.potential_duplicate_patients import PotentialDuplicatePatients
from .types.mutable_patient import MutablePatient
from .types.patient import Patient
from .types.patient_page import PatientPage
from .types.patient_sort_field import PatientSortField
from .types.potential_duplicate_patients_error_body import PotentialDuplicatePatientsErrorBody

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class V1Client:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def create(
        self,
        *,
        request: MutablePatient,
        skip_duplicate_check: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Patient:
        """
        Adds a patient. VersionConflictError is returned when the patient's external ID is already in use.

        Parameters
        ----------
        request : MutablePatient

        skip_duplicate_check : typing.Optional[bool]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        Patient

        Examples
        --------
        import datetime
        import uuid

        from candid.client import CandidApiClient
        from candid.resources.pre_encounter import (
            Address,
            AddressUse,
            ContactPoint,
            ContactPointUse,
            DisabilityStatus,
            Ethnicity,
            ExternalProvider,
            ExternalProviderType,
            Gender,
            HumanName,
            NameUse,
            Period,
            Race,
            Relationship,
            Sex,
            SexualOrientation,
        )
        from candid.resources.pre_encounter.patients.v_1 import (
            Contact,
            ExternalProvenance,
            FilingOrder,
            Guarantor,
            MaritalStatus,
            MutablePatient,
        )

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.pre_encounter.patients.v_1.create(
            skip_duplicate_check=True,
            request=MutablePatient(
                name=HumanName(
                    family="string",
                    given=["string"],
                    use=NameUse.USUAL,
                    period=Period(
                        start=datetime.date.fromisoformat(
                            "2023-01-15",
                        ),
                        end=datetime.date.fromisoformat(
                            "2023-01-15",
                        ),
                    ),
                ),
                other_names=[
                    HumanName(
                        family="string",
                        given=["string"],
                        use=NameUse.USUAL,
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    )
                ],
                gender=Gender.MAN,
                birth_date=datetime.date.fromisoformat(
                    "2023-01-15",
                ),
                social_security_number="string",
                biological_sex=Sex.FEMALE,
                sexual_orientation=SexualOrientation.HETEROSEXUAL,
                race=Race.AMERICAN_INDIAN_OR_ALASKA_NATIVE,
                ethnicity=Ethnicity.HISPANIC_OR_LATINO,
                disability_status=DisabilityStatus.DISABLED,
                marital_status=MaritalStatus.ANNULLED,
                deceased=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
                multiple_birth=1,
                primary_address=Address(
                    use=AddressUse.HOME,
                    line=["string"],
                    city="string",
                    state="string",
                    postal_code="string",
                    country="string",
                    period=Period(
                        start=datetime.date.fromisoformat(
                            "2023-01-15",
                        ),
                        end=datetime.date.fromisoformat(
                            "2023-01-15",
                        ),
                    ),
                ),
                other_addresses=[
                    Address(
                        use=AddressUse.HOME,
                        line=["string"],
                        city="string",
                        state="string",
                        postal_code="string",
                        country="string",
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    )
                ],
                primary_telecom=ContactPoint(
                    value="string",
                    use=ContactPointUse.HOME,
                    period=Period(
                        start=datetime.date.fromisoformat(
                            "2023-01-15",
                        ),
                        end=datetime.date.fromisoformat(
                            "2023-01-15",
                        ),
                    ),
                ),
                other_telecoms=[
                    ContactPoint(
                        value="string",
                        use=ContactPointUse.HOME,
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    )
                ],
                email="string",
                electronic_communication_opt_in=True,
                photo="string",
                language="string",
                external_provenance=ExternalProvenance(
                    external_id="string",
                    system_name="string",
                ),
                contacts=[
                    Contact(
                        relationship=[Relationship.SELF],
                        name=HumanName(
                            family="string",
                            given=["string"],
                            use=NameUse.USUAL,
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        ),
                        telecoms=[
                            ContactPoint(
                                value="string",
                                use=ContactPointUse.HOME,
                                period=Period(
                                    start=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                    end=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                ),
                            )
                        ],
                        addresses=[
                            Address(
                                use=AddressUse.HOME,
                                line=["string"],
                                city="string",
                                state="string",
                                postal_code="string",
                                country="string",
                                period=Period(
                                    start=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                    end=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                ),
                            )
                        ],
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                        hipaa_authorization=True,
                    )
                ],
                general_practitioners=[
                    ExternalProvider(
                        name=HumanName(
                            family="string",
                            given=["string"],
                            use=NameUse.USUAL,
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        ),
                        type=ExternalProviderType.PRIMARY,
                        npi="string",
                        telecoms=[
                            ContactPoint(
                                value="string",
                                use=ContactPointUse.HOME,
                                period=Period(
                                    start=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                    end=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                ),
                            )
                        ],
                        addresses=[{"key": "value"}],
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                        canonical_id="string",
                    )
                ],
                filing_order=FilingOrder(
                    coverages=[
                        uuid.UUID(
                            "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                        )
                    ],
                ),
                non_insurance_payers=["string"],
                guarantor=Guarantor(
                    name=HumanName(
                        family="string",
                        given=["string"],
                        use=NameUse.USUAL,
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    ),
                    telecom=ContactPoint(
                        value="string",
                        use=ContactPointUse.HOME,
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    ),
                    email="string",
                    birth_date=datetime.date.fromisoformat(
                        "2023-01-15",
                    ),
                    address=Address(
                        use=AddressUse.HOME,
                        line=["string"],
                        city="string",
                        state="string",
                        postal_code="string",
                        country="string",
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    ),
                ),
                self_pay=True,
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "patients/v1",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="POST",
            params={"skip_duplicate_check": skip_duplicate_check},
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(Patient, _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "VersionConflictError":
                raise VersionConflictError(
                    pydantic_v1.parse_obj_as(VersionConflictErrorBody, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "PotentialDuplicatePatients":
                raise PotentialDuplicatePatients(
                    pydantic_v1.parse_obj_as(PotentialDuplicatePatientsErrorBody, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_multi(
        self,
        *,
        limit: typing.Optional[int] = None,
        mrn: typing.Optional[str] = None,
        page_token: typing.Optional[PageToken] = None,
        sort_field: typing.Optional[PatientSortField] = None,
        sort_direction: typing.Optional[SortDirection] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PatientPage:
        """
        Searches for patients that match the query parameters.

        Parameters
        ----------
        limit : typing.Optional[int]

        mrn : typing.Optional[str]

        page_token : typing.Optional[PageToken]

        sort_field : typing.Optional[PatientSortField]

        sort_direction : typing.Optional[SortDirection]
            Defaults to ascending.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        PatientPage

        Examples
        --------
        from candid.client import CandidApiClient
        from candid.resources.pre_encounter import SortDirection

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.pre_encounter.patients.v_1.get_multi(
            limit=1,
            mrn="string",
            page_token="string",
            sort_field="string",
            sort_direction=SortDirection.ASC,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "patients/v1/get_multi",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            params={
                "limit": limit,
                "mrn": mrn,
                "page_token": page_token,
                "sort_field": sort_field,
                "sort_direction": sort_direction,
            },
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(PatientPage, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get(self, id: PatientId, *, request_options: typing.Optional[RequestOptions] = None) -> Patient:
        """
        Gets a patient.

        Parameters
        ----------
        id : PatientId

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        Patient

        Examples
        --------
        from candid.client import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.pre_encounter.patients.v_1.get(
            id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"patients/v1/{jsonable_encoder(id)}",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(Patient, _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    pydantic_v1.parse_obj_as(NotFoundErrorBody, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_history(
        self, id: PatientId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[Patient]:
        """
        Gets a patient along with it's full history. The return list is ordered by version ascending.

        Parameters
        ----------
        id : PatientId

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[Patient]

        Examples
        --------
        from candid.client import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.pre_encounter.patients.v_1.get_history(
            id="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"patients/v1/{jsonable_encoder(id)}/history",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(typing.List[Patient], _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    pydantic_v1.parse_obj_as(NotFoundErrorBody, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update(
        self,
        id: PatientId,
        version: str,
        *,
        request: MutablePatient,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Patient:
        """
        Updates a patient. The path must contain the most recent version to prevent race conditions. Updating historic versions is not supported.

        Parameters
        ----------
        id : PatientId

        version : str

        request : MutablePatient

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        Patient

        Examples
        --------
        import datetime
        import uuid

        from candid.client import CandidApiClient
        from candid.resources.pre_encounter import (
            Address,
            AddressUse,
            ContactPoint,
            ContactPointUse,
            DisabilityStatus,
            Ethnicity,
            ExternalProvider,
            ExternalProviderType,
            Gender,
            HumanName,
            NameUse,
            Period,
            Race,
            Relationship,
            Sex,
            SexualOrientation,
        )
        from candid.resources.pre_encounter.patients.v_1 import (
            Contact,
            ExternalProvenance,
            FilingOrder,
            Guarantor,
            MaritalStatus,
            MutablePatient,
        )

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.pre_encounter.patients.v_1.update(
            id="string",
            version="string",
            request=MutablePatient(
                name=HumanName(
                    family="string",
                    given=["string"],
                    use=NameUse.USUAL,
                    period=Period(
                        start=datetime.date.fromisoformat(
                            "2023-01-15",
                        ),
                        end=datetime.date.fromisoformat(
                            "2023-01-15",
                        ),
                    ),
                ),
                other_names=[
                    HumanName(
                        family="string",
                        given=["string"],
                        use=NameUse.USUAL,
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    )
                ],
                gender=Gender.MAN,
                birth_date=datetime.date.fromisoformat(
                    "2023-01-15",
                ),
                social_security_number="string",
                biological_sex=Sex.FEMALE,
                sexual_orientation=SexualOrientation.HETEROSEXUAL,
                race=Race.AMERICAN_INDIAN_OR_ALASKA_NATIVE,
                ethnicity=Ethnicity.HISPANIC_OR_LATINO,
                disability_status=DisabilityStatus.DISABLED,
                marital_status=MaritalStatus.ANNULLED,
                deceased=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
                multiple_birth=1,
                primary_address=Address(
                    use=AddressUse.HOME,
                    line=["string"],
                    city="string",
                    state="string",
                    postal_code="string",
                    country="string",
                    period=Period(
                        start=datetime.date.fromisoformat(
                            "2023-01-15",
                        ),
                        end=datetime.date.fromisoformat(
                            "2023-01-15",
                        ),
                    ),
                ),
                other_addresses=[
                    Address(
                        use=AddressUse.HOME,
                        line=["string"],
                        city="string",
                        state="string",
                        postal_code="string",
                        country="string",
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    )
                ],
                primary_telecom=ContactPoint(
                    value="string",
                    use=ContactPointUse.HOME,
                    period=Period(
                        start=datetime.date.fromisoformat(
                            "2023-01-15",
                        ),
                        end=datetime.date.fromisoformat(
                            "2023-01-15",
                        ),
                    ),
                ),
                other_telecoms=[
                    ContactPoint(
                        value="string",
                        use=ContactPointUse.HOME,
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    )
                ],
                email="string",
                electronic_communication_opt_in=True,
                photo="string",
                language="string",
                external_provenance=ExternalProvenance(
                    external_id="string",
                    system_name="string",
                ),
                contacts=[
                    Contact(
                        relationship=[Relationship.SELF],
                        name=HumanName(
                            family="string",
                            given=["string"],
                            use=NameUse.USUAL,
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        ),
                        telecoms=[
                            ContactPoint(
                                value="string",
                                use=ContactPointUse.HOME,
                                period=Period(
                                    start=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                    end=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                ),
                            )
                        ],
                        addresses=[
                            Address(
                                use=AddressUse.HOME,
                                line=["string"],
                                city="string",
                                state="string",
                                postal_code="string",
                                country="string",
                                period=Period(
                                    start=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                    end=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                ),
                            )
                        ],
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                        hipaa_authorization=True,
                    )
                ],
                general_practitioners=[
                    ExternalProvider(
                        name=HumanName(
                            family="string",
                            given=["string"],
                            use=NameUse.USUAL,
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        ),
                        type=ExternalProviderType.PRIMARY,
                        npi="string",
                        telecoms=[
                            ContactPoint(
                                value="string",
                                use=ContactPointUse.HOME,
                                period=Period(
                                    start=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                    end=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                ),
                            )
                        ],
                        addresses=[{"key": "value"}],
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                        canonical_id="string",
                    )
                ],
                filing_order=FilingOrder(
                    coverages=[
                        uuid.UUID(
                            "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                        )
                    ],
                ),
                non_insurance_payers=["string"],
                guarantor=Guarantor(
                    name=HumanName(
                        family="string",
                        given=["string"],
                        use=NameUse.USUAL,
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    ),
                    telecom=ContactPoint(
                        value="string",
                        use=ContactPointUse.HOME,
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    ),
                    email="string",
                    birth_date=datetime.date.fromisoformat(
                        "2023-01-15",
                    ),
                    address=Address(
                        use=AddressUse.HOME,
                        line=["string"],
                        city="string",
                        state="string",
                        postal_code="string",
                        country="string",
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    ),
                ),
                self_pay=True,
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"patients/v1/{jsonable_encoder(id)}/{jsonable_encoder(version)}",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="PUT",
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(Patient, _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    pydantic_v1.parse_obj_as(NotFoundErrorBody, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "VersionConflictError":
                raise VersionConflictError(
                    pydantic_v1.parse_obj_as(VersionConflictErrorBody, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def deactivate(
        self, id: PatientId, version: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Sets a patient as deactivated. The path must contain the most recent version to prevent race conditions. Deactivating historic versions is not supported. Subsequent updates via PUT to the patient will "reactivate" the patient and set the deactivated flag to false.

        Parameters
        ----------
        id : PatientId

        version : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        None

        Examples
        --------
        from candid.client import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.pre_encounter.patients.v_1.deactivate(
            id="string",
            version="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"patients/v1/{jsonable_encoder(id)}/{jsonable_encoder(version)}",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="DELETE",
            request_options=request_options,
        )
        if 200 <= _response.status_code < 300:
            return
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    pydantic_v1.parse_obj_as(NotFoundErrorBody, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "VersionConflictError":
                raise VersionConflictError(
                    pydantic_v1.parse_obj_as(VersionConflictErrorBody, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def search(
        self,
        *,
        mrn: typing.Optional[str] = None,
        similar_name_ordering: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[Patient]:
        """
        Returns a list of Patients based on the search criteria.

        Parameters
        ----------
        mrn : typing.Optional[str]

        similar_name_ordering : typing.Optional[str]
            A string that is used to order similar names in search results.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[Patient]

        Examples
        --------
        from candid.client import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.pre_encounter.patients.v_1.search(
            mrn="string",
            similar_name_ordering="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "patients/v1",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            params={"mrn": mrn, "similar_name_ordering": similar_name_ordering},
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(typing.List[Patient], _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def scan(
        self, *, since: dt.datetime, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[Patient]:
        """
        Scans up to 100 patient updates. The since query parameter is inclusive, and the result list is ordered by updatedAt ascending.

        Parameters
        ----------
        since : dt.datetime

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[Patient]

        Examples
        --------
        import datetime

        from candid.client import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.pre_encounter.patients.v_1.scan(
            since=datetime.datetime.fromisoformat(
                "2024-01-15 09:30:00+00:00",
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "patients/v1/updates/scan",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            params={"since": serialize_datetime(since)},
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(typing.List[Patient], _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncV1Client:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def create(
        self,
        *,
        request: MutablePatient,
        skip_duplicate_check: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Patient:
        """
        Adds a patient. VersionConflictError is returned when the patient's external ID is already in use.

        Parameters
        ----------
        request : MutablePatient

        skip_duplicate_check : typing.Optional[bool]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        Patient

        Examples
        --------
        import asyncio
        import datetime
        import uuid

        from candid.client import AsyncCandidApiClient
        from candid.resources.pre_encounter import (
            Address,
            AddressUse,
            ContactPoint,
            ContactPointUse,
            DisabilityStatus,
            Ethnicity,
            ExternalProvider,
            ExternalProviderType,
            Gender,
            HumanName,
            NameUse,
            Period,
            Race,
            Relationship,
            Sex,
            SexualOrientation,
        )
        from candid.resources.pre_encounter.patients.v_1 import (
            Contact,
            ExternalProvenance,
            FilingOrder,
            Guarantor,
            MaritalStatus,
            MutablePatient,
        )

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.pre_encounter.patients.v_1.create(
                skip_duplicate_check=True,
                request=MutablePatient(
                    name=HumanName(
                        family="string",
                        given=["string"],
                        use=NameUse.USUAL,
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    ),
                    other_names=[
                        HumanName(
                            family="string",
                            given=["string"],
                            use=NameUse.USUAL,
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        )
                    ],
                    gender=Gender.MAN,
                    birth_date=datetime.date.fromisoformat(
                        "2023-01-15",
                    ),
                    social_security_number="string",
                    biological_sex=Sex.FEMALE,
                    sexual_orientation=SexualOrientation.HETEROSEXUAL,
                    race=Race.AMERICAN_INDIAN_OR_ALASKA_NATIVE,
                    ethnicity=Ethnicity.HISPANIC_OR_LATINO,
                    disability_status=DisabilityStatus.DISABLED,
                    marital_status=MaritalStatus.ANNULLED,
                    deceased=datetime.datetime.fromisoformat(
                        "2024-01-15 09:30:00+00:00",
                    ),
                    multiple_birth=1,
                    primary_address=Address(
                        use=AddressUse.HOME,
                        line=["string"],
                        city="string",
                        state="string",
                        postal_code="string",
                        country="string",
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    ),
                    other_addresses=[
                        Address(
                            use=AddressUse.HOME,
                            line=["string"],
                            city="string",
                            state="string",
                            postal_code="string",
                            country="string",
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        )
                    ],
                    primary_telecom=ContactPoint(
                        value="string",
                        use=ContactPointUse.HOME,
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    ),
                    other_telecoms=[
                        ContactPoint(
                            value="string",
                            use=ContactPointUse.HOME,
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        )
                    ],
                    email="string",
                    electronic_communication_opt_in=True,
                    photo="string",
                    language="string",
                    external_provenance=ExternalProvenance(
                        external_id="string",
                        system_name="string",
                    ),
                    contacts=[
                        Contact(
                            relationship=[Relationship.SELF],
                            name=HumanName(
                                family="string",
                                given=["string"],
                                use=NameUse.USUAL,
                                period=Period(
                                    start=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                    end=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                ),
                            ),
                            telecoms=[
                                ContactPoint(
                                    value="string",
                                    use=ContactPointUse.HOME,
                                    period=Period(
                                        start=datetime.date.fromisoformat(
                                            "2023-01-15",
                                        ),
                                        end=datetime.date.fromisoformat(
                                            "2023-01-15",
                                        ),
                                    ),
                                )
                            ],
                            addresses=[
                                Address(
                                    use=AddressUse.HOME,
                                    line=["string"],
                                    city="string",
                                    state="string",
                                    postal_code="string",
                                    country="string",
                                    period=Period(
                                        start=datetime.date.fromisoformat(
                                            "2023-01-15",
                                        ),
                                        end=datetime.date.fromisoformat(
                                            "2023-01-15",
                                        ),
                                    ),
                                )
                            ],
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                            hipaa_authorization=True,
                        )
                    ],
                    general_practitioners=[
                        ExternalProvider(
                            name=HumanName(
                                family="string",
                                given=["string"],
                                use=NameUse.USUAL,
                                period=Period(
                                    start=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                    end=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                ),
                            ),
                            type=ExternalProviderType.PRIMARY,
                            npi="string",
                            telecoms=[
                                ContactPoint(
                                    value="string",
                                    use=ContactPointUse.HOME,
                                    period=Period(
                                        start=datetime.date.fromisoformat(
                                            "2023-01-15",
                                        ),
                                        end=datetime.date.fromisoformat(
                                            "2023-01-15",
                                        ),
                                    ),
                                )
                            ],
                            addresses=[{"key": "value"}],
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                            canonical_id="string",
                        )
                    ],
                    filing_order=FilingOrder(
                        coverages=[
                            uuid.UUID(
                                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                            )
                        ],
                    ),
                    non_insurance_payers=["string"],
                    guarantor=Guarantor(
                        name=HumanName(
                            family="string",
                            given=["string"],
                            use=NameUse.USUAL,
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        ),
                        telecom=ContactPoint(
                            value="string",
                            use=ContactPointUse.HOME,
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        ),
                        email="string",
                        birth_date=datetime.date.fromisoformat(
                            "2023-01-15",
                        ),
                        address=Address(
                            use=AddressUse.HOME,
                            line=["string"],
                            city="string",
                            state="string",
                            postal_code="string",
                            country="string",
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        ),
                    ),
                    self_pay=True,
                ),
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "patients/v1",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="POST",
            params={"skip_duplicate_check": skip_duplicate_check},
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(Patient, _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "VersionConflictError":
                raise VersionConflictError(
                    pydantic_v1.parse_obj_as(VersionConflictErrorBody, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "PotentialDuplicatePatients":
                raise PotentialDuplicatePatients(
                    pydantic_v1.parse_obj_as(PotentialDuplicatePatientsErrorBody, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_multi(
        self,
        *,
        limit: typing.Optional[int] = None,
        mrn: typing.Optional[str] = None,
        page_token: typing.Optional[PageToken] = None,
        sort_field: typing.Optional[PatientSortField] = None,
        sort_direction: typing.Optional[SortDirection] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PatientPage:
        """
        Searches for patients that match the query parameters.

        Parameters
        ----------
        limit : typing.Optional[int]

        mrn : typing.Optional[str]

        page_token : typing.Optional[PageToken]

        sort_field : typing.Optional[PatientSortField]

        sort_direction : typing.Optional[SortDirection]
            Defaults to ascending.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        PatientPage

        Examples
        --------
        import asyncio

        from candid.client import AsyncCandidApiClient
        from candid.resources.pre_encounter import SortDirection

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.pre_encounter.patients.v_1.get_multi(
                limit=1,
                mrn="string",
                page_token="string",
                sort_field="string",
                sort_direction=SortDirection.ASC,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "patients/v1/get_multi",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            params={
                "limit": limit,
                "mrn": mrn,
                "page_token": page_token,
                "sort_field": sort_field,
                "sort_direction": sort_direction,
            },
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(PatientPage, _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get(self, id: PatientId, *, request_options: typing.Optional[RequestOptions] = None) -> Patient:
        """
        Gets a patient.

        Parameters
        ----------
        id : PatientId

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        Patient

        Examples
        --------
        import asyncio

        from candid.client import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.pre_encounter.patients.v_1.get(
                id="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"patients/v1/{jsonable_encoder(id)}",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(Patient, _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    pydantic_v1.parse_obj_as(NotFoundErrorBody, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_history(
        self, id: PatientId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[Patient]:
        """
        Gets a patient along with it's full history. The return list is ordered by version ascending.

        Parameters
        ----------
        id : PatientId

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[Patient]

        Examples
        --------
        import asyncio

        from candid.client import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.pre_encounter.patients.v_1.get_history(
                id="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"patients/v1/{jsonable_encoder(id)}/history",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(typing.List[Patient], _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    pydantic_v1.parse_obj_as(NotFoundErrorBody, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update(
        self,
        id: PatientId,
        version: str,
        *,
        request: MutablePatient,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Patient:
        """
        Updates a patient. The path must contain the most recent version to prevent race conditions. Updating historic versions is not supported.

        Parameters
        ----------
        id : PatientId

        version : str

        request : MutablePatient

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        Patient

        Examples
        --------
        import asyncio
        import datetime
        import uuid

        from candid.client import AsyncCandidApiClient
        from candid.resources.pre_encounter import (
            Address,
            AddressUse,
            ContactPoint,
            ContactPointUse,
            DisabilityStatus,
            Ethnicity,
            ExternalProvider,
            ExternalProviderType,
            Gender,
            HumanName,
            NameUse,
            Period,
            Race,
            Relationship,
            Sex,
            SexualOrientation,
        )
        from candid.resources.pre_encounter.patients.v_1 import (
            Contact,
            ExternalProvenance,
            FilingOrder,
            Guarantor,
            MaritalStatus,
            MutablePatient,
        )

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.pre_encounter.patients.v_1.update(
                id="string",
                version="string",
                request=MutablePatient(
                    name=HumanName(
                        family="string",
                        given=["string"],
                        use=NameUse.USUAL,
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    ),
                    other_names=[
                        HumanName(
                            family="string",
                            given=["string"],
                            use=NameUse.USUAL,
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        )
                    ],
                    gender=Gender.MAN,
                    birth_date=datetime.date.fromisoformat(
                        "2023-01-15",
                    ),
                    social_security_number="string",
                    biological_sex=Sex.FEMALE,
                    sexual_orientation=SexualOrientation.HETEROSEXUAL,
                    race=Race.AMERICAN_INDIAN_OR_ALASKA_NATIVE,
                    ethnicity=Ethnicity.HISPANIC_OR_LATINO,
                    disability_status=DisabilityStatus.DISABLED,
                    marital_status=MaritalStatus.ANNULLED,
                    deceased=datetime.datetime.fromisoformat(
                        "2024-01-15 09:30:00+00:00",
                    ),
                    multiple_birth=1,
                    primary_address=Address(
                        use=AddressUse.HOME,
                        line=["string"],
                        city="string",
                        state="string",
                        postal_code="string",
                        country="string",
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    ),
                    other_addresses=[
                        Address(
                            use=AddressUse.HOME,
                            line=["string"],
                            city="string",
                            state="string",
                            postal_code="string",
                            country="string",
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        )
                    ],
                    primary_telecom=ContactPoint(
                        value="string",
                        use=ContactPointUse.HOME,
                        period=Period(
                            start=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            end=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                        ),
                    ),
                    other_telecoms=[
                        ContactPoint(
                            value="string",
                            use=ContactPointUse.HOME,
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        )
                    ],
                    email="string",
                    electronic_communication_opt_in=True,
                    photo="string",
                    language="string",
                    external_provenance=ExternalProvenance(
                        external_id="string",
                        system_name="string",
                    ),
                    contacts=[
                        Contact(
                            relationship=[Relationship.SELF],
                            name=HumanName(
                                family="string",
                                given=["string"],
                                use=NameUse.USUAL,
                                period=Period(
                                    start=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                    end=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                ),
                            ),
                            telecoms=[
                                ContactPoint(
                                    value="string",
                                    use=ContactPointUse.HOME,
                                    period=Period(
                                        start=datetime.date.fromisoformat(
                                            "2023-01-15",
                                        ),
                                        end=datetime.date.fromisoformat(
                                            "2023-01-15",
                                        ),
                                    ),
                                )
                            ],
                            addresses=[
                                Address(
                                    use=AddressUse.HOME,
                                    line=["string"],
                                    city="string",
                                    state="string",
                                    postal_code="string",
                                    country="string",
                                    period=Period(
                                        start=datetime.date.fromisoformat(
                                            "2023-01-15",
                                        ),
                                        end=datetime.date.fromisoformat(
                                            "2023-01-15",
                                        ),
                                    ),
                                )
                            ],
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                            hipaa_authorization=True,
                        )
                    ],
                    general_practitioners=[
                        ExternalProvider(
                            name=HumanName(
                                family="string",
                                given=["string"],
                                use=NameUse.USUAL,
                                period=Period(
                                    start=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                    end=datetime.date.fromisoformat(
                                        "2023-01-15",
                                    ),
                                ),
                            ),
                            type=ExternalProviderType.PRIMARY,
                            npi="string",
                            telecoms=[
                                ContactPoint(
                                    value="string",
                                    use=ContactPointUse.HOME,
                                    period=Period(
                                        start=datetime.date.fromisoformat(
                                            "2023-01-15",
                                        ),
                                        end=datetime.date.fromisoformat(
                                            "2023-01-15",
                                        ),
                                    ),
                                )
                            ],
                            addresses=[{"key": "value"}],
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                            canonical_id="string",
                        )
                    ],
                    filing_order=FilingOrder(
                        coverages=[
                            uuid.UUID(
                                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                            )
                        ],
                    ),
                    non_insurance_payers=["string"],
                    guarantor=Guarantor(
                        name=HumanName(
                            family="string",
                            given=["string"],
                            use=NameUse.USUAL,
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        ),
                        telecom=ContactPoint(
                            value="string",
                            use=ContactPointUse.HOME,
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        ),
                        email="string",
                        birth_date=datetime.date.fromisoformat(
                            "2023-01-15",
                        ),
                        address=Address(
                            use=AddressUse.HOME,
                            line=["string"],
                            city="string",
                            state="string",
                            postal_code="string",
                            country="string",
                            period=Period(
                                start=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                end=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                            ),
                        ),
                    ),
                    self_pay=True,
                ),
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"patients/v1/{jsonable_encoder(id)}/{jsonable_encoder(version)}",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="PUT",
            json=request,
            request_options=request_options,
            omit=OMIT,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(Patient, _response_json)  # type: ignore
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    pydantic_v1.parse_obj_as(NotFoundErrorBody, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "VersionConflictError":
                raise VersionConflictError(
                    pydantic_v1.parse_obj_as(VersionConflictErrorBody, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def deactivate(
        self, id: PatientId, version: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Sets a patient as deactivated. The path must contain the most recent version to prevent race conditions. Deactivating historic versions is not supported. Subsequent updates via PUT to the patient will "reactivate" the patient and set the deactivated flag to false.

        Parameters
        ----------
        id : PatientId

        version : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from candid.client import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.pre_encounter.patients.v_1.deactivate(
                id="string",
                version="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"patients/v1/{jsonable_encoder(id)}/{jsonable_encoder(version)}",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="DELETE",
            request_options=request_options,
        )
        if 200 <= _response.status_code < 300:
            return
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if "errorName" in _response_json:
            if _response_json["errorName"] == "NotFoundError":
                raise NotFoundError(
                    pydantic_v1.parse_obj_as(NotFoundErrorBody, _response_json["content"])  # type: ignore
                )
            if _response_json["errorName"] == "VersionConflictError":
                raise VersionConflictError(
                    pydantic_v1.parse_obj_as(VersionConflictErrorBody, _response_json["content"])  # type: ignore
                )
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def search(
        self,
        *,
        mrn: typing.Optional[str] = None,
        similar_name_ordering: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[Patient]:
        """
        Returns a list of Patients based on the search criteria.

        Parameters
        ----------
        mrn : typing.Optional[str]

        similar_name_ordering : typing.Optional[str]
            A string that is used to order similar names in search results.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[Patient]

        Examples
        --------
        import asyncio

        from candid.client import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.pre_encounter.patients.v_1.search(
                mrn="string",
                similar_name_ordering="string",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "patients/v1",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            params={"mrn": mrn, "similar_name_ordering": similar_name_ordering},
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(typing.List[Patient], _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def scan(
        self, *, since: dt.datetime, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[Patient]:
        """
        Scans up to 100 patient updates. The since query parameter is inclusive, and the result list is ordered by updatedAt ascending.

        Parameters
        ----------
        since : dt.datetime

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[Patient]

        Examples
        --------
        import asyncio
        import datetime

        from candid.client import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.pre_encounter.patients.v_1.scan(
                since=datetime.datetime.fromisoformat(
                    "2024-01-15 09:30:00+00:00",
                ),
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "patients/v1/updates/scan",
            base_url=self._client_wrapper.get_environment().pre_encounter,
            method="GET",
            params={"since": serialize_datetime(since)},
            request_options=request_options,
        )
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(typing.List[Patient], _response_json)  # type: ignore
        raise ApiError(status_code=_response.status_code, body=_response_json)
