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

from __future__ import annotations

import os
import typing

import httpx
from .core.api_error import ApiError
from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from .environment import SamsaraEnvironment

if typing.TYPE_CHECKING:
    from .addresses.client import AddressesClient, AsyncAddressesClient
    from .alerts.client import AlertsClient, AsyncAlertsClient
    from .assets.client import AssetsClient, AsyncAssetsClient
    from .attributes.client import AsyncAttributesClient, AttributesClient
    from .auth_token_for_driver.client import AsyncAuthTokenForDriverClient, AuthTokenForDriverClient
    from .beta_ap_is.client import AsyncBetaApIsClient, BetaApIsClient
    from .carrier_proposed_assignments.client import (
        AsyncCarrierProposedAssignmentsClient,
        CarrierProposedAssignmentsClient,
    )
    from .coaching.client import AsyncCoachingClient, CoachingClient
    from .contacts.client import AsyncContactsClient, ContactsClient
    from .documents.client import AsyncDocumentsClient, DocumentsClient
    from .driver_qr_codes.client import AsyncDriverQrCodesClient, DriverQrCodesClient
    from .driver_trailer_assignments.client import AsyncDriverTrailerAssignmentsClient, DriverTrailerAssignmentsClient
    from .driver_vehicle_assignments.client import AsyncDriverVehicleAssignmentsClient, DriverVehicleAssignmentsClient
    from .drivers.client import AsyncDriversClient, DriversClient
    from .equipment.client import AsyncEquipmentClient, EquipmentClient
    from .fleet.client import AsyncFleetClient, FleetClient
    from .forms.client import AsyncFormsClient, FormsClient
    from .fuel_and_energy.client import AsyncFuelAndEnergyClient, FuelAndEnergyClient
    from .gateways.client import AsyncGatewaysClient, GatewaysClient
    from .hours_of_service.client import AsyncHoursOfServiceClient, HoursOfServiceClient
    from .hubs.client import AsyncHubsClient, HubsClient
    from .idling.client import AsyncIdlingClient, IdlingClient
    from .ifta.client import AsyncIftaClient, IftaClient
    from .industrial.client import AsyncIndustrialClient, IndustrialClient
    from .issues.client import AsyncIssuesClient, IssuesClient
    from .legacy.client import AsyncLegacyClient, LegacyClient
    from .legacy_ap_is.client import AsyncLegacyApIsClient, LegacyApIsClient
    from .live_sharing_links.client import AsyncLiveSharingLinksClient, LiveSharingLinksClient
    from .location_and_speed.client import AsyncLocationAndSpeedClient, LocationAndSpeedClient
    from .maintenance.client import AsyncMaintenanceClient, MaintenanceClient
    from .media.client import AsyncMediaClient, MediaClient
    from .messages.client import AsyncMessagesClient, MessagesClient
    from .organization_info.client import AsyncOrganizationInfoClient, OrganizationInfoClient
    from .plans.client import AsyncPlansClient, PlansClient
    from .preview_ap_is.client import AsyncPreviewApIsClient, PreviewApIsClient
    from .route_events.client import AsyncRouteEventsClient, RouteEventsClient
    from .routes.client import AsyncRoutesClient, RoutesClient
    from .safety.client import AsyncSafetyClient, SafetyClient
    from .sensors.client import AsyncSensorsClient, SensorsClient
    from .settings.client import AsyncSettingsClient, SettingsClient
    from .speeding_intervals.client import AsyncSpeedingIntervalsClient, SpeedingIntervalsClient
    from .tachograph_eu_only.client import AsyncTachographEuOnlyClient, TachographEuOnlyClient
    from .tags.client import AsyncTagsClient, TagsClient
    from .trailer_assignments.client import AsyncTrailerAssignmentsClient, TrailerAssignmentsClient
    from .trailers.client import AsyncTrailersClient, TrailersClient
    from .training_assignments.client import AsyncTrainingAssignmentsClient, TrainingAssignmentsClient
    from .training_courses.client import AsyncTrainingCoursesClient, TrainingCoursesClient
    from .trips.client import AsyncTripsClient, TripsClient
    from .users.client import AsyncUsersClient, UsersClient
    from .vehicle_locations.client import AsyncVehicleLocationsClient, VehicleLocationsClient
    from .vehicle_stats.client import AsyncVehicleStatsClient, VehicleStatsClient
    from .vehicles.client import AsyncVehiclesClient, VehiclesClient
    from .webhooks.client import AsyncWebhooksClient, WebhooksClient
    from .work_orders.client import AsyncWorkOrdersClient, WorkOrdersClient


