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

import datetime as dt
import typing
import urllib.parse
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.remove_none_from_dict import remove_none_from_dict
from ...errors.unprocessable_entity_error import UnprocessableEntityError
from ...types.ao_e_answer import AoEAnswer
from ...types.appointment_availability_slots import AppointmentAvailabilitySlots
from ...types.appointment_provider import AppointmentProvider
from ...types.area_info import AreaInfo
from ...types.client_facing_appointment import ClientFacingAppointment
from ...types.client_facing_appointment_cancellation_reason import ClientFacingAppointmentCancellationReason
from ...types.client_facing_lab import ClientFacingLab
from ...types.client_facing_lab_test import ClientFacingLabTest
from ...types.client_facing_marker import ClientFacingMarker
from ...types.client_facing_order import ClientFacingOrder
from ...types.consent import Consent
from ...types.get_markers_response import GetMarkersResponse
from ...types.get_orders_response import GetOrdersResponse
from ...types.health_insurance_create_request import HealthInsuranceCreateRequest
from ...types.http_validation_error import HttpValidationError
from ...types.lab_results_metadata import LabResultsMetadata
from ...types.lab_results_raw import LabResultsRaw
from ...types.lab_test_collection_method import LabTestCollectionMethod
from ...types.lab_test_sample_type import LabTestSampleType
from ...types.order_status import OrderStatus
from ...types.patient_address_compatible import PatientAddressCompatible
from ...types.patient_details import PatientDetails
from ...types.physician_create_request import PhysicianCreateRequest
from ...types.post_order_response import PostOrderResponse
from ...types.us_address import UsAddress

try:
    import pydantic.v1 as pydantic  # type: ignore
