"""Sm API endpoints.

This file is automatically @generated from the Meraki API specification.
Do not edit this file manually.

"""

from __future__ import annotations

import urllib.parse
from typing import TYPE_CHECKING, Any, Literal

from meraki_client.schemas import (
    CheckinNetworkSmDevicesResponse,
    CreateNetworkSmTargetGroupResponse,
    CreateOrganizationSmAdminsRoleResponse,
    DictResponse,
    GetNetworkSmDeviceCellularUsageHistoryResponseItem,
    GetNetworkSmDeviceCertsResponseItem,
    GetNetworkSmDeviceConnectivityResponseItem,
    GetNetworkSmDeviceDesktopLogsResponseItem,
    GetNetworkSmDeviceDeviceCommandLogsResponseItem,
    GetNetworkSmDeviceDeviceProfilesResponseItem,
    GetNetworkSmDeviceNetworkAdaptersResponseItem,
    GetNetworkSmDevicePerformanceHistoryResponseItem,
    GetNetworkSmDeviceRestrictionsResponse,
    GetNetworkSmDeviceSecurityCentersResponseItem,
    GetNetworkSmDeviceSoftwaresResponseItem,
    GetNetworkSmDevicesResponseItem,
    GetNetworkSmDeviceWlanListsResponseItem,
    GetNetworkSmProfilesResponseItem,
    GetNetworkSmTargetGroupResponse,
    GetNetworkSmTargetGroupsResponseItem,
    GetNetworkSmTrustedAccessConfigsResponseItem,
    GetNetworkSmUserAccessDevicesResponseItem,
    GetNetworkSmUserDeviceProfilesResponseItem,
    GetNetworkSmUserSoftwaresResponseItem,
    GetNetworkSmUsersResponseItem,
    GetOrganizationSmAdminsRoleResponse,
    GetOrganizationSmAdminsRolesResponseItemsItem,
    GetOrganizationSmApnsCertResponse,
    GetOrganizationSmSentryPoliciesAssignmentsByNetworkResponseItem,
    GetOrganizationSmVppAccountResponse,
    GetOrganizationSmVppAccountsResponseItem,
    LockNetworkSmDevicesResponse,
    ModifyNetworkSmDevicesTagsResponse,
    MoveNetworkSmDevicesResponse,
    RebootNetworkSmDevicesResponse,
    ShutdownNetworkSmDevicesResponse,
    UnenrollNetworkSmDeviceResponse,
    UpdateNetworkSmDevicesFieldsDeviceFields,
    UpdateNetworkSmDevicesFieldsResponse,
    UpdateNetworkSmTargetGroupResponse,
    UpdateOrganizationSmAdminsRoleResponse,
    UpdateOrganizationSmSentryPoliciesAssignmentsItemsItem,
    UpdateOrganizationSmSentryPoliciesAssignmentsResponse,
    WipeNetworkSmDevicesResponse,
)
from meraki_client.types import (
    CreateOrganizationSmAdminsRoleScope,
    UpdateOrganizationSmAdminsRoleScope,
)

if TYPE_CHECKING:
    from meraki_client._session import PaginatedResponse, Session