class Samsara:
    """
    Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.

    Parameters
    ----------
    base_url : typing.Optional[str]
        The base url to use for requests from the client.

    environment : SamsaraEnvironment
        The environment to use for requests from the client. from .environment import SamsaraEnvironment



        Defaults to SamsaraEnvironment.PRODUCTION_API



    token : typing.Optional[typing.Union[str, typing.Callable[[], str]]]
    headers : typing.Optional[typing.Dict[str, str]]
        Additional headers to send with every request.

    timeout : typing.Optional[float]
        The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.

    follow_redirects : typing.Optional[bool]
        Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.

    httpx_client : typing.Optional[httpx.Client]
        The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.

    Examples
    --------
    from samsara import Samsara

    client = Samsara(
        token="YOUR_TOKEN",
    )
    """

    def __init__(
        self,
        *,
        base_url: typing.Optional[str] = None,
        environment: SamsaraEnvironment = SamsaraEnvironment.PRODUCTION_API,
        token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = os.getenv("SAMSARA_API_KEY"),
        headers: typing.Optional[typing.Dict[str, str]] = None,
        timeout: typing.Optional[float] = None,
        follow_redirects: typing.Optional[bool] = True,
        httpx_client: typing.Optional[httpx.Client] = None,
    ):
        _defaulted_timeout = (
            timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read
        )
        if token is None:
            raise ApiError(body="The client must be instantiated be either passing in token or setting SAMSARA_API_KEY")
        self._client_wrapper = SyncClientWrapper(
            base_url=_get_base_url(base_url=base_url, environment=environment),
            token=token,
            headers=headers,
            httpx_client=httpx_client
            if httpx_client is not None
            else httpx.Client(timeout=_defaulted_timeout, follow_redirects=follow_redirects)
            if follow_redirects is not None
            else httpx.Client(timeout=_defaulted_timeout),
            timeout=_defaulted_timeout,
        )
        self._addresses: typing.Optional[AddressesClient] = None
        self._alerts: typing.Optional[AlertsClient] = None
        self._assets: typing.Optional[AssetsClient] = None
        self._beta_ap_is: typing.Optional[BetaApIsClient] = None
        self._location_and_speed: typing.Optional[LocationAndSpeedClient] = None
        self._attributes: typing.Optional[AttributesClient] = None
        self._media: typing.Optional[MediaClient] = None
        self._coaching: typing.Optional[CoachingClient] = None
        self._contacts: typing.Optional[ContactsClient] = None
        self._maintenance: typing.Optional[MaintenanceClient] = None
        self._fuel_and_energy: typing.Optional[FuelAndEnergyClient] = None
        self._driver_trailer_assignments: typing.Optional[DriverTrailerAssignmentsClient] = None
        self._driver_qr_codes: typing.Optional[DriverQrCodesClient] = None
        self._carrier_proposed_assignments: typing.Optional[CarrierProposedAssignmentsClient] = None
        self._legacy_ap_is: typing.Optional[LegacyApIsClient] = None
        self._documents: typing.Optional[DocumentsClient] = None
        self._driver_vehicle_assignments: typing.Optional[DriverVehicleAssignmentsClient] = None
        self._drivers: typing.Optional[DriversClient] = None
        self._auth_token_for_driver: typing.Optional[AuthTokenForDriverClient] = None
        self._tachograph_eu_only: typing.Optional[TachographEuOnlyClient] = None
        self._equipment: typing.Optional[EquipmentClient] = None
        self._hours_of_service: typing.Optional[HoursOfServiceClient] = None
        self._ifta: typing.Optional[IftaClient] = None
        self._routes: typing.Optional[RoutesClient] = None
        self._settings: typing.Optional[SettingsClient] = None
        self._trailers: typing.Optional[TrailersClient] = None
        self._vehicles: typing.Optional[VehiclesClient] = None
        self._vehicle_locations: typing.Optional[VehicleLocationsClient] = None
        self._vehicle_stats: typing.Optional[VehicleStatsClient] = None
        self._forms: typing.Optional[FormsClient] = None
        self._gateways: typing.Optional[GatewaysClient] = None
        self._hubs: typing.Optional[HubsClient] = None
        self._plans: typing.Optional[PlansClient] = None
        self._idling: typing.Optional[IdlingClient] = None
        self._industrial: typing.Optional[IndustrialClient] = None
        self._issues: typing.Optional[IssuesClient] = None
        self._live_sharing_links: typing.Optional[LiveSharingLinksClient] = None
        self._work_orders: typing.Optional[WorkOrdersClient] = None
        self._organization_info: typing.Optional[OrganizationInfoClient] = None
        self._preview_ap_is: typing.Optional[PreviewApIsClient] = None
        self._route_events: typing.Optional[RouteEventsClient] = None
        self._safety: typing.Optional[SafetyClient] = None
        self._speeding_intervals: typing.Optional[SpeedingIntervalsClient] = None
        self._tags: typing.Optional[TagsClient] = None
        self._training_assignments: typing.Optional[TrainingAssignmentsClient] = None
        self._training_courses: typing.Optional[TrainingCoursesClient] = None
        self._trips: typing.Optional[TripsClient] = None
        self._users: typing.Optional[UsersClient] = None
        self._legacy: typing.Optional[LegacyClient] = None
        self._messages: typing.Optional[MessagesClient] = None
        self._trailer_assignments: typing.Optional[TrailerAssignmentsClient] = None
        self._sensors: typing.Optional[SensorsClient] = None
        self._webhooks: typing.Optional[WebhooksClient] = None
        self._fleet: typing.Optional[FleetClient] = None

    @property
    def addresses(self):
        if self._addresses is None:
            from .addresses.client import AddressesClient  # noqa: E402

            self._addresses = AddressesClient(client_wrapper=self._client_wrapper)
        return self._addresses

    @property
    def alerts(self):
        if self._alerts is None:
            from .alerts.client import AlertsClient  # noqa: E402

            self._alerts = AlertsClient(client_wrapper=self._client_wrapper)
        return self._alerts

    @property
    def assets(self):
        if self._assets is None:
            from .assets.client import AssetsClient  # noqa: E402

            self._assets = AssetsClient(client_wrapper=self._client_wrapper)
        return self._assets

    @property
    def beta_ap_is(self):
        if self._beta_ap_is is None:
            from .beta_ap_is.client import BetaApIsClient  # noqa: E402

            self._beta_ap_is = BetaApIsClient(client_wrapper=self._client_wrapper)
        return self._beta_ap_is

    @property
    def location_and_speed(self):
        if self._location_and_speed is None:
            from .location_and_speed.client import LocationAndSpeedClient  # noqa: E402

            self._location_and_speed = LocationAndSpeedClient(client_wrapper=self._client_wrapper)
        return self._location_and_speed

    @property
    def attributes(self):
        if self._attributes is None:
            from .attributes.client import AttributesClient  # noqa: E402

            self._attributes = AttributesClient(client_wrapper=self._client_wrapper)
        return self._attributes

    @property
    def media(self):
        if self._media is None:
            from .media.client import MediaClient  # noqa: E402

            self._media = MediaClient(client_wrapper=self._client_wrapper)
        return self._media

    @property
    def coaching(self):
        if self._coaching is None:
            from .coaching.client import CoachingClient  # noqa: E402

            self._coaching = CoachingClient(client_wrapper=self._client_wrapper)
        return self._coaching

    @property
    def contacts(self):
        if self._contacts is None:
            from .contacts.client import ContactsClient  # noqa: E402

            self._contacts = ContactsClient(client_wrapper=self._client_wrapper)
        return self._contacts

    @property
    def maintenance(self):
        if self._maintenance is None:
            from .maintenance.client import MaintenanceClient  # noqa: E402

            self._maintenance = MaintenanceClient(client_wrapper=self._client_wrapper)
        return self._maintenance

    @property
    def fuel_and_energy(self):
        if self._fuel_and_energy is None:
            from .fuel_and_energy.client import FuelAndEnergyClient  # noqa: E402

            self._fuel_and_energy = FuelAndEnergyClient(client_wrapper=self._client_wrapper)
        return self._fuel_and_energy

    @property
    def driver_trailer_assignments(self):
        if self._driver_trailer_assignments is None:
            from .driver_trailer_assignments.client import DriverTrailerAssignmentsClient  # noqa: E402

            self._driver_trailer_assignments = DriverTrailerAssignmentsClient(client_wrapper=self._client_wrapper)
        return self._driver_trailer_assignments

    @property
    def driver_qr_codes(self):
        if self._driver_qr_codes is None:
            from .driver_qr_codes.client import DriverQrCodesClient  # noqa: E402

            self._driver_qr_codes = DriverQrCodesClient(client_wrapper=self._client_wrapper)
        return self._driver_qr_codes

    @property
    def carrier_proposed_assignments(self):
        if self._carrier_proposed_assignments is None:
            from .carrier_proposed_assignments.client import CarrierProposedAssignmentsClient  # noqa: E402

            self._carrier_proposed_assignments = CarrierProposedAssignmentsClient(client_wrapper=self._client_wrapper)
        return self._carrier_proposed_assignments

    @property
    def legacy_ap_is(self):
        if self._legacy_ap_is is None:
            from .legacy_ap_is.client import LegacyApIsClient  # noqa: E402

            self._legacy_ap_is = LegacyApIsClient(client_wrapper=self._client_wrapper)
        return self._legacy_ap_is

    @property
    def documents(self):
        if self._documents is None:
            from .documents.client import DocumentsClient  # noqa: E402

            self._documents = DocumentsClient(client_wrapper=self._client_wrapper)
        return self._documents

    @property
    def driver_vehicle_assignments(self):
        if self._driver_vehicle_assignments is None:
            from .driver_vehicle_assignments.client import DriverVehicleAssignmentsClient  # noqa: E402

            self._driver_vehicle_assignments = DriverVehicleAssignmentsClient(client_wrapper=self._client_wrapper)
        return self._driver_vehicle_assignments

    @property
    def drivers(self):
        if self._drivers is None:
            from .drivers.client import DriversClient  # noqa: E402

            self._drivers = DriversClient(client_wrapper=self._client_wrapper)
        return self._drivers

    @property
    def auth_token_for_driver(self):
        if self._auth_token_for_driver is None:
            from .auth_token_for_driver.client import AuthTokenForDriverClient  # noqa: E402

            self._auth_token_for_driver = AuthTokenForDriverClient(client_wrapper=self._client_wrapper)
        return self._auth_token_for_driver

    @property
    def tachograph_eu_only(self):
        if self._tachograph_eu_only is None:
            from .tachograph_eu_only.client import TachographEuOnlyClient  # noqa: E402

            self._tachograph_eu_only = TachographEuOnlyClient(client_wrapper=self._client_wrapper)
        return self._tachograph_eu_only

    @property
    def equipment(self):
        if self._equipment is None:
            from .equipment.client import EquipmentClient  # noqa: E402

            self._equipment = EquipmentClient(client_wrapper=self._client_wrapper)
        return self._equipment

    @property
    def hours_of_service(self):
        if self._hours_of_service is None:
            from .hours_of_service.client import HoursOfServiceClient  # noqa: E402

            self._hours_of_service = HoursOfServiceClient(client_wrapper=self._client_wrapper)
        return self._hours_of_service

    @property
    def ifta(self):
        if self._ifta is None:
            from .ifta.client import IftaClient  # noqa: E402

            self._ifta = IftaClient(client_wrapper=self._client_wrapper)
        return self._ifta

    @property
    def routes(self):
        if self._routes is None:
            from .routes.client import RoutesClient  # noqa: E402

            self._routes = RoutesClient(client_wrapper=self._client_wrapper)
        return self._routes

    @property
    def settings(self):
        if self._settings is None:
            from .settings.client import SettingsClient  # noqa: E402

            self._settings = SettingsClient(client_wrapper=self._client_wrapper)
        return self._settings

    @property
    def trailers(self):
        if self._trailers is None:
            from .trailers.client import TrailersClient  # noqa: E402

            self._trailers = TrailersClient(client_wrapper=self._client_wrapper)
        return self._trailers

    @property
    def vehicles(self):
        if self._vehicles is None:
            from .vehicles.client import VehiclesClient  # noqa: E402

            self._vehicles = VehiclesClient(client_wrapper=self._client_wrapper)
        return self._vehicles

    @property
    def vehicle_locations(self):
        if self._vehicle_locations is None:
            from .vehicle_locations.client import VehicleLocationsClient  # noqa: E402

            self._vehicle_locations = VehicleLocationsClient(client_wrapper=self._client_wrapper)
        return self._vehicle_locations

    @property
    def vehicle_stats(self):
        if self._vehicle_stats is None:
            from .vehicle_stats.client import VehicleStatsClient  # noqa: E402

            self._vehicle_stats = VehicleStatsClient(client_wrapper=self._client_wrapper)
        return self._vehicle_stats

    @property
    def forms(self):
        if self._forms is None:
            from .forms.client import FormsClient  # noqa: E402

            self._forms = FormsClient(client_wrapper=self._client_wrapper)
        return self._forms

    @property
    def gateways(self):
        if self._gateways is None:
            from .gateways.client import GatewaysClient  # noqa: E402

            self._gateways = GatewaysClient(client_wrapper=self._client_wrapper)
        return self._gateways

    @property
    def hubs(self):
        if self._hubs is None:
            from .hubs.client import HubsClient  # noqa: E402

            self._hubs = HubsClient(client_wrapper=self._client_wrapper)
        return self._hubs

    @property
    def plans(self):
        if self._plans is None:
            from .plans.client import PlansClient  # noqa: E402

            self._plans = PlansClient(client_wrapper=self._client_wrapper)
        return self._plans

    @property
    def idling(self):
        if self._idling is None:
            from .idling.client import IdlingClient  # noqa: E402

            self._idling = IdlingClient(client_wrapper=self._client_wrapper)
        return self._idling

    @property
    def industrial(self):
        if self._industrial is None:
            from .industrial.client import IndustrialClient  # noqa: E402

            self._industrial = IndustrialClient(client_wrapper=self._client_wrapper)
        return self._industrial

    @property
    def issues(self):
        if self._issues is None:
            from .issues.client import IssuesClient  # noqa: E402

            self._issues = IssuesClient(client_wrapper=self._client_wrapper)
        return self._issues

    @property
    def live_sharing_links(self):
        if self._live_sharing_links is None:
            from .live_sharing_links.client import LiveSharingLinksClient  # noqa: E402

            self._live_sharing_links = LiveSharingLinksClient(client_wrapper=self._client_wrapper)
        return self._live_sharing_links

    @property
    def work_orders(self):
        if self._work_orders is None:
            from .work_orders.client import WorkOrdersClient  # noqa: E402

            self._work_orders = WorkOrdersClient(client_wrapper=self._client_wrapper)
        return self._work_orders

    @property
    def organization_info(self):
        if self._organization_info is None:
            from .organization_info.client import OrganizationInfoClient  # noqa: E402

            self._organization_info = OrganizationInfoClient(client_wrapper=self._client_wrapper)
        return self._organization_info

    @property
    def preview_ap_is(self):
        if self._preview_ap_is is None:
            from .preview_ap_is.client import PreviewApIsClient  # noqa: E402

            self._preview_ap_is = PreviewApIsClient(client_wrapper=self._client_wrapper)
        return self._preview_ap_is

    @property
    def route_events(self):
        if self._route_events is None:
            from .route_events.client import RouteEventsClient  # noqa: E402

            self._route_events = RouteEventsClient(client_wrapper=self._client_wrapper)
        return self._route_events

    @property
    def safety(self):
        if self._safety is None:
            from .safety.client import SafetyClient  # noqa: E402

            self._safety = SafetyClient(client_wrapper=self._client_wrapper)
        return self._safety

    @property
    def speeding_intervals(self):
        if self._speeding_intervals is None:
            from .speeding_intervals.client import SpeedingIntervalsClient  # noqa: E402

            self._speeding_intervals = SpeedingIntervalsClient(client_wrapper=self._client_wrapper)
        return self._speeding_intervals

    @property
    def tags(self):
        if self._tags is None:
            from .tags.client import TagsClient  # noqa: E402

            self._tags = TagsClient(client_wrapper=self._client_wrapper)
        return self._tags

    @property
    def training_assignments(self):
        if self._training_assignments is None:
            from .training_assignments.client import TrainingAssignmentsClient  # noqa: E402

            self._training_assignments = TrainingAssignmentsClient(client_wrapper=self._client_wrapper)
        return self._training_assignments

    @property
    def training_courses(self):
        if self._training_courses is None:
            from .training_courses.client import TrainingCoursesClient  # noqa: E402

            self._training_courses = TrainingCoursesClient(client_wrapper=self._client_wrapper)
        return self._training_courses

    @property
    def trips(self):
        if self._trips is None:
            from .trips.client import TripsClient  # noqa: E402

            self._trips = TripsClient(client_wrapper=self._client_wrapper)
        return self._trips

    @property
    def users(self):
        if self._users is None:
            from .users.client import UsersClient  # noqa: E402

            self._users = UsersClient(client_wrapper=self._client_wrapper)
        return self._users

    @property
    def legacy(self):
        if self._legacy is None:
            from .legacy.client import LegacyClient  # noqa: E402

            self._legacy = LegacyClient(client_wrapper=self._client_wrapper)
        return self._legacy

    @property
    def messages(self):
        if self._messages is None:
            from .messages.client import MessagesClient  # noqa: E402

            self._messages = MessagesClient(client_wrapper=self._client_wrapper)
        return self._messages

    @property
    def trailer_assignments(self):
        if self._trailer_assignments is None:
            from .trailer_assignments.client import TrailerAssignmentsClient  # noqa: E402

            self._trailer_assignments = TrailerAssignmentsClient(client_wrapper=self._client_wrapper)
        return self._trailer_assignments

    @property
    def sensors(self):
        if self._sensors is None:
            from .sensors.client import SensorsClient  # noqa: E402

            self._sensors = SensorsClient(client_wrapper=self._client_wrapper)
        return self._sensors

    @property
    def webhooks(self):
        if self._webhooks is None:
            from .webhooks.client import WebhooksClient  # noqa: E402

            self._webhooks = WebhooksClient(client_wrapper=self._client_wrapper)
        return self._webhooks

    @property
    def fleet(self):
        if self._fleet is None:
            from .fleet.client import FleetClient  # noqa: E402

            self._fleet = FleetClient(client_wrapper=self._client_wrapper)
        return self._fleet