except ImportError:
    import pydantic  # type: ignore

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


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

    def get(self) -> typing.List[ClientFacingLabTest]:
        """
        GET all the lab tests the team has access to.

        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.get()
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v3/lab_tests"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[ClientFacingLabTest], _response.json())  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def create(
        self,
        *,
        marker_ids: typing.List[int],
        lab_id: int,
        name: str,
        method: LabTestCollectionMethod,
        sample_type: LabTestSampleType,
        description: str,
        fasting: typing.Optional[bool] = OMIT,
    ) -> ClientFacingLabTest:
        """
        Parameters:
            - marker_ids: typing.List[int].

            - lab_id: int.

            - name: str.

            - method: LabTestCollectionMethod.

            - sample_type: LabTestSampleType.

            - description: str.

            - fasting: typing.Optional[bool].
        ---
        from vital import LabTestCollectionMethod, LabTestSampleType
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.create(
            marker_ids=[1],
            lab_id=1,
            name="name",
            method=LabTestCollectionMethod.TESTKIT,
            sample_type=LabTestSampleType.DRIED_BLOOD_SPOT,
            description="description",
        )
        """
        _request: typing.Dict[str, typing.Any] = {
            "marker_ids": marker_ids,
            "lab_id": lab_id,
            "name": name,
            "method": method.value,
            "sample_type": sample_type.value,
            "description": description,
        }
        if fasting is not OMIT:
            _request["fasting"] = fasting
        _response = self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v3/lab_tests"),
            json=jsonable_encoder(_request),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingLabTest, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_markers(
        self,
        *,
        lab_id: typing.Optional[typing.Union[int, typing.List[int]]] = None,
        name: typing.Optional[str] = None,
        page: typing.Optional[int] = None,
        size: typing.Optional[int] = None,
    ) -> GetMarkersResponse:
        """
        GET all the markers for the given lab.

        Parameters:
            - lab_id: typing.Optional[typing.Union[int, typing.List[int]]]. The identifier Vital assigned to a lab partner.

            - name: typing.Optional[str]. The name or test code of an individual biomarker or a panel.

            - page: typing.Optional[int].

            - size: typing.Optional[int].
        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.get_markers()
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v3/lab_tests/markers"),
            params=remove_none_from_dict({"lab_id": lab_id, "name": name, "page": page, "size": size}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(GetMarkersResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_markers_for_lab_test(
        self, lab_test_id: str, *, page: typing.Optional[int] = None, size: typing.Optional[int] = None
    ) -> GetMarkersResponse:
        """
        Parameters:
            - lab_test_id: str.

            - page: typing.Optional[int].

            - size: typing.Optional[int].
        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.get_markers_for_lab_test(
            lab_test_id="lab_test_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/lab_tests/{lab_test_id}/markers"),
            params=remove_none_from_dict({"page": page, "size": size}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(GetMarkersResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_markers_by_lab_and_provider_id(self, provider_id: str, lab_id: int) -> ClientFacingMarker:
        """
        GET a specific marker for the given lab and provider_id

        Parameters:
            - provider_id: str.

            - lab_id: int.
        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.get_markers_by_lab_and_provider_id(
            provider_id="provider_id",
            lab_id=1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"v3/lab_tests/{lab_id}/markers/{provider_id}"
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingMarker, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_labs(self) -> typing.List[ClientFacingLab]:
        """
        GET all the labs.

        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.get_labs()
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v3/lab_tests/labs"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[ClientFacingLab], _response.json())  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_by_id(self, lab_test_id: str) -> ClientFacingLabTest:
        """
        GET all the lab tests the team has access to.

        Parameters:
            - lab_test_id: str.
        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.get_by_id(
            lab_test_id="lab_test_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/lab_tests/{lab_test_id}"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingLabTest, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_phlebotomy_appointment_availability(self, *, request: UsAddress) -> AppointmentAvailabilitySlots:
        """
        Return the available time slots to book an appointment with a phlebotomist
        for the given address and order.

        Parameters:
            - request: UsAddress.
        ---
        from vital import UsAddress
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.get_phlebotomy_appointment_availability(
            request=UsAddress(
                first_line="first_line",
                city="city",
                state="state",
                zip_code="zip_code",
            ),
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", "v3/order/phlebotomy/appointment/availability"
            ),
            json=jsonable_encoder(request),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(AppointmentAvailabilitySlots, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def book_phlebotomy_appointment(self, order_id: str, *, booking_key: str) -> ClientFacingAppointment:
        """
        Book an at-home phlebotomy appointment.

        Parameters:
            - order_id: str. Your Order ID.

            - booking_key: str.
        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.book_phlebotomy_appointment(
            order_id="order_id",
            booking_key="booking_key",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/phlebotomy/appointment/book"
            ),
            json=jsonable_encoder({"booking_key": booking_key}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingAppointment, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def request_phlebotomy_appointment(
        self, order_id: str, *, address: UsAddress, provider: AppointmentProvider
    ) -> ClientFacingAppointment:
        """
        Request an at-home phlebotomy appointment.

        Parameters:
            - order_id: str. Your Order ID.

            - address: UsAddress. At-home phlebotomy appointment address.

            - provider: AppointmentProvider.
        ---
        from vital import AppointmentProvider, UsAddress
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.request_phlebotomy_appointment(
            order_id="order_id",
            address=UsAddress(
                first_line="first_line",
                city="city",
                state="state",
                zip_code="zip_code",
            ),
            provider=AppointmentProvider.GETLABS,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/phlebotomy/appointment/request"
            ),
            json=jsonable_encoder({"address": address, "provider": provider}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingAppointment, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def reschedule_phlebotomy_appointment(self, order_id: str, *, booking_key: str) -> ClientFacingAppointment:
        """
        Reschedule a previously booked at-home phlebotomy appointment.

        Parameters:
            - order_id: str. Your Order ID.

            - booking_key: str.
        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.reschedule_phlebotomy_appointment(
            order_id="order_id",
            booking_key="booking_key",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "PATCH",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/phlebotomy/appointment/reschedule"
            ),
            json=jsonable_encoder({"booking_key": booking_key}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingAppointment, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def cancel_phlebotomy_appointment(
        self, order_id: str, *, cancellation_reason_id: str, notes: typing.Optional[str] = OMIT
    ) -> ClientFacingAppointment:
        """
        Cancel a previously booked at-home phlebotomy appointment.

        Parameters:
            - order_id: str. Your Order ID.

            - cancellation_reason_id: str.

            - notes: typing.Optional[str].
        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.cancel_phlebotomy_appointment(
            order_id="order_id",
            cancellation_reason_id="cancellation_reason_id",
        )
        """
        _request: typing.Dict[str, typing.Any] = {"cancellation_reason_id": cancellation_reason_id}
        if notes is not OMIT:
            _request["notes"] = notes
        _response = self._client_wrapper.httpx_client.request(
            "PATCH",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/phlebotomy/appointment/cancel"
            ),
            json=jsonable_encoder(_request),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingAppointment, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_phlebotomy_appointment_cancellation_reason(self) -> typing.List[ClientFacingAppointmentCancellationReason]:
        """
        Get the list of reasons for cancelling an at-home phlebotomy appointment.

        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.get_phlebotomy_appointment_cancellation_reason()
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", "v3/order/phlebotomy/appointment/cancellation-reasons"
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[ClientFacingAppointmentCancellationReason], _response.json())  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_phlebotomy_appointment(self, order_id: str) -> ClientFacingAppointment:
        """
        Get the appointment associated with an order.

        Parameters:
            - order_id: str. Your Order ID.
        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.get_phlebotomy_appointment(
            order_id="order_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/phlebotomy/appointment"
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingAppointment, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_area_info(self, *, zip_code: str) -> AreaInfo:
        """
        GET information about an area with respect to lab-testing.

        Information returned:

        - Whether a given zip code is served by our Phlebotomy network.

        Parameters:
            - zip_code: str. Zip code of the area to check
        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.get_area_info(
            zip_code="zip_code",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v3/order/area/info"),
            params=remove_none_from_dict({"zip_code": zip_code}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(AreaInfo, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_result_pdf(self, order_id: str) -> typing.Iterator[bytes]:
        """
        This endpoint returns the lab results for the order.

        Parameters:
            - order_id: str.
        """
        with self._client_wrapper.httpx_client.stream(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/result/pdf"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        ) as _response:
            if 200 <= _response.status_code < 300:
                for _chunk in _response.iter_bytes():
                    yield _chunk
                return
            _response.read()
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    pydantic.parse_obj_as(HttpValidationError, _response.json())  # type: ignore
                )
            try:
                _response_json = _response.json()
            except JSONDecodeError:
                raise ApiError(status_code=_response.status_code, body=_response.text)
            raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_result_metadata(self, order_id: str) -> LabResultsMetadata:
        """
        Return metadata related to order results, such as lab metadata,
        provider and sample dates.

        Parameters:
            - order_id: str.
        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.get_result_metadata(
            order_id="order_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/result/metadata"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(LabResultsMetadata, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_result_raw(self, order_id: str) -> LabResultsRaw:
        """
        Return both metadata and raw json test data

        Parameters:
            - order_id: str.
        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.get_result_raw(
            order_id="order_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/result"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(LabResultsRaw, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_order_requistion_pdf(self, order_id: str) -> typing.Iterator[bytes]:
        """
        GET requisition pdf for an order

        Parameters:
            - order_id: str. Your Order ID.
        """
        with self._client_wrapper.httpx_client.stream(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/requisition/pdf"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        ) as _response:
            if 200 <= _response.status_code < 300:
                for _chunk in _response.iter_bytes():
                    yield _chunk
                return
            _response.read()
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    pydantic.parse_obj_as(HttpValidationError, _response.json())  # type: ignore
                )
            try:
                _response_json = _response.json()
            except JSONDecodeError:
                raise ApiError(status_code=_response.status_code, body=_response.text)
            raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_order(self, order_id: str) -> ClientFacingOrder:
        """
        GET individual order by ID.

        Parameters:
            - order_id: str. Your Order ID.
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingOrder, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def create_order(
        self,
        *,
        user_id: str,
        lab_test_id: str,
        physician: typing.Optional[PhysicianCreateRequest] = OMIT,
        health_insurance: typing.Optional[HealthInsuranceCreateRequest] = OMIT,
        priority: typing.Optional[bool] = OMIT,
        consents: typing.Optional[typing.List[Consent]] = OMIT,
        activate_by: typing.Optional[str] = OMIT,
        aoe_answers: typing.Optional[typing.List[AoEAnswer]] = OMIT,
        patient_details: PatientDetails,
        patient_address: PatientAddressCompatible,
    ) -> PostOrderResponse:
        """
        POST create new order

        Parameters:
            - user_id: str.

            - lab_test_id: str.

            - physician: typing.Optional[PhysicianCreateRequest].

            - health_insurance: typing.Optional[HealthInsuranceCreateRequest].

            - priority: typing.Optional[bool]. Defines whether order is priority or not. For some labs, this refers to a STAT order.

            - consents: typing.Optional[typing.List[Consent]].

            - activate_by: typing.Optional[str]. Schedule an Order to be processed in a future date.

            - aoe_answers: typing.Optional[typing.List[AoEAnswer]].

            - patient_details: PatientDetails.

            - patient_address: PatientAddressCompatible.
        """
        _request: typing.Dict[str, typing.Any] = {
            "user_id": user_id,
            "lab_test_id": lab_test_id,
            "patient_details": patient_details,
            "patient_address": patient_address,
        }
        if physician is not OMIT:
            _request["physician"] = physician
        if health_insurance is not OMIT:
            _request["health_insurance"] = health_insurance
        if priority is not OMIT:
            _request["priority"] = priority
        if consents is not OMIT:
            _request["consents"] = consents
        if activate_by is not OMIT:
            _request["activate_by"] = activate_by
        if aoe_answers is not OMIT:
            _request["aoe_answers"] = aoe_answers
        _response = self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v3/order"),
            json=jsonable_encoder(_request),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(PostOrderResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def cancel_order(self, order_id: str) -> PostOrderResponse:
        """
        POST cancel order

        Parameters:
            - order_id: str. Your Order ID.
        """
        _response = self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/cancel"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(PostOrderResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def simulate_order_process(
        self, order_id: str, *, final_status: typing.Optional[OrderStatus] = None, delay: typing.Optional[int] = None
    ) -> typing.Any:
        """
        Get available test kits.

        Parameters:
            - order_id: str.

            - final_status: typing.Optional[OrderStatus].

            - delay: typing.Optional[int].
        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.simulate_order_process(
            order_id="order_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/test"),
            params=remove_none_from_dict({"final_status": final_status, "delay": delay}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Any, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_orders(
        self,
        *,
        start_date: typing.Optional[dt.datetime] = None,
        end_date: typing.Optional[dt.datetime] = None,
        user_id: typing.Optional[str] = None,
        patient_name: typing.Optional[str] = None,
        order_ids: typing.Optional[typing.Union[str, typing.List[str]]] = None,
        page: typing.Optional[int] = None,
        size: typing.Optional[int] = None,
    ) -> GetOrdersResponse:
        """
        GET many orders with filters.

        Parameters:
            - start_date: typing.Optional[dt.datetime]. Date from in YYYY-MM-DD or ISO formatted date time. If a date is provided without a time, the time will be set to 00:00:00

            - end_date: typing.Optional[dt.datetime]. Date to YYYY-MM-DD or ISO formatted date time. If a date is provided without a time, the time will be set to 23:59:59

            - user_id: typing.Optional[str]. Filter by user ID.

            - patient_name: typing.Optional[str]. Filter by patient name.

            - order_ids: typing.Optional[typing.Union[str, typing.List[str]]]. Filter by order ids.

            - page: typing.Optional[int].

            - size: typing.Optional[int].
        ---
        from vital.client import Vital

        client = Vital(
            api_key="YOUR_API_KEY",
        )
        client.lab_tests.get_orders()
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v3/orders"),
            params=remove_none_from_dict(
                {
                    "start_date": serialize_datetime(start_date) if start_date is not None else None,
                    "end_date": serialize_datetime(end_date) if end_date is not None else None,
                    "user_id": user_id,
                    "patient_name": patient_name,
                    "order_ids": order_ids,
                    "page": page,
                    "size": size,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(GetOrdersResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


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

    async def get(self) -> typing.List[ClientFacingLabTest]:
        """
        GET all the lab tests the team has access to.

        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.get()
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v3/lab_tests"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[ClientFacingLabTest], _response.json())  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def create(
        self,
        *,
        marker_ids: typing.List[int],
        lab_id: int,
        name: str,
        method: LabTestCollectionMethod,
        sample_type: LabTestSampleType,
        description: str,
        fasting: typing.Optional[bool] = OMIT,
    ) -> ClientFacingLabTest:
        """
        Parameters:
            - marker_ids: typing.List[int].

            - lab_id: int.

            - name: str.

            - method: LabTestCollectionMethod.

            - sample_type: LabTestSampleType.

            - description: str.

            - fasting: typing.Optional[bool].
        ---
        from vital import LabTestCollectionMethod, LabTestSampleType
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.create(
            marker_ids=[1],
            lab_id=1,
            name="name",
            method=LabTestCollectionMethod.TESTKIT,
            sample_type=LabTestSampleType.DRIED_BLOOD_SPOT,
            description="description",
        )
        """
        _request: typing.Dict[str, typing.Any] = {
            "marker_ids": marker_ids,
            "lab_id": lab_id,
            "name": name,
            "method": method.value,
            "sample_type": sample_type.value,
            "description": description,
        }
        if fasting is not OMIT:
            _request["fasting"] = fasting
        _response = await self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v3/lab_tests"),
            json=jsonable_encoder(_request),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingLabTest, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_markers(
        self,
        *,
        lab_id: typing.Optional[typing.Union[int, typing.List[int]]] = None,
        name: typing.Optional[str] = None,
        page: typing.Optional[int] = None,
        size: typing.Optional[int] = None,
    ) -> GetMarkersResponse:
        """
        GET all the markers for the given lab.

        Parameters:
            - lab_id: typing.Optional[typing.Union[int, typing.List[int]]]. The identifier Vital assigned to a lab partner.

            - name: typing.Optional[str]. The name or test code of an individual biomarker or a panel.

            - page: typing.Optional[int].

            - size: typing.Optional[int].
        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.get_markers()
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v3/lab_tests/markers"),
            params=remove_none_from_dict({"lab_id": lab_id, "name": name, "page": page, "size": size}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(GetMarkersResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_markers_for_lab_test(
        self, lab_test_id: str, *, page: typing.Optional[int] = None, size: typing.Optional[int] = None
    ) -> GetMarkersResponse:
        """
        Parameters:
            - lab_test_id: str.

            - page: typing.Optional[int].

            - size: typing.Optional[int].
        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.get_markers_for_lab_test(
            lab_test_id="lab_test_id",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/lab_tests/{lab_test_id}/markers"),
            params=remove_none_from_dict({"page": page, "size": size}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(GetMarkersResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_markers_by_lab_and_provider_id(self, provider_id: str, lab_id: int) -> ClientFacingMarker:
        """
        GET a specific marker for the given lab and provider_id

        Parameters:
            - provider_id: str.

            - lab_id: int.
        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.get_markers_by_lab_and_provider_id(
            provider_id="provider_id",
            lab_id=1,
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"v3/lab_tests/{lab_id}/markers/{provider_id}"
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingMarker, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_labs(self) -> typing.List[ClientFacingLab]:
        """
        GET all the labs.

        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.get_labs()
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v3/lab_tests/labs"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[ClientFacingLab], _response.json())  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_by_id(self, lab_test_id: str) -> ClientFacingLabTest:
        """
        GET all the lab tests the team has access to.

        Parameters:
            - lab_test_id: str.
        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.get_by_id(
            lab_test_id="lab_test_id",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/lab_tests/{lab_test_id}"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingLabTest, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_phlebotomy_appointment_availability(self, *, request: UsAddress) -> AppointmentAvailabilitySlots:
        """
        Return the available time slots to book an appointment with a phlebotomist
        for the given address and order.

        Parameters:
            - request: UsAddress.
        ---
        from vital import UsAddress
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.get_phlebotomy_appointment_availability(
            request=UsAddress(
                first_line="first_line",
                city="city",
                state="state",
                zip_code="zip_code",
            ),
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", "v3/order/phlebotomy/appointment/availability"
            ),
            json=jsonable_encoder(request),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(AppointmentAvailabilitySlots, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def book_phlebotomy_appointment(self, order_id: str, *, booking_key: str) -> ClientFacingAppointment:
        """
        Book an at-home phlebotomy appointment.

        Parameters:
            - order_id: str. Your Order ID.

            - booking_key: str.
        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.book_phlebotomy_appointment(
            order_id="order_id",
            booking_key="booking_key",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/phlebotomy/appointment/book"
            ),
            json=jsonable_encoder({"booking_key": booking_key}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingAppointment, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def request_phlebotomy_appointment(
        self, order_id: str, *, address: UsAddress, provider: AppointmentProvider
    ) -> ClientFacingAppointment:
        """
        Request an at-home phlebotomy appointment.

        Parameters:
            - order_id: str. Your Order ID.

            - address: UsAddress. At-home phlebotomy appointment address.

            - provider: AppointmentProvider.
        ---
        from vital import AppointmentProvider, UsAddress
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.request_phlebotomy_appointment(
            order_id="order_id",
            address=UsAddress(
                first_line="first_line",
                city="city",
                state="state",
                zip_code="zip_code",
            ),
            provider=AppointmentProvider.GETLABS,
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/phlebotomy/appointment/request"
            ),
            json=jsonable_encoder({"address": address, "provider": provider}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingAppointment, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def reschedule_phlebotomy_appointment(self, order_id: str, *, booking_key: str) -> ClientFacingAppointment:
        """
        Reschedule a previously booked at-home phlebotomy appointment.

        Parameters:
            - order_id: str. Your Order ID.

            - booking_key: str.
        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.reschedule_phlebotomy_appointment(
            order_id="order_id",
            booking_key="booking_key",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "PATCH",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/phlebotomy/appointment/reschedule"
            ),
            json=jsonable_encoder({"booking_key": booking_key}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingAppointment, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def cancel_phlebotomy_appointment(
        self, order_id: str, *, cancellation_reason_id: str, notes: typing.Optional[str] = OMIT
    ) -> ClientFacingAppointment:
        """
        Cancel a previously booked at-home phlebotomy appointment.

        Parameters:
            - order_id: str. Your Order ID.

            - cancellation_reason_id: str.

            - notes: typing.Optional[str].
        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.cancel_phlebotomy_appointment(
            order_id="order_id",
            cancellation_reason_id="cancellation_reason_id",
        )
        """
        _request: typing.Dict[str, typing.Any] = {"cancellation_reason_id": cancellation_reason_id}
        if notes is not OMIT:
            _request["notes"] = notes
        _response = await self._client_wrapper.httpx_client.request(
            "PATCH",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/phlebotomy/appointment/cancel"
            ),
            json=jsonable_encoder(_request),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingAppointment, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_phlebotomy_appointment_cancellation_reason(
        self,
    ) -> typing.List[ClientFacingAppointmentCancellationReason]:
        """
        Get the list of reasons for cancelling an at-home phlebotomy appointment.

        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.get_phlebotomy_appointment_cancellation_reason()
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", "v3/order/phlebotomy/appointment/cancellation-reasons"
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[ClientFacingAppointmentCancellationReason], _response.json())  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_phlebotomy_appointment(self, order_id: str) -> ClientFacingAppointment:
        """
        Get the appointment associated with an order.

        Parameters:
            - order_id: str. Your Order ID.
        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.get_phlebotomy_appointment(
            order_id="order_id",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/phlebotomy/appointment"
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingAppointment, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_area_info(self, *, zip_code: str) -> AreaInfo:
        """
        GET information about an area with respect to lab-testing.

        Information returned:

        - Whether a given zip code is served by our Phlebotomy network.

        Parameters:
            - zip_code: str. Zip code of the area to check
        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.get_area_info(
            zip_code="zip_code",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v3/order/area/info"),
            params=remove_none_from_dict({"zip_code": zip_code}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(AreaInfo, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_result_pdf(self, order_id: str) -> typing.AsyncIterator[bytes]:
        """
        This endpoint returns the lab results for the order.

        Parameters:
            - order_id: str.
        """
        async with self._client_wrapper.httpx_client.stream(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/result/pdf"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        ) as _response:
            if 200 <= _response.status_code < 300:
                async for _chunk in _response.aiter_bytes():
                    yield _chunk
                return
            await _response.aread()
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    pydantic.parse_obj_as(HttpValidationError, _response.json())  # type: ignore
                )
            try:
                _response_json = _response.json()
            except JSONDecodeError:
                raise ApiError(status_code=_response.status_code, body=_response.text)
            raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_result_metadata(self, order_id: str) -> LabResultsMetadata:
        """
        Return metadata related to order results, such as lab metadata,
        provider and sample dates.

        Parameters:
            - order_id: str.
        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.get_result_metadata(
            order_id="order_id",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/result/metadata"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(LabResultsMetadata, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_result_raw(self, order_id: str) -> LabResultsRaw:
        """
        Return both metadata and raw json test data

        Parameters:
            - order_id: str.
        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.get_result_raw(
            order_id="order_id",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/result"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(LabResultsRaw, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_order_requistion_pdf(self, order_id: str) -> typing.AsyncIterator[bytes]:
        """
        GET requisition pdf for an order

        Parameters:
            - order_id: str. Your Order ID.
        """
        async with self._client_wrapper.httpx_client.stream(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/requisition/pdf"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        ) as _response:
            if 200 <= _response.status_code < 300:
                async for _chunk in _response.aiter_bytes():
                    yield _chunk
                return
            await _response.aread()
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    pydantic.parse_obj_as(HttpValidationError, _response.json())  # type: ignore
                )
            try:
                _response_json = _response.json()
            except JSONDecodeError:
                raise ApiError(status_code=_response.status_code, body=_response.text)
            raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_order(self, order_id: str) -> ClientFacingOrder:
        """
        GET individual order by ID.

        Parameters:
            - order_id: str. Your Order ID.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(ClientFacingOrder, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def create_order(
        self,
        *,
        user_id: str,
        lab_test_id: str,
        physician: typing.Optional[PhysicianCreateRequest] = OMIT,
        health_insurance: typing.Optional[HealthInsuranceCreateRequest] = OMIT,
        priority: typing.Optional[bool] = OMIT,
        consents: typing.Optional[typing.List[Consent]] = OMIT,
        activate_by: typing.Optional[str] = OMIT,
        aoe_answers: typing.Optional[typing.List[AoEAnswer]] = OMIT,
        patient_details: PatientDetails,
        patient_address: PatientAddressCompatible,
    ) -> PostOrderResponse:
        """
        POST create new order

        Parameters:
            - user_id: str.

            - lab_test_id: str.

            - physician: typing.Optional[PhysicianCreateRequest].

            - health_insurance: typing.Optional[HealthInsuranceCreateRequest].

            - priority: typing.Optional[bool]. Defines whether order is priority or not. For some labs, this refers to a STAT order.

            - consents: typing.Optional[typing.List[Consent]].

            - activate_by: typing.Optional[str]. Schedule an Order to be processed in a future date.

            - aoe_answers: typing.Optional[typing.List[AoEAnswer]].

            - patient_details: PatientDetails.

            - patient_address: PatientAddressCompatible.
        """
        _request: typing.Dict[str, typing.Any] = {
            "user_id": user_id,
            "lab_test_id": lab_test_id,
            "patient_details": patient_details,
            "patient_address": patient_address,
        }
        if physician is not OMIT:
            _request["physician"] = physician
        if health_insurance is not OMIT:
            _request["health_insurance"] = health_insurance
        if priority is not OMIT:
            _request["priority"] = priority
        if consents is not OMIT:
            _request["consents"] = consents
        if activate_by is not OMIT:
            _request["activate_by"] = activate_by
        if aoe_answers is not OMIT:
            _request["aoe_answers"] = aoe_answers
        _response = await self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v3/order"),
            json=jsonable_encoder(_request),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(PostOrderResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def cancel_order(self, order_id: str) -> PostOrderResponse:
        """
        POST cancel order

        Parameters:
            - order_id: str. Your Order ID.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/cancel"),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(PostOrderResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def simulate_order_process(
        self, order_id: str, *, final_status: typing.Optional[OrderStatus] = None, delay: typing.Optional[int] = None
    ) -> typing.Any:
        """
        Get available test kits.

        Parameters:
            - order_id: str.

            - final_status: typing.Optional[OrderStatus].

            - delay: typing.Optional[int].
        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.simulate_order_process(
            order_id="order_id",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            "POST",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v3/order/{order_id}/test"),
            params=remove_none_from_dict({"final_status": final_status, "delay": delay}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Any, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_orders(
        self,
        *,
        start_date: typing.Optional[dt.datetime] = None,
        end_date: typing.Optional[dt.datetime] = None,
        user_id: typing.Optional[str] = None,
        patient_name: typing.Optional[str] = None,
        order_ids: typing.Optional[typing.Union[str, typing.List[str]]] = None,
        page: typing.Optional[int] = None,
        size: typing.Optional[int] = None,
    ) -> GetOrdersResponse:
        """
        GET many orders with filters.

        Parameters:
            - start_date: typing.Optional[dt.datetime]. Date from in YYYY-MM-DD or ISO formatted date time. If a date is provided without a time, the time will be set to 00:00:00

            - end_date: typing.Optional[dt.datetime]. Date to YYYY-MM-DD or ISO formatted date time. If a date is provided without a time, the time will be set to 23:59:59

            - user_id: typing.Optional[str]. Filter by user ID.

            - patient_name: typing.Optional[str]. Filter by patient name.

            - order_ids: typing.Optional[typing.Union[str, typing.List[str]]]. Filter by order ids.

            - page: typing.Optional[int].

            - size: typing.Optional[int].
        ---
        from vital.client import AsyncVital

        client = AsyncVital(
            api_key="YOUR_API_KEY",
        )
        await client.lab_tests.get_orders()
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v3/orders"),
            params=remove_none_from_dict(
                {
                    "start_date": serialize_datetime(start_date) if start_date is not None else None,
                    "end_date": serialize_datetime(end_date) if end_date is not None else None,
                    "user_id": user_id,
                    "patient_name": patient_name,
                    "order_ids": order_ids,
                    "page": page,
                    "size": size,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(GetOrdersResponse, _response.json())  # type: ignore
        if _response.status_code == 422:
            raise UnprocessableEntityError(pydantic.parse_obj_as(HttpValidationError, _response.json()))  # type: ignore
        try:
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