class Sm:
    """Sm class."""

    def __init__(self, session: Session) -> None:
        self._session = session

    def create_network_sm_bypass_activation_lock_attempt(
        self, *, network_id: str, ids: list[str]
    ) -> DictResponse:
        """Bypass activation lock attempt.

        [API documentation: createNetworkSmBypassActivationLockAttempt](https://developer.cisco.com/meraki/api-v1/#!create-network-sm-bypass-activation-lock-attempt)

        Args:
            network_id: Network ID.
            ids: The ids of the devices to attempt activation lock bypass.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "status": "pending",
              "data": {}
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/bypassActivationLockAttempts"

        payload: dict[str, Any] = {}
        if ids is not None:
            payload["ids"] = ids

        return self._session.post(
            scope="sm",
            operation_id="createNetworkSmBypassActivationLockAttempt",
            path=path,
            json=payload,
            response_schema=DictResponse,
        )

    def get_network_sm_bypass_activation_lock_attempt(
        self, *, network_id: str, attempt_id: str
    ) -> DictResponse:
        """Bypass activation lock attempt status.

        [API documentation: getNetworkSmBypassActivationLockAttempt](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-bypass-activation-lock-attempt)

        Args:
            network_id: Network ID.
            attempt_id: Attempt ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "status": "complete",
              "data": {
                "38290139892": {
                  "success": true
                },
                "2090938209": {
                  "success": false,
                  "errors": [
                    "Activation lock bypass code not known for this device"
                  ]
                }
              }
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        attempt_id = urllib.parse.quote(str(attempt_id), safe="")
        path = f"/networks/{network_id}/sm/bypassActivationLockAttempts/{attempt_id}"

        return self._session.get(
            scope="sm",
            operation_id="getNetworkSmBypassActivationLockAttempt",
            path=path,
            response_schema=DictResponse,
        )

    def get_network_sm_devices(
        self,
        network_id: str,
        *,
        fields: list[str] | None = None,
        wifi_macs: list[str] | None = None,
        serials: list[str] | None = None,
        ids: list[str] | None = None,
        uuids: list[str] | None = None,
        system_types: list[str] | None = None,
        scope: list[str] | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetNetworkSmDevicesResponseItem]:
        """List the devices enrolled in an SM network with various specified fields and filters.

        [API documentation: getNetworkSmDevices](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-devices)

        Args:
            network_id: Network ID.
            fields: Additional fields that will be displayed for each device. The default fields
                are: id, name, tags, ssid, wifiMac, osName, systemModel, uuid, and
                serialNumber. The additional fields are: ip, systemType,
                availableDeviceCapacity, kioskAppName, biosVersion, lastConnected,
                missingAppsCount, userSuppliedAddress, location, lastUser, ownerEmail,
                ownerUsername, osBuild, publicIp, phoneNumber, diskInfoJson,
                deviceCapacity, isManaged, hadMdm, isSupervised, meid, imei, iccid,
                simCarrierNetwork, cellularDataUsed, isHotspotEnabled, createdAt,
                batteryEstCharge, quarantined, avName, avRunning, asName, fwName,
                isRooted, loginRequired, screenLockEnabled, screenLockDelay,
                autoLoginDisabled, autoTags, hasMdm, hasDesktopAgent,
                diskEncryptionEnabled, hardwareEncryptionCaps, passCodeLock,
                usesHardwareKeystore, androidSecurityPatchVersion, cellular, and url.
            wifi_macs: Filter devices by wifi mac(s).
            serials: Filter devices by serial(s).
            ids: Filter devices by id(s).
            uuids: Filter devices by uuid(s).
            system_types: Filter devices by system type(s).
            scope: Specify a scope (one of all, none, withAny, withAll, withoutAny, or withoutAll)
                and a set of tags.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "1284392014819",
                "name": "Miles's phone",
                "tags": [
                  "tag1",
                  "tag2"
                ],
                "ssid": "My SSID",
                "wifiMac": "00:11:22:33:44:55",
                "osName": "iOS 9.3.5",
                "systemModel": "iPhone",
                "uuid": "3d990628ede4c628d52",
                "serialNumber": "F5XKHEBX",
                "serial": "F5XKHEBX",
                "ip": "1.2.3.4",
                "notes": "Here's some info about my device"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/devices"

        params: dict[str, Any] = {}
        if fields is not None:
            params["fields[]"] = fields
        if wifi_macs is not None:
            params["wifiMacs[]"] = wifi_macs
        if serials is not None:
            params["serials[]"] = serials
        if ids is not None:
            params["ids[]"] = ids
        if uuids is not None:
            params["uuids[]"] = uuids
        if system_types is not None:
            params["systemTypes[]"] = system_types
        if scope is not None:
            params["scope[]"] = scope
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmDevices",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetNetworkSmDevicesResponseItem,
        )

    def checkin_network_sm_devices(
        self,
        network_id: str,
        *,
        wifi_macs: list[str] | None = None,
        ids: list[str] | None = None,
        serials: list[str] | None = None,
        scope: list[str] | None = None,
    ) -> CheckinNetworkSmDevicesResponse:
        """Force check-in a set of devices.

        [API documentation: checkinNetworkSmDevices](https://developer.cisco.com/meraki/api-v1/#!checkin-network-sm-devices)

        Args:
            network_id: Network ID.
            wifi_macs: The wifiMacs of the devices to be checked-in.
            ids: The ids of the devices to be checked-in.
            serials: The serials of the devices to be checked-in.
            scope: The scope (one of all, none, withAny, withAll, withoutAny, or withoutAll) and a
                set of tags of the devices to be checked-in.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "ids": [
                "1284392014819",
                "2983092129865"
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/devices/checkin"

        payload: dict[str, Any] = {}
        if wifi_macs is not None:
            payload["wifiMacs"] = wifi_macs
        if ids is not None:
            payload["ids"] = ids
        if serials is not None:
            payload["serials"] = serials
        if scope is not None:
            payload["scope"] = scope

        return self._session.post(
            scope="sm",
            operation_id="checkinNetworkSmDevices",
            path=path,
            json=payload,
            response_schema=CheckinNetworkSmDevicesResponse,
        )

    def update_network_sm_devices_fields(
        self,
        *,
        network_id: str,
        device_fields: UpdateNetworkSmDevicesFieldsDeviceFields,
        wifi_mac: str | None = None,
        id: str | None = None,
        serial: str | None = None,
    ) -> UpdateNetworkSmDevicesFieldsResponse:
        """Modify the fields of a device.

        [API documentation: updateNetworkSmDevicesFields](https://developer.cisco.com/meraki/api-v1/#!update-network-sm-devices-fields)

        Args:
            network_id: Network ID.
            wifi_mac: The wifiMac of the device to be modified.
            id: The id of the device to be modified.
            serial: The serial of the device to be modified.
            device_fields: The new fields of the device. Each field of this object is optional.

        Returns:
            Successful operation.

        Example API response:
            ```json
            [
              {
                "id": "1284392014819",
                "name": "Miles's phone",
                "wifiMac": "00:11:22:33:44:55",
                "serial": "F5XKHEBX",
                "notes": "Here's some info about my device"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/devices/fields"

        payload: dict[str, Any] = {}
        if wifi_mac is not None:
            payload["wifiMac"] = wifi_mac
        if id is not None:
            payload["id"] = id
        if serial is not None:
            payload["serial"] = serial
        if device_fields is not None:
            payload["deviceFields"] = device_fields.model_dump(by_alias=True, exclude_none=True)

        return self._session.put(
            scope="sm",
            operation_id="updateNetworkSmDevicesFields",
            path=path,
            json=payload,
            response_schema=UpdateNetworkSmDevicesFieldsResponse,
        )

    def lock_network_sm_devices(
        self,
        network_id: str,
        *,
        wifi_macs: list[str] | None = None,
        ids: list[str] | None = None,
        serials: list[str] | None = None,
        scope: list[str] | None = None,
        pin: int | None = None,
    ) -> LockNetworkSmDevicesResponse:
        """Lock a set of devices.

        [API documentation: lockNetworkSmDevices](https://developer.cisco.com/meraki/api-v1/#!lock-network-sm-devices)

        Args:
            network_id: Network ID.
            wifi_macs: The wifiMacs of the devices to be locked.
            ids: The ids of the devices to be locked.
            serials: The serials of the devices to be locked.
            scope: The scope (one of all, none, withAny, withAll, withoutAny, or withoutAll) and a
                set of tags of the devices to be locked.
            pin: The pin number for locking macOS devices (a six digit number). Required only for
                macOS devices.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "ids": [
                "1284392014819",
                "2983092129865"
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/devices/lock"

        payload: dict[str, Any] = {}
        if wifi_macs is not None:
            payload["wifiMacs"] = wifi_macs
        if ids is not None:
            payload["ids"] = ids
        if serials is not None:
            payload["serials"] = serials
        if scope is not None:
            payload["scope"] = scope
        if pin is not None:
            payload["pin"] = pin

        return self._session.post(
            scope="sm",
            operation_id="lockNetworkSmDevices",
            path=path,
            json=payload,
            response_schema=LockNetworkSmDevicesResponse,
        )

    def modify_network_sm_devices_tags(
        self,
        *,
        network_id: str,
        tags: list[str],
        update_action: str,
        wifi_macs: list[str] | None = None,
        ids: list[str] | None = None,
        serials: list[str] | None = None,
        scope: list[str] | None = None,
    ) -> ModifyNetworkSmDevicesTagsResponse:
        """Add, delete, or update the tags of a set of devices.

        [API documentation: modifyNetworkSmDevicesTags](https://developer.cisco.com/meraki/api-v1/#!modify-network-sm-devices-tags)

        Args:
            network_id: Network ID.
            wifi_macs: The wifiMacs of the devices to be modified.
            ids: The ids of the devices to be modified.
            serials: The serials of the devices to be modified.
            scope: The scope (one of all, none, withAny, withAll, withoutAny, or withoutAll) and a
                set of tags of the devices to be modified.
            tags: The tags to be added, deleted, or updated.
            update_action: One of add, delete, or update. Only devices that have been modified will
                be returned.

        Returns:
            Successful operation.

        Example API response:
            ```json
            [
              {
                "id": "1284392014819",
                "tags": [
                  "tag1",
                  "tag2"
                ],
                "wifiMac": "00:11:22:33:44:55",
                "serial": "F5XKHEBX"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/devices/modifyTags"

        payload: dict[str, Any] = {}
        if wifi_macs is not None:
            payload["wifiMacs"] = wifi_macs
        if ids is not None:
            payload["ids"] = ids
        if serials is not None:
            payload["serials"] = serials
        if scope is not None:
            payload["scope"] = scope
        if tags is not None:
            payload["tags"] = tags
        if update_action is not None:
            payload["updateAction"] = update_action

        return self._session.post(
            scope="sm",
            operation_id="modifyNetworkSmDevicesTags",
            path=path,
            json=payload,
            response_schema=ModifyNetworkSmDevicesTagsResponse,
        )

    def move_network_sm_devices(
        self,
        *,
        network_id: str,
        new_network: str,
        wifi_macs: list[str] | None = None,
        ids: list[str] | None = None,
        serials: list[str] | None = None,
        scope: list[str] | None = None,
    ) -> MoveNetworkSmDevicesResponse:
        """Move a set of devices to a new network.

        [API documentation: moveNetworkSmDevices](https://developer.cisco.com/meraki/api-v1/#!move-network-sm-devices)

        Args:
            network_id: Network ID.
            wifi_macs: The wifiMacs of the devices to be moved.
            ids: The ids of the devices to be moved.
            serials: The serials of the devices to be moved.
            scope: The scope (one of all, none, withAny, withAll, withoutAny, or withoutAll) and a
                set of tags of the devices to be moved.
            new_network: The new network to which the devices will be moved.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "ids": [
                "1284392014819",
                "2983092129865"
              ],
              "newNetwork": "1284392014819"
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/devices/move"

        payload: dict[str, Any] = {}
        if wifi_macs is not None:
            payload["wifiMacs"] = wifi_macs
        if ids is not None:
            payload["ids"] = ids
        if serials is not None:
            payload["serials"] = serials
        if scope is not None:
            payload["scope"] = scope
        if new_network is not None:
            payload["newNetwork"] = new_network

        return self._session.post(
            scope="sm",
            operation_id="moveNetworkSmDevices",
            path=path,
            json=payload,
            response_schema=MoveNetworkSmDevicesResponse,
        )

    def reboot_network_sm_devices(
        self,
        network_id: str,
        *,
        wifi_macs: list[str] | None = None,
        ids: list[str] | None = None,
        serials: list[str] | None = None,
        scope: list[str] | None = None,
        kext_paths: list[str] | None = None,
        notify_user: bool | None = None,
        rebuild_kernel_cache: bool | None = None,
        request_requires_network_tether: bool | None = None,
    ) -> RebootNetworkSmDevicesResponse:
        """Reboot a set of endpoints.

        [API documentation: rebootNetworkSmDevices](https://developer.cisco.com/meraki/api-v1/#!reboot-network-sm-devices)

        Args:
            network_id: Network ID.
            wifi_macs: The wifiMacs of the endpoints to be rebooted.
            ids: The ids of the endpoints to be rebooted.
            serials: The serials of the endpoints to be rebooted.
            scope: The scope (one of all, none, withAny, withAll, withoutAny, or withoutAll) and a
                set of tags of the endpoints to be rebooted.
            kext_paths: The KextPaths of the endpoints to be rebooted. Available for macOS 11+.
            notify_user: Whether or not to notify the user before rebooting the endpoint. Available
                for macOS 11.3+.
            rebuild_kernel_cache: Whether or not to rebuild the kernel cache when rebooting the
                endpoint. Available for macOS 11+.
            request_requires_network_tether: Whether or not the request requires network tethering.
                Available for macOS and supervised iOS or tvOS.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "ids": [
                "1284392014819",
                "2983092129865"
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/devices/reboot"

        payload: dict[str, Any] = {}
        if wifi_macs is not None:
            payload["wifiMacs"] = wifi_macs
        if ids is not None:
            payload["ids"] = ids
        if serials is not None:
            payload["serials"] = serials
        if scope is not None:
            payload["scope"] = scope
        if kext_paths is not None:
            payload["kextPaths"] = kext_paths
        if notify_user is not None:
            payload["notifyUser"] = notify_user
        if rebuild_kernel_cache is not None:
            payload["rebuildKernelCache"] = rebuild_kernel_cache
        if request_requires_network_tether is not None:
            payload["requestRequiresNetworkTether"] = request_requires_network_tether

        return self._session.post(
            scope="sm",
            operation_id="rebootNetworkSmDevices",
            path=path,
            json=payload,
            response_schema=RebootNetworkSmDevicesResponse,
        )

    def shutdown_network_sm_devices(
        self,
        network_id: str,
        *,
        wifi_macs: list[str] | None = None,
        ids: list[str] | None = None,
        serials: list[str] | None = None,
        scope: list[str] | None = None,
    ) -> ShutdownNetworkSmDevicesResponse:
        """Shutdown a set of endpoints.

        [API documentation: shutdownNetworkSmDevices](https://developer.cisco.com/meraki/api-v1/#!shutdown-network-sm-devices)

        Args:
            network_id: Network ID.
            wifi_macs: The wifiMacs of the endpoints to be shutdown.
            ids: The ids of the endpoints to be shutdown.
            serials: The serials of the endpoints to be shutdown.
            scope: The scope (one of all, none, withAny, withAll, withoutAny, or withoutAll) and a
                set of tags of the endpoints to be shutdown.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "ids": [
                "1284392014819",
                "2983092129865"
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/devices/shutdown"

        payload: dict[str, Any] = {}
        if wifi_macs is not None:
            payload["wifiMacs"] = wifi_macs
        if ids is not None:
            payload["ids"] = ids
        if serials is not None:
            payload["serials"] = serials
        if scope is not None:
            payload["scope"] = scope

        return self._session.post(
            scope="sm",
            operation_id="shutdownNetworkSmDevices",
            path=path,
            json=payload,
            response_schema=ShutdownNetworkSmDevicesResponse,
        )

    def wipe_network_sm_devices(
        self,
        network_id: str,
        *,
        wifi_mac: str | None = None,
        id: str | None = None,
        serial: str | None = None,
        pin: int | None = None,
    ) -> WipeNetworkSmDevicesResponse:
        """Wipe a device.

        [API documentation: wipeNetworkSmDevices](https://developer.cisco.com/meraki/api-v1/#!wipe-network-sm-devices)

        Args:
            network_id: Network ID.
            wifi_mac: The wifiMac of the device to be wiped.
            id: The id of the device to be wiped.
            serial: The serial of the device to be wiped.
            pin: The pin number (a six digit value) for wiping a macOS device. Required only for
                macOS devices.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1284392014819"
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/devices/wipe"

        payload: dict[str, Any] = {}
        if wifi_mac is not None:
            payload["wifiMac"] = wifi_mac
        if id is not None:
            payload["id"] = id
        if serial is not None:
            payload["serial"] = serial
        if pin is not None:
            payload["pin"] = pin

        return self._session.post(
            scope="sm",
            operation_id="wipeNetworkSmDevices",
            path=path,
            json=payload,
            response_schema=WipeNetworkSmDevicesResponse,
        )

    def get_network_sm_device_cellular_usage_history(
        self, *, network_id: str, device_id: str
    ) -> PaginatedResponse[GetNetworkSmDeviceCellularUsageHistoryResponseItem]:
        """Return the client's daily cellular data usage history.

        [API documentation: getNetworkSmDeviceCellularUsageHistory](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-device-cellular-usage-history)

        Args:
            network_id: Network ID.
            device_id: Device ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "received": 61.0,
                "sent": 138.0,
                "ts": "2018-05-12T00:00:00Z"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/cellularUsageHistory"

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmDeviceCellularUsageHistory",
            path=path,
            item_schema=GetNetworkSmDeviceCellularUsageHistoryResponseItem,
        )

    def get_network_sm_device_certs(
        self, *, network_id: str, device_id: str
    ) -> PaginatedResponse[GetNetworkSmDeviceCertsResponseItem]:
        r"""List the certs on a device.

        [API documentation: getNetworkSmDeviceCerts](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-device-certs)

        Args:
            network_id: Network ID.
            device_id: Device ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "name": "My Cert",
                "notValidAfter": "2018-05-12T00:00:00Z",
                "notValidBefore": "2018-02-11T00:00:00Z",
                "certPem": "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----\n",
                "deviceId": "1234",
                "issuer": "",
                "subject": "",
                "id": "15"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/certs"

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmDeviceCerts",
            path=path,
            item_schema=GetNetworkSmDeviceCertsResponseItem,
        )

    def get_network_sm_device_connectivity(
        self,
        *,
        network_id: str,
        device_id: str,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetNetworkSmDeviceConnectivityResponseItem]:
        """Returns historical connectivity data (whether a device is regularly checking in to Dashboard).

        [API documentation: getNetworkSmDeviceConnectivity](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-device-connectivity)

        Args:
            network_id: Network ID.
            device_id: Device ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "firstSeenAt": "2018-02-11T00:00:00Z",
                "lastSeenAt": "2018-05-12T00:00:00Z"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/connectivity"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmDeviceConnectivity",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetNetworkSmDeviceConnectivityResponseItem,
        )

    def get_network_sm_device_desktop_logs(
        self,
        *,
        network_id: str,
        device_id: str,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetNetworkSmDeviceDesktopLogsResponseItem]:
        """Return historical records of various Systems Manager network connection details for desktop devices.

        [API documentation: getNetworkSmDeviceDesktopLogs](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-device-desktop-logs)

        Args:
            network_id: Network ID.
            device_id: Device ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "measuredAt": "2018-05-12T00:00:00Z",
                "user": "milesmeraki",
                "networkDevice": "NIC",
                "networkDriver": "Driver",
                "wifiChannel": "11",
                "wifiAuth": "wpa-psk",
                "wifiBssid": "00:11:22:33:44:55",
                "wifiSsid": "ssid",
                "wifiRssi": "-11",
                "wifiNoise": "-99",
                "dhcpServer": "1.2.3.4",
                "ip": "1.2.3.4",
                "networkMTU": "1500",
                "subnet": "192.168.1.0/24",
                "gateway": "1.2.3.5",
                "publicIP": "123.123.123.1",
                "dnsServer": "8",
                "ts": "2018-05-12T00:00:00Z"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/desktopLogs"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmDeviceDesktopLogs",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetNetworkSmDeviceDesktopLogsResponseItem,
        )

    def get_network_sm_device_device_command_logs(
        self,
        *,
        network_id: str,
        device_id: str,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetNetworkSmDeviceDeviceCommandLogsResponseItem]:
        """Return historical records of commands sent to Systems Manager devices.

        [API documentation: getNetworkSmDeviceDeviceCommandLogs](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-device-device-command-logs)

        Args:
            network_id: Network ID.
            device_id: Device ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "action": "UpdateProfile",
                "name": "My profile",
                "details": "{}",
                "dashboardUser": "Miles Meraki",
                "ts": "2018-05-12T00:00:00Z"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/deviceCommandLogs"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmDeviceDeviceCommandLogs",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetNetworkSmDeviceDeviceCommandLogsResponseItem,
        )

    def get_network_sm_device_device_profiles(
        self, *, network_id: str, device_id: str
    ) -> PaginatedResponse[GetNetworkSmDeviceDeviceProfilesResponseItem]:
        """Get the installed profiles associated with a device.

        [API documentation: getNetworkSmDeviceDeviceProfiles](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-device-device-profiles)

        Args:
            network_id: Network ID.
            device_id: Device ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "deviceId": "1234",
                "id": "1284392014819",
                "isEncrypted": true,
                "isManaged": true,
                "profileData": "{}",
                "profileIdentifier": "com.test.app",
                "name": "My profile",
                "version": "0.0.1"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/deviceProfiles"

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmDeviceDeviceProfiles",
            path=path,
            item_schema=GetNetworkSmDeviceDeviceProfilesResponseItem,
        )

    def install_network_sm_device_apps(
        self, *, network_id: str, device_id: str, app_ids: list[str], force: bool | None = None
    ) -> DictResponse:
        """Install applications on a device.

        [API documentation: installNetworkSmDeviceApps](https://developer.cisco.com/meraki/api-v1/#!install-network-sm-device-apps)

        Args:
            network_id: Network ID.
            device_id: Device ID.
            app_ids: ids of applications to be installed.
            force: By default, installation of an app which is believed to already be present on the
                device will be skipped. If you'd like to force the installation of the
                app, set this parameter to true.

        Returns:
            Successful operation.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/installApps"

        payload: dict[str, Any] = {}
        if app_ids is not None:
            payload["appIds"] = app_ids
        if force is not None:
            payload["force"] = force

        return self._session.post(
            scope="sm",
            operation_id="installNetworkSmDeviceApps",
            path=path,
            json=payload,
            response_schema=DictResponse,
        )

    def get_network_sm_device_network_adapters(
        self, *, network_id: str, device_id: str
    ) -> PaginatedResponse[GetNetworkSmDeviceNetworkAdaptersResponseItem]:
        """List the network adapters of a device.

        [API documentation: getNetworkSmDeviceNetworkAdapters](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-device-network-adapters)

        Args:
            network_id: Network ID.
            device_id: Device ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "dhcpServer": "123.123.123.1",
                "dnsServer": "8.8.8.8, 8.8.4.4",
                "gateway": "1.2.3.5",
                "id": "1284392014819",
                "ip": "1.2.3.4",
                "mac": "00:11:22:33:44:55",
                "name": "en0",
                "subnet": "255.255.255.0"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/networkAdapters"

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmDeviceNetworkAdapters",
            path=path,
            item_schema=GetNetworkSmDeviceNetworkAdaptersResponseItem,
        )

    def get_network_sm_device_performance_history(
        self,
        *,
        network_id: str,
        device_id: str,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetNetworkSmDevicePerformanceHistoryResponseItem]:
        """Return historical records of various Systems Manager client metrics for desktop devices.

        [API documentation: getNetworkSmDevicePerformanceHistory](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-device-performance-history)

        Args:
            network_id: Network ID.
            device_id: Device ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "cpuPercentUsed": 0.95,
                "memFree": 1024,
                "memWired": 4096,
                "memActive": 1024,
                "memInactive": 2048,
                "networkSent": 512,
                "networkReceived": 512,
                "swapUsed": 768,
                "diskUsage": {
                  "c": {
                    "used": 2048,
                    "space": 9096
                  }
                },
                "ts": "2018-05-12T00:00:00Z"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/performanceHistory"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmDevicePerformanceHistory",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetNetworkSmDevicePerformanceHistoryResponseItem,
        )

    def refresh_network_sm_device_details(self, *, network_id: str, device_id: str) -> DictResponse:
        """Refresh the details of a device.

        [API documentation: refreshNetworkSmDeviceDetails](https://developer.cisco.com/meraki/api-v1/#!refresh-network-sm-device-details)

        Args:
            network_id: Network ID.
            device_id: Device ID.

        Returns:
            Successful operation.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/refreshDetails"

        return self._session.post(
            scope="sm",
            operation_id="refreshNetworkSmDeviceDetails",
            path=path,
            response_schema=DictResponse,
        )

    def get_network_sm_device_restrictions(
        self, *, network_id: str, device_id: str
    ) -> GetNetworkSmDeviceRestrictionsResponse:
        """List the restrictions on a device.

        [API documentation: getNetworkSmDeviceRestrictions](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-device-restrictions)

        Args:
            network_id: Network ID.
            device_id: Device ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "restrictions": [
                {
                  "profile": "com.test.app"
                }
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/restrictions"

        return self._session.get(
            scope="sm",
            operation_id="getNetworkSmDeviceRestrictions",
            path=path,
            response_schema=GetNetworkSmDeviceRestrictionsResponse,
        )

    def get_network_sm_device_security_centers(
        self, *, network_id: str, device_id: str
    ) -> PaginatedResponse[GetNetworkSmDeviceSecurityCentersResponseItem]:
        """List the security centers on a device.

        [API documentation: getNetworkSmDeviceSecurityCenters](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-device-security-centers)

        Args:
            network_id: Network ID.
            device_id: Device ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "isRooted": true,
                "hasAntiVirus": true,
                "antiVirusName": "meraki_av",
                "isFireWallEnabled": true,
                "hasFireWallInstalled": true,
                "fireWallName": "meraki_fw",
                "isDiskEncrypted": true,
                "isAutoLoginDisabled": true,
                "id": "1284392014819",
                "runningProcs": "/software,/software_2"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/securityCenters"

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmDeviceSecurityCenters",
            path=path,
            item_schema=GetNetworkSmDeviceSecurityCentersResponseItem,
        )

    def get_network_sm_device_softwares(
        self, *, network_id: str, device_id: str
    ) -> PaginatedResponse[GetNetworkSmDeviceSoftwaresResponseItem]:
        """Get a list of softwares associated with a device.

        [API documentation: getNetworkSmDeviceSoftwares](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-device-softwares)

        Args:
            network_id: Network ID.
            device_id: Device ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "appId": "1234",
                "bundleSize": 1024,
                "createdAt": "2018-02-11T00:00:00Z",
                "deviceId": "1234",
                "dynamicSize": 2048,
                "id": "1284392014819",
                "identifier": "com.test.app",
                "installedAt": "2018-05-12T00:00:00Z",
                "toInstall": true,
                "iosRedemptionCode": false,
                "isManaged": true,
                "itunesId": "1234",
                "licenseKey": "Z21234567890",
                "name": "My app",
                "path": "/Path/to/app.app",
                "redemptionCode": 1234,
                "shortVersion": "1.1",
                "status": "Managed",
                "toUninstall": false,
                "uninstalledAt": "2018-02-11T00:00:00Z",
                "updatedAt": "2018-05-12T00:00:00Z",
                "vendor": "Apple",
                "version": "0.1"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/softwares"

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmDeviceSoftwares",
            path=path,
            item_schema=GetNetworkSmDeviceSoftwaresResponseItem,
        )

    def unenroll_network_sm_device(
        self, *, network_id: str, device_id: str
    ) -> UnenrollNetworkSmDeviceResponse:
        """Unenroll a device.

        [API documentation: unenrollNetworkSmDevice](https://developer.cisco.com/meraki/api-v1/#!unenroll-network-sm-device)

        Args:
            network_id: Network ID.
            device_id: Device ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "success": true
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/unenroll"

        return self._session.post(
            scope="sm",
            operation_id="unenrollNetworkSmDevice",
            path=path,
            response_schema=UnenrollNetworkSmDeviceResponse,
        )

    def uninstall_network_sm_device_apps(
        self, *, network_id: str, device_id: str, app_ids: list[str]
    ) -> DictResponse:
        """Uninstall applications on a device.

        [API documentation: uninstallNetworkSmDeviceApps](https://developer.cisco.com/meraki/api-v1/#!uninstall-network-sm-device-apps)

        Args:
            network_id: Network ID.
            device_id: Device ID.
            app_ids: ids of applications to be uninstalled.

        Returns:
            Successful operation.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/uninstallApps"

        payload: dict[str, Any] = {}
        if app_ids is not None:
            payload["appIds"] = app_ids

        return self._session.post(
            scope="sm",
            operation_id="uninstallNetworkSmDeviceApps",
            path=path,
            json=payload,
            response_schema=DictResponse,
        )

    def get_network_sm_device_wlan_lists(
        self, *, network_id: str, device_id: str
    ) -> PaginatedResponse[GetNetworkSmDeviceWlanListsResponseItem]:
        """List the saved SSID names on a device.

        [API documentation: getNetworkSmDeviceWlanLists](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-device-wlan-lists)

        Args:
            network_id: Network ID.
            device_id: Device ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "createdAt": "2018-02-11T00:00:00Z",
                "id": "1284392014819",
                "xml": "Preferred networks on en0:"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        device_id = urllib.parse.quote(str(device_id), safe="")
        path = f"/networks/{network_id}/sm/devices/{device_id}/wlanLists"

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmDeviceWlanLists",
            path=path,
            item_schema=GetNetworkSmDeviceWlanListsResponseItem,
        )

    def get_network_sm_profiles(
        self, network_id: str, *, payload_types: list[str] | None = None
    ) -> PaginatedResponse[GetNetworkSmProfilesResponseItem]:
        """List all profiles in a network.

        [API documentation: getNetworkSmProfiles](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-profiles)

        Args:
            network_id: Network ID.
            payload_types: Filter by payload types.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "1284392014819",
                "name": "My profile",
                "description": "Some profile description",
                "scope": "withAny",
                "tags": [
                  "tag1",
                  "tag2"
                ],
                "payloadTypes": [
                  "Vpn",
                  "ManagedSettings"
                ]
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/profiles"

        params: dict[str, Any] = {}
        if payload_types is not None:
            params["payloadTypes[]"] = payload_types

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmProfiles",
            path=path,
            params=params,
            item_schema=GetNetworkSmProfilesResponseItem,
        )

    def get_network_sm_target_groups(
        self, network_id: str, *, with_details: bool | None = None
    ) -> PaginatedResponse[GetNetworkSmTargetGroupsResponseItem]:
        """List the target groups in this network.

        [API documentation: getNetworkSmTargetGroups](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-target-groups)

        Args:
            network_id: Network ID.
            with_details: Boolean indicating if the the ids of the devices or users scoped by the
                target group should be included in the response.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "1284392014819",
                "name": "Target group name",
                "scope": "withAny",
                "tags": [
                  "tag1",
                  "tag2"
                ]
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/targetGroups"

        params: dict[str, Any] = {}
        if with_details is not None:
            params["withDetails"] = with_details

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmTargetGroups",
            path=path,
            params=params,
            item_schema=GetNetworkSmTargetGroupsResponseItem,
        )

    def create_network_sm_target_group(
        self, network_id: str, *, name: str | None = None, scope: str | None = None
    ) -> CreateNetworkSmTargetGroupResponse:
        """Add a target group.

        [API documentation: createNetworkSmTargetGroup](https://developer.cisco.com/meraki/api-v1/#!create-network-sm-target-group)

        Args:
            network_id: Network ID.
            name: The name of this target group.
            scope: The scope and tag options of the target group. Comma separated values beginning
                with one of withAny, withAll, withoutAny, withoutAll, all, none,
                followed by tags. Default to none if empty.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1284392014819",
              "name": "Target group name",
              "scope": "withAny",
              "tags": [
                "tag1",
                "tag2"
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/targetGroups"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if scope is not None:
            payload["scope"] = scope

        return self._session.post(
            scope="sm",
            operation_id="createNetworkSmTargetGroup",
            path=path,
            json=payload,
            response_schema=CreateNetworkSmTargetGroupResponse,
        )

    def get_network_sm_target_group(
        self, *, network_id: str, target_group_id: str, with_details: bool | None = None
    ) -> GetNetworkSmTargetGroupResponse:
        """Return a target group.

        [API documentation: getNetworkSmTargetGroup](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-target-group)

        Args:
            network_id: Network ID.
            target_group_id: Target group ID.
            with_details: Boolean indicating if the the ids of the devices or users scoped by the
                target group should be included in the response.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1284392014819",
              "name": "Target group name",
              "scope": "withAny",
              "tags": [
                "tag1",
                "tag2"
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        target_group_id = urllib.parse.quote(str(target_group_id), safe="")
        path = f"/networks/{network_id}/sm/targetGroups/{target_group_id}"

        params: dict[str, Any] = {}
        if with_details is not None:
            params["withDetails"] = with_details

        return self._session.get(
            scope="sm",
            operation_id="getNetworkSmTargetGroup",
            path=path,
            params=params,
            response_schema=GetNetworkSmTargetGroupResponse,
        )

    def update_network_sm_target_group(
        self,
        *,
        network_id: str,
        target_group_id: str,
        name: str | None = None,
        scope: str | None = None,
    ) -> UpdateNetworkSmTargetGroupResponse:
        """Update a target group.

        [API documentation: updateNetworkSmTargetGroup](https://developer.cisco.com/meraki/api-v1/#!update-network-sm-target-group)

        Args:
            network_id: Network ID.
            target_group_id: Target group ID.
            name: The name of this target group.
            scope: The scope and tag options of the target group. Comma separated values beginning
                with one of withAny, withAll, withoutAny, withoutAll, all, none,
                followed by tags. Default to none if empty.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1284392014819",
              "name": "Target group name",
              "scope": "withAny",
              "tags": [
                "tag1",
                "tag2"
              ]
            }
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        target_group_id = urllib.parse.quote(str(target_group_id), safe="")
        path = f"/networks/{network_id}/sm/targetGroups/{target_group_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if scope is not None:
            payload["scope"] = scope

        return self._session.put(
            scope="sm",
            operation_id="updateNetworkSmTargetGroup",
            path=path,
            json=payload,
            response_schema=UpdateNetworkSmTargetGroupResponse,
        )

    def delete_network_sm_target_group(self, *, network_id: str, target_group_id: str) -> None:
        """Delete a target group from a network.

        [API documentation: deleteNetworkSmTargetGroup](https://developer.cisco.com/meraki/api-v1/#!delete-network-sm-target-group)

        Args:
            network_id: Network ID.
            target_group_id: Target group ID.

        Returns:
            Successful operation.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        target_group_id = urllib.parse.quote(str(target_group_id), safe="")
        path = f"/networks/{network_id}/sm/targetGroups/{target_group_id}"

        return self._session.delete(
            scope="sm", operation_id="deleteNetworkSmTargetGroup", path=path
        )

    def get_network_sm_trusted_access_configs(
        self,
        network_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetNetworkSmTrustedAccessConfigsResponseItem]:
        """List Trusted Access Configs.

        [API documentation: getNetworkSmTrustedAccessConfigs](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-trusted-access-configs)

        Args:
            network_id: Network ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 100.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "1284392014819",
                "ssidName": "My SSID",
                "name": "Cisco Meraki valued client",
                "scope": "withAny",
                "tags": [
                  "tag1",
                  "tag2"
                ],
                "timeboundType": "static",
                "sendExpirationEmails": true,
                "notifyTimeBeforeAccessEnds": 50000,
                "additionalEmailText": "test",
                "accessStartAt": "2018-02-11T00:00:00Z",
                "accessEndAt": "2018-05-12T00:00:00Z"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/trustedAccessConfigs"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmTrustedAccessConfigs",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetNetworkSmTrustedAccessConfigsResponseItem,
        )

    def get_network_sm_user_access_devices(
        self,
        network_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetNetworkSmUserAccessDevicesResponseItem]:
        """List User Access Devices and its Trusted Access Connections.

        [API documentation: getNetworkSmUserAccessDevices](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-user-access-devices)

        Args:
            network_id: Network ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 100.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "1284392014819",
                "name": "Cisco Meraki valued client",
                "systemType": "ios",
                "mac": "00:11:22:33:44:55",
                "username": "milesmeraki",
                "email": "miles@meraki.com",
                "tags": [
                  "tag1",
                  "tag2"
                ],
                "trustedAccessConnections": [
                  {
                    "trustedAccessConfigId": "1234",
                    "downloadedAt": "2018-02-11T00:00:00Z",
                    "scepCompletedAt": "2018-05-12T00:00:00Z",
                    "lastConnectedAt": "2018-05-12T00:00:00Z"
                  }
                ]
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/userAccessDevices"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmUserAccessDevices",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetNetworkSmUserAccessDevicesResponseItem,
        )

    def delete_network_sm_user_access_device(
        self, *, network_id: str, user_access_device_id: str
    ) -> None:
        """Delete a User Access Device.

        [API documentation: deleteNetworkSmUserAccessDevice](https://developer.cisco.com/meraki/api-v1/#!delete-network-sm-user-access-device)

        Args:
            network_id: Network ID.
            user_access_device_id: User access device ID.

        Returns:
            Successful operation.

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        user_access_device_id = urllib.parse.quote(str(user_access_device_id), safe="")
        path = f"/networks/{network_id}/sm/userAccessDevices/{user_access_device_id}"

        return self._session.delete(
            scope="sm", operation_id="deleteNetworkSmUserAccessDevice", path=path
        )

    def get_network_sm_users(
        self,
        network_id: str,
        *,
        ids: list[str] | None = None,
        usernames: list[str] | None = None,
        emails: list[str] | None = None,
        scope: list[str] | None = None,
    ) -> PaginatedResponse[GetNetworkSmUsersResponseItem]:
        """List the owners in an SM network with various specified fields and filters.

        [API documentation: getNetworkSmUsers](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-users)

        Args:
            network_id: Network ID.
            ids: Filter users by id(s).
            usernames: Filter users by username(s).
            emails: Filter users by email(s).
            scope: Specifiy a scope (one of all, none, withAny, withAll, withoutAny, withoutAll) and
                a set of tags.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "1234",
                "email": "miles@meraki.com",
                "fullName": "Miles Meraki",
                "username": "",
                "hasPassword": false,
                "tags": " tag1 tag2 ",
                "adGroups": [],
                "azureAdGroups": [],
                "samlGroups": [],
                "asmGroups": [],
                "isExternal": false,
                "displayName": "Miles Meraki <miles@meraki.com>",
                "hasIdentityCertificate": false,
                "userThumbnail": "https://s3.amazonaws.com/image.extension"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        path = f"/networks/{network_id}/sm/users"

        params: dict[str, Any] = {}
        if ids is not None:
            params["ids[]"] = ids
        if usernames is not None:
            params["usernames[]"] = usernames
        if emails is not None:
            params["emails[]"] = emails
        if scope is not None:
            params["scope[]"] = scope

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmUsers",
            path=path,
            params=params,
            item_schema=GetNetworkSmUsersResponseItem,
        )

    def get_network_sm_user_device_profiles(
        self, *, network_id: str, user_id: str
    ) -> PaginatedResponse[GetNetworkSmUserDeviceProfilesResponseItem]:
        """Get the profiles associated with a user.

        [API documentation: getNetworkSmUserDeviceProfiles](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-user-device-profiles)

        Args:
            network_id: Network ID.
            user_id: User ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "deviceId": "1234",
                "id": "1284392014819",
                "isEncrypted": true,
                "isManaged": true,
                "profileData": "{}",
                "profileIdentifier": "com.test.app",
                "name": "My profile",
                "version": "0.0.1"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        user_id = urllib.parse.quote(str(user_id), safe="")
        path = f"/networks/{network_id}/sm/users/{user_id}/deviceProfiles"

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmUserDeviceProfiles",
            path=path,
            item_schema=GetNetworkSmUserDeviceProfilesResponseItem,
        )

    def get_network_sm_user_softwares(
        self, *, network_id: str, user_id: str
    ) -> PaginatedResponse[GetNetworkSmUserSoftwaresResponseItem]:
        """Get a list of softwares associated with a user.

        [API documentation: getNetworkSmUserSoftwares](https://developer.cisco.com/meraki/api-v1/#!get-network-sm-user-softwares)

        Args:
            network_id: Network ID.
            user_id: User ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "appId": "1234",
                "bundleSize": 1024,
                "createdAt": "2018-02-11T00:00:00Z",
                "deviceId": "1234",
                "dynamicSize": 2048,
                "id": "1284392014819",
                "identifier": "com.test.app",
                "installedAt": "2018-05-12T00:00:00Z",
                "toInstall": true,
                "iosRedemptionCode": false,
                "isManaged": true,
                "itunesId": "1234",
                "licenseKey": "Z21234567890",
                "name": "My app",
                "path": "/Path/to/app.app",
                "redemptionCode": 1234,
                "shortVersion": "1.1",
                "status": "Managed",
                "toUninstall": false,
                "uninstalledAt": "2018-02-11T00:00:00Z",
                "updatedAt": "2018-05-12T00:00:00Z",
                "vendor": "Apple",
                "version": "0.1"
              }
            ]
            ```

        """
        network_id = urllib.parse.quote(str(network_id), safe="")
        user_id = urllib.parse.quote(str(user_id), safe="")
        path = f"/networks/{network_id}/sm/users/{user_id}/softwares"

        return self._session.get_pages(
            scope="sm",
            operation_id="getNetworkSmUserSoftwares",
            path=path,
            item_schema=GetNetworkSmUserSoftwaresResponseItem,
        )

    def get_organization_sm_admins_roles(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationSmAdminsRolesResponseItemsItem]:
        """List the Limited Access Roles for an organization.

        [API documentation: getOrganizationSmAdminsRoles](https://developer.cisco.com/meraki/api-v1/#!get-organization-sm-admins-roles)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 50.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "roleId": "1284392014819",
                  "name": "sample name",
                  "scope": "all_tags",
                  "tags": [
                    "tag"
                  ]
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 10,
                    "remaining": 0
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/sm/admins/roles"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="sm",
            operation_id="getOrganizationSmAdminsRoles",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationSmAdminsRolesResponseItemsItem,
        )

    def create_organization_sm_admins_role(
        self,
        *,
        organization_id: str,
        name: str,
        scope: CreateOrganizationSmAdminsRoleScope | None = None,
        tags: list[str] | None = None,
    ) -> CreateOrganizationSmAdminsRoleResponse:
        """Create a Limited Access Role.

        [API documentation: createOrganizationSmAdminsRole](https://developer.cisco.com/meraki/api-v1/#!create-organization-sm-admins-role)

        Args:
            organization_id: Organization ID.
            name: The name of the Limited Access Role.
            scope: The scope of the Limited Access Role.
            tags: The tags of the Limited Access Role.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "roleId": "1284392014819",
              "name": "sample name",
              "scope": "all_tags",
              "tags": [
                "tag"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/sm/admins/roles"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if scope is not None:
            payload["scope"] = scope
        if tags is not None:
            payload["tags"] = tags

        return self._session.post(
            scope="sm",
            operation_id="createOrganizationSmAdminsRole",
            path=path,
            json=payload,
            response_schema=CreateOrganizationSmAdminsRoleResponse,
        )

    def get_organization_sm_admins_role(
        self, *, organization_id: str, role_id: str
    ) -> GetOrganizationSmAdminsRoleResponse:
        """Return a Limited Access Role.

        [API documentation: getOrganizationSmAdminsRole](https://developer.cisco.com/meraki/api-v1/#!get-organization-sm-admins-role)

        Args:
            organization_id: Organization ID.
            role_id: Role ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "roleId": "1284392014819",
              "name": "sample name",
              "scope": "all_tags",
              "tags": [
                "tag"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        role_id = urllib.parse.quote(str(role_id), safe="")
        path = f"/organizations/{organization_id}/sm/admins/roles/{role_id}"

        return self._session.get(
            scope="sm",
            operation_id="getOrganizationSmAdminsRole",
            path=path,
            response_schema=GetOrganizationSmAdminsRoleResponse,
        )

    def update_organization_sm_admins_role(
        self,
        *,
        organization_id: str,
        role_id: str,
        name: str | None = None,
        scope: UpdateOrganizationSmAdminsRoleScope | None = None,
        tags: list[str] | None = None,
    ) -> UpdateOrganizationSmAdminsRoleResponse:
        """Update a Limited Access Role.

        [API documentation: updateOrganizationSmAdminsRole](https://developer.cisco.com/meraki/api-v1/#!update-organization-sm-admins-role)

        Args:
            organization_id: Organization ID.
            role_id: Role ID.
            name: The name of the Limited Access Role.
            scope: The scope of the Limited Access Role.
            tags: The tags of the Limited Access Role.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "roleId": "1284392014819",
              "name": "sample name",
              "scope": "all_tags",
              "tags": [
                "tag"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        role_id = urllib.parse.quote(str(role_id), safe="")
        path = f"/organizations/{organization_id}/sm/admins/roles/{role_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if scope is not None:
            payload["scope"] = scope
        if tags is not None:
            payload["tags"] = tags

        return self._session.put(
            scope="sm",
            operation_id="updateOrganizationSmAdminsRole",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationSmAdminsRoleResponse,
        )

    def delete_organization_sm_admins_role(self, *, organization_id: str, role_id: str) -> None:
        """Delete a Limited Access Role.

        [API documentation: deleteOrganizationSmAdminsRole](https://developer.cisco.com/meraki/api-v1/#!delete-organization-sm-admins-role)

        Args:
            organization_id: Organization ID.
            role_id: Role ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        role_id = urllib.parse.quote(str(role_id), safe="")
        path = f"/organizations/{organization_id}/sm/admins/roles/{role_id}"

        return self._session.delete(
            scope="sm", operation_id="deleteOrganizationSmAdminsRole", path=path
        )

    def get_organization_sm_apns_cert(
        self, organization_id: str
    ) -> GetOrganizationSmApnsCertResponse:
        r"""Get the organization's APNS certificate.

        [API documentation: getOrganizationSmApnsCert](https://developer.cisco.com/meraki/api-v1/#!get-organization-sm-apns-cert)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "certificate": "          -----BEGIN CERTIFICATE-----\n          MIIFdjCCBF6gAwIBAgIIM/hhf5ww8MwwDQYJKoZIhvcNAQELBQAwgYwxQDA+BgNV\n          BAMMN0FwcGxlIEFwcGxpY2F0aW9uIEludGVncmF0aW9uIDIgQ2VydGlmaWNhdGlv\n          biBBdXRob3JpdHkxJjAkBgNVBAsMHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9y\n          aXR5MRMwEQYDVQQKDApBcHBsZSBJbmMuMQswCQYDVQQGEwJVUzAeFw0yMDAyMjYx\n          ODIzNDJaFw0yMTAyMjUxODIzNDJaMIGPMUwwSgYKCZImiZPyLGQBAQw8Y29tLmFw\n          cGxlLm1nbXQuRXh0ZXJuYWwuOTA3NDJhYmYtZDhhZC00MTc2LTllZmQtMGNiMzg1\n          MTM1MGM0MTIwMAYDVQQDDClBUFNQOjkwNzQyYWJmLWQ4YWQtNDE3Ni05ZWZkLTBj\n          YjM4NTEzNTBjNDELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\n          ggEKAoIBAQDANdpo62hfxkP1IpMPXuO1+xKekUkY+iYae6cRaP886bodUaH1OwCj\n          Qd011u9Vng6m8I9rcLdIOS+IkFGKcTAHRYY3noqfEQUPyi5TN6yM1/mVYVoWZUnY\n          TrNWqDN/HfRagdYfZyQ7kAtOY2K8TF78HLLqQm7ez2+r4qibumoSli9+qCzKwDW/\n          hbx7JTeMlbYkhLTFgBkRxlp+usKymsLKm8D7kdbxtct4mx6p9z1FiNu4U1Hi/PgK\n          I/V3zHD4Ww7SzTICiLdCPeAmt042JvXAMQi0qhzrEdDiapmWwUC9xiiORN0BTIRA\n          T+DddTx8Xcly4wj9vQFdGUGLrJnzB3xZAgMBAAGjggHVMIIB0TAJBgNVHRMEAjAA\n          MB8GA1UdIwQYMBaAFPe+fCFgkds9G3vYOjKBad+ebH+bMIIBHAYDVR0gBIIBEzCC\n          AQ8wggELBgkqhkiG92NkBQEwgf0wgcMGCCsGAQUFBwICMIG2DIGzUmVsaWFuY2Ug\n          b24gdGhpcyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2NlcHRh\n          bmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNv\n          bmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kgYW5kIGNlcnRpZmlj\n          YXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wNQYIKwYBBQUHAgEWKWh0dHA6Ly93\n          d3cuYXBwbGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5MBMGA1UdJQQMMAoGCCsG\n          AQUFBwMCMDAGA1UdHwQpMCcwJaAjoCGGH2h0dHA6Ly9jcmwuYXBwbGUuY29tL2Fh\n          aTJjYS5jcmwwHQYDVR0OBBYEFDj4Jizt9bQX7dn3ypIanvaNIy8fMAsGA1UdDwQE\n          AwIHgDAQBgoqhkiG92NkBgMCBAIFADANBgkqhkiG9w0BAQsFAAOCAQEARmLmy4Mh\n          80hTBHMj2whrC2LR0dIe2ngAUwYGSocyPZOzlGZYntUvpsNGwflbWSPNxFpVF15z\n          exEcLPKM4f9KGdM27s/m/x1Es2us9Vve+wS+N0C84zMC++FJBIxj3yAINXqSpYJv\n          bA5wccHlzP9F9Ks7sVNQB8y0mibYahtxVV959gC4522t5SRaEEsd82oTCtXE2Ljg\n          fQ1IAmWi4MuMSPwp26oDSwun8Wxyx+sfi/it9YWxD36Ga9mrfIjK1WIHyhge0HHr\n          olnvMfxgwI9E5gGV/4bQzPlmsHdz+/pLupWMkALaAxI9D7ajUG7iyyjJBCOpsr1s\n          FjDvo6WUkaqMHA==\n          -----END CERTIFICATE-----\n"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/sm/apnsCert"

        return self._session.get(
            scope="sm",
            operation_id="getOrganizationSmApnsCert",
            path=path,
            response_schema=GetOrganizationSmApnsCertResponse,
        )

    def update_organization_sm_sentry_policies_assignments(
        self,
        *,
        organization_id: str,
        items: list[UpdateOrganizationSmSentryPoliciesAssignmentsItemsItem],
    ) -> UpdateOrganizationSmSentryPoliciesAssignmentsResponse:
        """Update an Organizations Sentry Policies using the provided list.

        [API documentation: updateOrganizationSmSentryPoliciesAssignments](https://developer.cisco.com/meraki/api-v1/#!update-organization-sm-sentry-policies-assignments)

        Args:
            organization_id: Organization ID.
            items: Sentry Group Policies for the Organization keyed by Network Id.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "items": [
                {
                  "networkId": "N_24329156",
                  "policies": [
                    {
                      "policyId": "1284392014819",
                      "networkId": "N_24329156",
                      "smNetworkId": "N_24329156",
                      "tags": [
                        "tag1",
                        "tag2"
                      ],
                      "scope": "withAny",
                      "groupNumber": "1234",
                      "groupPolicyId": "1284392014819",
                      "priority": "1",
                      "createdAt": "2018-05-12T00:00:00Z",
                      "lastUpdatedAt": "2018-05-12T00:00:00Z"
                    }
                  ]
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/sm/sentry/policies/assignments"

        payload: dict[str, Any] = {}
        if items is not None:
            payload["items"] = [item.model_dump(by_alias=True, exclude_none=True) for item in items]

        return self._session.put(
            scope="sm",
            operation_id="updateOrganizationSmSentryPoliciesAssignments",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationSmSentryPoliciesAssignmentsResponse,
        )

    def get_organization_sm_sentry_policies_assignments_by_network(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationSmSentryPoliciesAssignmentsByNetworkResponseItem]:
        """List the Sentry Policies for an organization ordered in ascending order of priority.

        [API documentation: getOrganizationSmSentryPoliciesAssignmentsByNetwork](https://developer.cisco.com/meraki/api-v1/#!get-organization-sm-sentry-policies-assignments-by-network)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 50.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter Sentry Policies by Network Id.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "items": [
                  {
                    "networkId": "N_24329156",
                    "policies": [
                      {
                        "policyId": "1284392014819",
                        "networkId": "N_24329156",
                        "smNetworkId": "N_24329156",
                        "tags": [
                          "tag1",
                          "tag2"
                        ],
                        "scope": "withAny",
                        "groupNumber": "1234",
                        "groupPolicyId": "1284392014819",
                        "priority": "1",
                        "createdAt": "2018-05-12T00:00:00Z",
                        "lastUpdatedAt": "2018-05-12T00:00:00Z"
                      }
                    ]
                  }
                ],
                "meta": {
                  "counts": {
                    "items": {
                      "total": 10,
                      "remaining": 0
                    }
                  }
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/sm/sentry/policies/assignments/byNetwork"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids

        return self._session.get_pages(
            scope="sm",
            operation_id="getOrganizationSmSentryPoliciesAssignmentsByNetwork",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationSmSentryPoliciesAssignmentsByNetworkResponseItem,
        )

    def get_organization_sm_vpp_accounts(
        self, organization_id: str
    ) -> PaginatedResponse[GetOrganizationSmVppAccountsResponseItem]:
        """List the VPP accounts in the organization.

        [API documentation: getOrganizationSmVppAccounts](https://developer.cisco.com/meraki/api-v1/#!get-organization-sm-vpp-accounts)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "vppAccountId": "1284392014819",
                "contentToken": "eyJleHBEYXRlIjoiMzAyMy0xMC0yMVQxMjowOTo0NSswMDAwIiwidG9rZW4iOiIvVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlQiLCJvcmdOYW1lIjoiTWVyYWtpICsgREVWRUxPUEVSIn0=",
                "email": "email@example.com",
                "name": "VPP Account name",
                "allowedAdmins": "Network",
                "networkIdAdmins": "N_24329156",
                "assignableNetworks": "Some",
                "assignableNetworkIds": [
                  "N_24329156"
                ],
                "vppLocationId": "22222222222",
                "vppLocationName": "LocationName",
                "lastSyncedAt": "2021-02-25T16:59:23Z",
                "lastForceSyncedAt": "2021-02-25T16:59:23Z",
                "parsedToken": {
                  "orgName": "My organization",
                  "hashedToken": "f572d396fae9206628714fb2ce00f72e94f2258f",
                  "expiresAt": "2023-10-21T12:09:45Z"
                },
                "id": "1284392014819",
                "vppServiceToken": "eyJleHBEYXRlIjoiMzAyMy0xMC0yMVQxMjowOTo0NSswMDAwIiwidG9rZW4iOiIvVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlQiLCJvcmdOYW1lIjoiTWVyYWtpICsgREVWRUxPUEVSIn0="
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/sm/vppAccounts"

        return self._session.get_pages(
            scope="sm",
            operation_id="getOrganizationSmVppAccounts",
            path=path,
            item_schema=GetOrganizationSmVppAccountsResponseItem,
        )

    def get_organization_sm_vpp_account(
        self, *, organization_id: str, vpp_account_id: str
    ) -> GetOrganizationSmVppAccountResponse:
        """Get a hash containing the unparsed token of the VPP account with the given ID.

        [API documentation: getOrganizationSmVppAccount](https://developer.cisco.com/meraki/api-v1/#!get-organization-sm-vpp-account)

        Args:
            organization_id: Organization ID.
            vpp_account_id: Vpp account ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "vppAccountId": "1284392014819",
              "contentToken": "eyJleHBEYXRlIjoiMzAyMy0xMC0yMVQxMjowOTo0NSswMDAwIiwidG9rZW4iOiIvVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlQiLCJvcmdOYW1lIjoiTWVyYWtpICsgREVWRUxPUEVSIn0=",
              "email": "email@example.com",
              "name": "VPP Account name",
              "allowedAdmins": "Network",
              "networkIdAdmins": "N_24329156",
              "assignableNetworks": "Some",
              "assignableNetworkIds": [
                "N_24329156"
              ],
              "vppLocationId": "22222222222",
              "vppLocationName": "LocationName",
              "lastSyncedAt": "2021-02-25T16:59:23Z",
              "lastForceSyncedAt": "2021-02-25T16:59:23Z",
              "parsedToken": {
                "orgName": "My organization",
                "hashedToken": "f572d396fae9206628714fb2ce00f72e94f2258f",
                "expiresAt": "2023-10-21T12:09:45Z"
              },
              "id": "1284392014819",
              "vppServiceToken": "eyJleHBEYXRlIjoiMzAyMy0xMC0yMVQxMjowOTo0NSswMDAwIiwidG9rZW4iOiIvVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlRPS0VOVE9LRU5UT0tFTlQiLCJvcmdOYW1lIjoiTWVyYWtpICsgREVWRUxPUEVSIn0="
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        vpp_account_id = urllib.parse.quote(str(vpp_account_id), safe="")
        path = f"/organizations/{organization_id}/sm/vppAccounts/{vpp_account_id}"

        return self._session.get(
            scope="sm",
            operation_id="getOrganizationSmVppAccount",
            path=path,
            response_schema=GetOrganizationSmVppAccountResponse,
        )