class AsyncSamsara:
    """
    Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.

    Parameters
    ----------
    base_url : typing.Optional[str]
        The base url to use for requests from the client.

    environment : SamsaraEnvironment
        The environment to use for requests from the client. from .environment import SamsaraEnvironment



        Defaults to SamsaraEnvironment.PRODUCTION_API



    token : typing.Optional[typing.Union[str, typing.Callable[[], str]]]
    headers : typing.Optional[typing.Dict[str, str]]
        Additional headers to send with every request.

    timeout : typing.Optional[float]
        The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.

    follow_redirects : typing.Optional[bool]
        Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.

    httpx_client : typing.Optional[httpx.AsyncClient]
        The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.

    Examples
    --------
    from samsara import AsyncSamsara

    client = AsyncSamsara(
        token="YOUR_TOKEN",
    )
    """

    def __init__(
        self,
        *,
        base_url: typing.Optional[str] = None,
        environment: SamsaraEnvironment = SamsaraEnvironment.PRODUCTION_API,
        token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = os.getenv("SAMSARA_API_KEY"),
        headers: typing.Optional[typing.Dict[str, str]] = None,
        timeout: typing.Optional[float] = None,
        follow_redirects: typing.Optional[bool] = True,
        httpx_client: typing.Optional[httpx.AsyncClient] = None,
    ):
        _defaulted_timeout = (
            timeout if timeout is not None else 60 if httpx_client is None else httpx_client.timeout.read
        )
        if token is None:
            raise ApiError(body="The client must be instantiated be either passing in token or setting SAMSARA_API_KEY")
        self._client_wrapper = AsyncClientWrapper(
            base_url=_get_base_url(base_url=base_url, environment=environment),
            token=token,
            headers=headers,
            httpx_client=httpx_client
            if httpx_client is not None
            else httpx.AsyncClient(timeout=_defaulted_timeout, follow_redirects=follow_redirects)
            if follow_redirects is not None
            else httpx.AsyncClient(timeout=_defaulted_timeout),
            timeout=_defaulted_timeout,
        )
        self._addresses: typing.Optional[AsyncAddressesClient] = None
        self._alerts: typing.Optional[AsyncAlertsClient] = None
        self._assets: typing.Optional[AsyncAssetsClient] = None
        self._beta_ap_is: typing.Optional[AsyncBetaApIsClient] = None
        self._location_and_speed: typing.Optional[AsyncLocationAndSpeedClient] = None
        self._attributes: typing.Optional[AsyncAttributesClient] = None
        self._media: typing.Optional[AsyncMediaClient] = None
        self._coaching: typing.Optional[AsyncCoachingClient] = None
        self._contacts: typing.Optional[AsyncContactsClient] = None
        self._maintenance: typing.Optional[AsyncMaintenanceClient] = None
        self._fuel_and_energy: typing.Optional[AsyncFuelAndEnergyClient] = None
        self._driver_trailer_assignments: typing.Optional[AsyncDriverTrailerAssignmentsClient] = None
        self._driver_qr_codes: typing.Optional[AsyncDriverQrCodesClient] = None
        self._carrier_proposed_assignments: typing.Optional[AsyncCarrierProposedAssignmentsClient] = None
        self._legacy_ap_is: typing.Optional[AsyncLegacyApIsClient] = None
        self._documents: typing.Optional[AsyncDocumentsClient] = None
        self._driver_vehicle_assignments: typing.Optional[AsyncDriverVehicleAssignmentsClient] = None
        self._drivers: typing.Optional[AsyncDriversClient] = None
        self._auth_token_for_driver: typing.Optional[AsyncAuthTokenForDriverClient] = None
        self._tachograph_eu_only: typing.Optional[AsyncTachographEuOnlyClient] = None
        self._equipment: typing.Optional[AsyncEquipmentClient] = None
        self._hours_of_service: typing.Optional[AsyncHoursOfServiceClient] = None
        self._ifta: typing.Optional[AsyncIftaClient] = None
        self._routes: typing.Optional[AsyncRoutesClient] = None
        self._settings: typing.Optional[AsyncSettingsClient] = None
        self._trailers: typing.Optional[AsyncTrailersClient] = None
        self._vehicles: typing.Optional[AsyncVehiclesClient] = None
        self._vehicle_locations: typing.Optional[AsyncVehicleLocationsClient] = None
        self._vehicle_stats: typing.Optional[AsyncVehicleStatsClient] = None
        self._forms: typing.Optional[AsyncFormsClient] = None
        self._gateways: typing.Optional[AsyncGatewaysClient] = None
        self._hubs: typing.Optional[AsyncHubsClient] = None
        self._plans: typing.Optional[AsyncPlansClient] = None
        self._idling: typing.Optional[AsyncIdlingClient] = None
        self._industrial: typing.Optional[AsyncIndustrialClient] = None
        self._issues: typing.Optional[AsyncIssuesClient] = None
        self._live_sharing_links: typing.Optional[AsyncLiveSharingLinksClient] = None
        self._work_orders: typing.Optional[AsyncWorkOrdersClient] = None
        self._organization_info: typing.Optional[AsyncOrganizationInfoClient] = None
        self._preview_ap_is: typing.Optional[AsyncPreviewApIsClient] = None
        self._route_events: typing.Optional[AsyncRouteEventsClient] = None
        self._safety: typing.Optional[AsyncSafetyClient] = None
        self._speeding_intervals: typing.Optional[AsyncSpeedingIntervalsClient] = None
        self._tags: typing.Optional[AsyncTagsClient] = None
        self._training_assignments: typing.Optional[AsyncTrainingAssignmentsClient] = None
        self._training_courses: typing.Optional[AsyncTrainingCoursesClient] = None
        self._trips: typing.Optional[AsyncTripsClient] = None
        self._users: typing.Optional[AsyncUsersClient] = None
        self._legacy: typing.Optional[AsyncLegacyClient] = None
        self._messages: typing.Optional[AsyncMessagesClient] = None
        self._trailer_assignments: typing.Optional[AsyncTrailerAssignmentsClient] = None
        self._sensors: typing.Optional[AsyncSensorsClient] = None
        self._webhooks: typing.Optional[AsyncWebhooksClient] = None
        self._fleet: typing.Optional[AsyncFleetClient] = None

    @property
    def addresses(self):
        if self._addresses is None:
            from .addresses.client import AsyncAddressesClient  # noqa: E402

            self._addresses = AsyncAddressesClient(client_wrapper=self._client_wrapper)
        return self._addresses

    @property
    def alerts(self):
        if self._alerts is None:
            from .alerts.client import AsyncAlertsClient  # noqa: E402

            self._alerts = AsyncAlertsClient(client_wrapper=self._client_wrapper)
        return self._alerts

    @property
    def assets(self):
        if self._assets is None:
            from .assets.client import AsyncAssetsClient  # noqa: E402

            self._assets = AsyncAssetsClient(client_wrapper=self._client_wrapper)
        return self._assets

    @property
    def beta_ap_is(self):
        if self._beta_ap_is is None:
            from .beta_ap_is.client import AsyncBetaApIsClient  # noqa: E402

            self._beta_ap_is = AsyncBetaApIsClient(client_wrapper=self._client_wrapper)
        return self._beta_ap_is

    @property
    def location_and_speed(self):
        if self._location_and_speed is None:
            from .location_and_speed.client import AsyncLocationAndSpeedClient  # noqa: E402

            self._location_and_speed = AsyncLocationAndSpeedClient(client_wrapper=self._client_wrapper)
        return self._location_and_speed

    @property
    def attributes(self):
        if self._attributes is None:
            from .attributes.client import AsyncAttributesClient  # noqa: E402

            self._attributes = AsyncAttributesClient(client_wrapper=self._client_wrapper)
        return self._attributes

    @property
    def media(self):
        if self._media is None:
            from .media.client import AsyncMediaClient  # noqa: E402

            self._media = AsyncMediaClient(client_wrapper=self._client_wrapper)
        return self._media

    @property
    def coaching(self):
        if self._coaching is None:
            from .coaching.client import AsyncCoachingClient  # noqa: E402

            self._coaching = AsyncCoachingClient(client_wrapper=self._client_wrapper)
        return self._coaching

    @property
    def contacts(self):
        if self._contacts is None:
            from .contacts.client import AsyncContactsClient  # noqa: E402

            self._contacts = AsyncContactsClient(client_wrapper=self._client_wrapper)
        return self._contacts

    @property
    def maintenance(self):
        if self._maintenance is None:
            from .maintenance.client import AsyncMaintenanceClient  # noqa: E402

            self._maintenance = AsyncMaintenanceClient(client_wrapper=self._client_wrapper)
        return self._maintenance

    @property
    def fuel_and_energy(self):
        if self._fuel_and_energy is None:
            from .fuel_and_energy.client import AsyncFuelAndEnergyClient  # noqa: E402

            self._fuel_and_energy = AsyncFuelAndEnergyClient(client_wrapper=self._client_wrapper)
        return self._fuel_and_energy

    @property
    def driver_trailer_assignments(self):
        if self._driver_trailer_assignments is None:
            from .driver_trailer_assignments.client import AsyncDriverTrailerAssignmentsClient  # noqa: E402

            self._driver_trailer_assignments = AsyncDriverTrailerAssignmentsClient(client_wrapper=self._client_wrapper)
        return self._driver_trailer_assignments

    @property
    def driver_qr_codes(self):
        if self._driver_qr_codes is None:
            from .driver_qr_codes.client import AsyncDriverQrCodesClient  # noqa: E402

            self._driver_qr_codes = AsyncDriverQrCodesClient(client_wrapper=self._client_wrapper)
        return self._driver_qr_codes

    @property
    def carrier_proposed_assignments(self):
        if self._carrier_proposed_assignments is None:
            from .carrier_proposed_assignments.client import AsyncCarrierProposedAssignmentsClient  # noqa: E402

            self._carrier_proposed_assignments = AsyncCarrierProposedAssignmentsClient(
                client_wrapper=self._client_wrapper
            )
        return self._carrier_proposed_assignments

    @property
    def legacy_ap_is(self):
        if self._legacy_ap_is is None:
            from .legacy_ap_is.client import AsyncLegacyApIsClient  # noqa: E402

            self._legacy_ap_is = AsyncLegacyApIsClient(client_wrapper=self._client_wrapper)
        return self._legacy_ap_is

    @property
    def documents(self):
        if self._documents is None:
            from .documents.client import AsyncDocumentsClient  # noqa: E402

            self._documents = AsyncDocumentsClient(client_wrapper=self._client_wrapper)
        return self._documents

    @property
    def driver_vehicle_assignments(self):
        if self._driver_vehicle_assignments is None:
            from .driver_vehicle_assignments.client import AsyncDriverVehicleAssignmentsClient  # noqa: E402

            self._driver_vehicle_assignments = AsyncDriverVehicleAssignmentsClient(client_wrapper=self._client_wrapper)
        return self._driver_vehicle_assignments

    @property
    def drivers(self):
        if self._drivers is None:
            from .drivers.client import AsyncDriversClient  # noqa: E402

            self._drivers = AsyncDriversClient(client_wrapper=self._client_wrapper)
        return self._drivers

    @property
    def auth_token_for_driver(self):
        if self._auth_token_for_driver is None:
            from .auth_token_for_driver.client import AsyncAuthTokenForDriverClient  # noqa: E402

            self._auth_token_for_driver = AsyncAuthTokenForDriverClient(client_wrapper=self._client_wrapper)
        return self._auth_token_for_driver

    @property
    def tachograph_eu_only(self):
        if self._tachograph_eu_only is None:
            from .tachograph_eu_only.client import AsyncTachographEuOnlyClient  # noqa: E402

            self._tachograph_eu_only = AsyncTachographEuOnlyClient(client_wrapper=self._client_wrapper)
        return self._tachograph_eu_only

    @property
    def equipment(self):
        if self._equipment is None:
            from .equipment.client import AsyncEquipmentClient  # noqa: E402

            self._equipment = AsyncEquipmentClient(client_wrapper=self._client_wrapper)
        return self._equipment

    @property
    def hours_of_service(self):
        if self._hours_of_service is None:
            from .hours_of_service.client import AsyncHoursOfServiceClient  # noqa: E402

            self._hours_of_service = AsyncHoursOfServiceClient(client_wrapper=self._client_wrapper)
        return self._hours_of_service

    @property
    def ifta(self):
        if self._ifta is None:
            from .ifta.client import AsyncIftaClient  # noqa: E402

            self._ifta = AsyncIftaClient(client_wrapper=self._client_wrapper)
        return self._ifta

    @property
    def routes(self):
        if self._routes is None:
            from .routes.client import AsyncRoutesClient  # noqa: E402

            self._routes = AsyncRoutesClient(client_wrapper=self._client_wrapper)
        return self._routes

    @property
    def settings(self):
        if self._settings is None:
            from .settings.client import AsyncSettingsClient  # noqa: E402

            self._settings = AsyncSettingsClient(client_wrapper=self._client_wrapper)
        return self._settings

    @property
    def trailers(self):
        if self._trailers is None:
            from .trailers.client import AsyncTrailersClient  # noqa: E402

            self._trailers = AsyncTrailersClient(client_wrapper=self._client_wrapper)
        return self._trailers

    @property
    def vehicles(self):
        if self._vehicles is None:
            from .vehicles.client import AsyncVehiclesClient  # noqa: E402

            self._vehicles = AsyncVehiclesClient(client_wrapper=self._client_wrapper)
        return self._vehicles

    @property
    def vehicle_locations(self):
        if self._vehicle_locations is None:
            from .vehicle_locations.client import AsyncVehicleLocationsClient  # noqa: E402

            self._vehicle_locations = AsyncVehicleLocationsClient(client_wrapper=self._client_wrapper)
        return self._vehicle_locations

    @property
    def vehicle_stats(self):
        if self._vehicle_stats is None:
            from .vehicle_stats.client import AsyncVehicleStatsClient  # noqa: E402

            self._vehicle_stats = AsyncVehicleStatsClient(client_wrapper=self._client_wrapper)
        return self._vehicle_stats

    @property
    def forms(self):
        if self._forms is None:
            from .forms.client import AsyncFormsClient  # noqa: E402

            self._forms = AsyncFormsClient(client_wrapper=self._client_wrapper)
        return self._forms

    @property
    def gateways(self):
        if self._gateways is None:
            from .gateways.client import AsyncGatewaysClient  # noqa: E402

            self._gateways = AsyncGatewaysClient(client_wrapper=self._client_wrapper)
        return self._gateways

    @property
    def hubs(self):
        if self._hubs is None:
            from .hubs.client import AsyncHubsClient  # noqa: E402

            self._hubs = AsyncHubsClient(client_wrapper=self._client_wrapper)
        return self._hubs

    @property
    def plans(self):
        if self._plans is None:
            from .plans.client import AsyncPlansClient  # noqa: E402

            self._plans = AsyncPlansClient(client_wrapper=self._client_wrapper)
        return self._plans

    @property
    def idling(self):
        if self._idling is None:
            from .idling.client import AsyncIdlingClient  # noqa: E402

            self._idling = AsyncIdlingClient(client_wrapper=self._client_wrapper)
        return self._idling

    @property
    def industrial(self):
        if self._industrial is None:
            from .industrial.client import AsyncIndustrialClient  # noqa: E402

            self._industrial = AsyncIndustrialClient(client_wrapper=self._client_wrapper)
        return self._industrial

    @property
    def issues(self):
        if self._issues is None:
            from .issues.client import AsyncIssuesClient  # noqa: E402

            self._issues = AsyncIssuesClient(client_wrapper=self._client_wrapper)
        return self._issues

    @property
    def live_sharing_links(self):
        if self._live_sharing_links is None:
            from .live_sharing_links.client import AsyncLiveSharingLinksClient  # noqa: E402

            self._live_sharing_links = AsyncLiveSharingLinksClient(client_wrapper=self._client_wrapper)
        return self._live_sharing_links

    @property
    def work_orders(self):
        if self._work_orders is None:
            from .work_orders.client import AsyncWorkOrdersClient  # noqa: E402

            self._work_orders = AsyncWorkOrdersClient(client_wrapper=self._client_wrapper)
        return self._work_orders

    @property
    def organization_info(self):
        if self._organization_info is None:
            from .organization_info.client import AsyncOrganizationInfoClient  # noqa: E402

            self._organization_info = AsyncOrganizationInfoClient(client_wrapper=self._client_wrapper)
        return self._organization_info

    @property
    def preview_ap_is(self):
        if self._preview_ap_is is None:
            from .preview_ap_is.client import AsyncPreviewApIsClient  # noqa: E402

            self._preview_ap_is = AsyncPreviewApIsClient(client_wrapper=self._client_wrapper)
        return self._preview_ap_is

    @property
    def route_events(self):
        if self._route_events is None:
            from .route_events.client import AsyncRouteEventsClient  # noqa: E402

            self._route_events = AsyncRouteEventsClient(client_wrapper=self._client_wrapper)
        return self._route_events

    @property
    def safety(self):
        if self._safety is None:
            from .safety.client import AsyncSafetyClient  # noqa: E402

            self._safety = AsyncSafetyClient(client_wrapper=self._client_wrapper)
        return self._safety

    @property
    def speeding_intervals(self):
        if self._speeding_intervals is None:
            from .speeding_intervals.client import AsyncSpeedingIntervalsClient  # noqa: E402

            self._speeding_intervals = AsyncSpeedingIntervalsClient(client_wrapper=self._client_wrapper)
        return self._speeding_intervals

    @property
    def tags(self):
        if self._tags is None:
            from .tags.client import AsyncTagsClient  # noqa: E402

            self._tags = AsyncTagsClient(client_wrapper=self._client_wrapper)
        return self._tags

    @property
    def training_assignments(self):
        if self._training_assignments is None:
            from .training_assignments.client import AsyncTrainingAssignmentsClient  # noqa: E402

            self._training_assignments = AsyncTrainingAssignmentsClient(client_wrapper=self._client_wrapper)
        return self._training_assignments

    @property
    def training_courses(self):
        if self._training_courses is None:
            from .training_courses.client import AsyncTrainingCoursesClient  # noqa: E402

            self._training_courses = AsyncTrainingCoursesClient(client_wrapper=self._client_wrapper)
        return self._training_courses

    @property
    def trips(self):
        if self._trips is None:
            from .trips.client import AsyncTripsClient  # noqa: E402

            self._trips = AsyncTripsClient(client_wrapper=self._client_wrapper)
        return self._trips

    @property
    def users(self):
        if self._users is None:
            from .users.client import AsyncUsersClient  # noqa: E402

            self._users = AsyncUsersClient(client_wrapper=self._client_wrapper)
        return self._users

    @property
    def legacy(self):
        if self._legacy is None:
            from .legacy.client import AsyncLegacyClient  # noqa: E402

            self._legacy = AsyncLegacyClient(client_wrapper=self._client_wrapper)
        return self._legacy

    @property
    def messages(self):
        if self._messages is None:
            from .messages.client import AsyncMessagesClient  # noqa: E402

            self._messages = AsyncMessagesClient(client_wrapper=self._client_wrapper)
        return self._messages

    @property
    def trailer_assignments(self):
        if self._trailer_assignments is None:
            from .trailer_assignments.client import AsyncTrailerAssignmentsClient  # noqa: E402

            self._trailer_assignments = AsyncTrailerAssignmentsClient(client_wrapper=self._client_wrapper)
        return self._trailer_assignments

    @property
    def sensors(self):
        if self._sensors is None:
            from .sensors.client import AsyncSensorsClient  # noqa: E402

            self._sensors = AsyncSensorsClient(client_wrapper=self._client_wrapper)
        return self._sensors

    @property
    def webhooks(self):
        if self._webhooks is None:
            from .webhooks.client import AsyncWebhooksClient  # noqa: E402

            self._webhooks = AsyncWebhooksClient(client_wrapper=self._client_wrapper)
        return self._webhooks

    @property
    def fleet(self):
        if self._fleet is None:
            from .fleet.client import AsyncFleetClient  # noqa: E402

            self._fleet = AsyncFleetClient(client_wrapper=self._client_wrapper)
        return self._fleet


def _get_base_url(*, base_url: typing.Optional[str] = None, environment: SamsaraEnvironment) -> str:
    if base_url is not None:
        return base_url
    elif environment is not None:
        return environment.value
    else:
        raise Exception("Please pass in either base_url or environment to construct the client")
