From 4d5c844ab84908caba19660afbf4bf3b3ec5e72f Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 4 Jun 2026 07:28:26 +0000 Subject: [PATCH] Auto-generated library v3.2.0b0 for API v1.71.0-beta.0. --- docs/generation-report.md | 6 + meraki/__init__.py | 2 +- meraki/_version.py | 2 +- meraki/aio/api/assistant.py | 443 ++++++++++++++++++++++++++++++ meraki/aio/api/devices.py | 50 ++++ meraki/aio/api/organizations.py | 22 +- meraki/aio/api/wireless.py | 55 +++- meraki/api/assistant.py | 443 ++++++++++++++++++++++++++++++ meraki/api/batch/assistant.py | 3 + meraki/api/batch/devices.py | 25 ++ meraki/api/batch/organizations.py | 2 + meraki/api/batch/wireless.py | 2 +- meraki/api/devices.py | 50 ++++ meraki/api/organizations.py | 22 +- meraki/api/wireless.py | 55 +++- pyproject.toml | 2 +- uv.lock | 2 +- 17 files changed, 1167 insertions(+), 19 deletions(-) create mode 100644 meraki/aio/api/assistant.py create mode 100644 meraki/api/assistant.py create mode 100644 meraki/api/batch/assistant.py diff --git a/docs/generation-report.md b/docs/generation-report.md index d9a22bc..cafdeea 100644 --- a/docs/generation-report.md +++ b/docs/generation-report.md @@ -1,5 +1,11 @@ # Generation Report +## 2026-06-04 | Library v3.2.0b0 | API 1.71.0-beta.0 + + +No Python keyword parameter conflicts detected. + + ## 2026-05-27 | Library v3.1.0b3 | API 1.70.0-beta.3 diff --git a/meraki/__init__.py b/meraki/__init__.py index 77505a4..c7df28e 100644 --- a/meraki/__init__.py +++ b/meraki/__init__.py @@ -52,7 +52,7 @@ from meraki._version import __version__ # noqa: F401 from datetime import datetime -__api_version__ = "1.70.0-beta.3" +__api_version__ = "1.71.0-beta.0" __all__ = [ "APIError", diff --git a/meraki/_version.py b/meraki/_version.py index ae9bf83..464816a 100644 --- a/meraki/_version.py +++ b/meraki/_version.py @@ -1 +1 @@ -__version__ = "3.1.0b3" +__version__ = "3.2.0b0" diff --git a/meraki/aio/api/assistant.py b/meraki/aio/api/assistant.py new file mode 100644 index 0000000..a8fc082 --- /dev/null +++ b/meraki/aio/api/assistant.py @@ -0,0 +1,443 @@ +import urllib + + +class AsyncAssistant: + def __init__(self, session): + super().__init__() + self._session = session + + + def getOrganizationAssistantCapabilities(self, organizationId: str): + """ + **List the AI assistant's available capabilities and agents for this organization.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-capabilities + + - organizationId (string): Organization ID + """ + + metadata = { + "tags": ["assistant", "configure", "capabilities"], + "operation": "getOrganizationAssistantCapabilities", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assistant/capabilities" + + return self._session.get(metadata, resource) + + + def createOrganizationAssistantChatCompletion(self, organizationId: str, **kwargs): + """ + **Create a chat completion with the AI assistant** + https://developer.cisco.com/meraki/api-v1/#!create-organization-assistant-chat-completion + + - organizationId (string): Organization ID + - query (string): Simple text question or instruction to send to the AI assistant. Provide either 'query' for text-only requests or 'content' for multi-modal input. + - content (array): List of multi-modal content blocks. Use instead of 'query' to send text or images. Supports text and image types only; for audio and file support, use the messages endpoint. Maximum 8 parts. + - threadId (string): An existing thread ID to continue a conversation. If omitted, a new thread is created. + - networkId (string): Optional network ID to scope the query to a specific network. Defaults to the user's last visited network. + - platform (string): Platform identifier. Defaults to MERAKI when omitted. Case-insensitive. + - language (string): Optional language override. Defaults to the user's preferred language. + - country (string): Optional country override. Defaults to the user's country. + """ + + kwargs.update(locals()) + + if "platform" in kwargs: + options = ['DIGITAL_TWIN', 'DNAC', 'MERAKI', 'digital_twin', 'dnac', 'meraki'] + assert kwargs["platform"] in options, f'''"platform" cannot be "{kwargs['platform']}", & must be set to one of: {options}''' + + metadata = { + "tags": ["assistant", "configure", "chat", "completions"], + "operation": "createOrganizationAssistantChatCompletion", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/completions" + + body_params = ["query", "content", "threadId", "networkId", "platform", "language", "country", ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createOrganizationAssistantChatCompletion: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + + def getOrganizationAssistantChatThreads(self, organizationId: str, total_pages=1, direction='next', **kwargs): + """ + **List all active conversation threads for the authenticated user.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-chat-threads + + - organizationId (string): Organization ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): Number of entries per page. Defaults to 100. Maximum 1000. + - sort (string): Field to sort results by. Defaults to dateModified. + - sortOrder (string): Sort direction for results. Defaults to desc. + - from (string): Filter threads modified after this timestamp. + - to (string): Filter threads modified before this timestamp. + """ + + kwargs.update(locals()) + + if "sort" in kwargs: + options = ['dateModified', 'id', 'name'] + assert kwargs["sort"] in options, f'''"sort" cannot be "{kwargs['sort']}", & must be set to one of: {options}''' + if "sortOrder" in kwargs: + options = ['asc', 'desc'] + assert kwargs["sortOrder"] in options, f'''"sortOrder" cannot be "{kwargs['sortOrder']}", & must be set to one of: {options}''' + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "getOrganizationAssistantChatThreads", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads" + + query_params = ["perPage", "sort", "sortOrder", "from", "to", ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + if self._session._validate_kwargs: + all_params = query_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationAssistantChatThreads: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + + def createOrganizationAssistantChatThread(self, organizationId: str, **kwargs): + """ + **Create a new conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!create-organization-assistant-chat-thread + + - organizationId (string): Organization ID + - threadName (string): Display name for the new thread. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "createOrganizationAssistantChatThread", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads" + + body_params = ["threadName", ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createOrganizationAssistantChatThread: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + + def getOrganizationAssistantChatThread(self, organizationId: str, threadId: str): + """ + **Return a single conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-chat-thread + + - organizationId (string): Organization ID + - threadId (string): Thread ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "getOrganizationAssistantChatThread", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}" + + return self._session.get(metadata, resource) + + + def updateOrganizationAssistantChatThread(self, organizationId: str, threadId: str, threadName: str, **kwargs): + """ + **Update the name of a conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!update-organization-assistant-chat-thread + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - threadName (string): New display name for the thread. + """ + + kwargs = locals() + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "updateOrganizationAssistantChatThread", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}" + + body_params = ["threadName", ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"updateOrganizationAssistantChatThread: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.put(metadata, resource, payload) + + + def deleteOrganizationAssistantChatThread(self, organizationId: str, threadId: str): + """ + **Delete a conversation thread and all its messages.** + https://developer.cisco.com/meraki/api-v1/#!delete-organization-assistant-chat-thread + + - organizationId (string): Organization ID + - threadId (string): Thread ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "deleteOrganizationAssistantChatThread", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}" + + return self._session.delete(metadata, resource) + + + def getOrganizationAssistantChatThreadMessages(self, organizationId: str, threadId: str, total_pages=1, direction='next', **kwargs): + """ + **List messages in a conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-chat-thread-messages + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): Number of entries per page. Defaults to 100. Maximum 1000. + - sortOrder (string): Sort direction for results by timestamp. Defaults to asc. + """ + + kwargs.update(locals()) + + if "sortOrder" in kwargs: + options = ['asc', 'desc'] + assert kwargs["sortOrder"] in options, f'''"sortOrder" cannot be "{kwargs['sortOrder']}", & must be set to one of: {options}''' + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages"], + "operation": "getOrganizationAssistantChatThreadMessages", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}/messages" + + query_params = ["perPage", "sortOrder", ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + if self._session._validate_kwargs: + all_params = query_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationAssistantChatThreadMessages: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + + def createOrganizationAssistantChatThreadMessage(self, organizationId: str, threadId: str, content: list, **kwargs): + """ + **Create a new chat message in a thread.** + https://developer.cisco.com/meraki/api-v1/#!create-organization-assistant-chat-thread-message + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - content (array): List of message content parts. Supports text, image, audio, and file types. Maximum 8 parts. + - networkName (string): Name of the target network. + - networkId (string): Optional Meraki network ID for thread context. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages"], + "operation": "createOrganizationAssistantChatThreadMessage", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}/messages" + + body_params = ["content", "networkName", "networkId", ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createOrganizationAssistantChatThreadMessage: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + + def getOrganizationAssistantChatThreadMessage(self, organizationId: str, threadId: str, messageId: str): + """ + **Return a single message in a conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-chat-thread-message + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - messageId (string): Message ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages"], + "operation": "getOrganizationAssistantChatThreadMessage", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + messageId = urllib.parse.quote(str(messageId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}/messages/{messageId}" + + return self._session.get(metadata, resource) + + + def getOrganizationAssistantChatThreadMessageArtifacts(self, organizationId: str, threadId: str, messageId: str): + """ + **List artifacts attached to a specific message** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-chat-thread-message-artifacts + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - messageId (string): Message ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages", "artifacts"], + "operation": "getOrganizationAssistantChatThreadMessageArtifacts", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + messageId = urllib.parse.quote(str(messageId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}/messages/{messageId}/artifacts" + + return self._session.get(metadata, resource) + + + def getOrganizationAssistantChatThreadMessageArtifact(self, organizationId: str, threadId: str, messageId: str, artifactId: str): + """ + **Return a single artifact with its full content.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-chat-thread-message-artifact + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - messageId (string): Message ID + - artifactId (string): Artifact ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages", "artifacts"], + "operation": "getOrganizationAssistantChatThreadMessageArtifact", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + messageId = urllib.parse.quote(str(messageId), safe="") + artifactId = urllib.parse.quote(str(artifactId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}/messages/{messageId}/artifacts/{artifactId}" + + return self._session.get(metadata, resource) + + + def getOrganizationAssistantChatThreadMessageFeedback(self, organizationId: str, threadId: str, messageId: str): + """ + **Return all feedback entries previously submitted for a specific message in a thread.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-chat-thread-message-feedback + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - messageId (string): Message ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages", "feedback"], + "operation": "getOrganizationAssistantChatThreadMessageFeedback", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + messageId = urllib.parse.quote(str(messageId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}/messages/{messageId}/feedback" + + return self._session.get(metadata, resource) + + + def createOrganizationAssistantChatThreadMessageFeedback(self, organizationId: str, threadId: str, messageId: str, vote: bool, **kwargs): + """ + **Submit or replace feedback for a specific assistant message.** + https://developer.cisco.com/meraki/api-v1/#!create-organization-assistant-chat-thread-message-feedback + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - messageId (string): Message ID + - vote (boolean): True for positive, false for negative. + - reason (string): Optional free-text reason for the feedback (e.g., 'inaccurate', 'incomplete', 'helpful'). Not constrained to a fixed set of values. + - comment (string): Optional free-text comment providing additional detail. + - message (string): The assistant message text the feedback refers to. Captured for analytics; not required. + - prompt (string): The user prompt that produced the assistant message. Captured for analytics; not required. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages", "feedback"], + "operation": "createOrganizationAssistantChatThreadMessageFeedback", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + messageId = urllib.parse.quote(str(messageId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}/messages/{messageId}/feedback" + + body_params = ["vote", "reason", "comment", "message", "prompt", ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createOrganizationAssistantChatThreadMessageFeedback: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + + def getOrganizationAssistantQuery-limits(self, organizationId: str): + """ + **Get query limits for the AI assistant for this organization.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-query--limits + + - organizationId (string): Organization ID + """ + + metadata = { + "tags": ["assistant", "configure", "query-limits"], + "operation": "getOrganizationAssistantQuery-limits", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assistant/query-limits" + + return self._session.get(metadata, resource) diff --git a/meraki/aio/api/devices.py b/meraki/aio/api/devices.py index 1b77816..b149f8c 100644 --- a/meraki/aio/api/devices.py +++ b/meraki/aio/api/devices.py @@ -964,6 +964,56 @@ def getDeviceLiveToolsPortsStatus(self, serial: str, jobId: str): return self._session.get(metadata, resource) + def createDeviceLiveToolsPowerUsage(self, serial: str, **kwargs): + """ + **Enqueues a live tool job that retrieves details about a device's overall power usage** + https://developer.cisco.com/meraki/api-v1/#!create-device-live-tools-power-usage + + - serial (string): Serial + - callback (object): Details for the callback. Please include either an httpServerId OR url and sharedSecret + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["devices", "liveTools", "power", "usage"], + "operation": "createDeviceLiveToolsPowerUsage", + } + serial = urllib.parse.quote(str(serial), safe="") + resource = f"/devices/{serial}/liveTools/power/usage" + + body_params = [ + "callback", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning(f"createDeviceLiveToolsPowerUsage: ignoring unrecognized kwargs: {invalid}") + + return self._session.post(metadata, resource, payload) + + def getDeviceLiveToolsPowerUsage(self, serial: str, jobId: str): + """ + **Retrieve the status and results of a previously created live tool job fetching details about a device's overall power usage.** + https://developer.cisco.com/meraki/api-v1/#!get-device-live-tools-power-usage + + - serial (string): Serial + - jobId (string): Job ID + """ + + metadata = { + "tags": ["devices", "liveTools", "power", "usage"], + "operation": "getDeviceLiveToolsPowerUsage", + } + serial = urllib.parse.quote(str(serial), safe="") + jobId = urllib.parse.quote(str(jobId), safe="") + resource = f"/devices/{serial}/liveTools/power/usage/{jobId}" + + return self._session.get(metadata, resource) + def createDeviceLiveToolsReboot(self, serial: str, **kwargs): """ **Enqueue a job to reboot a device** diff --git a/meraki/aio/api/organizations.py b/meraki/aio/api/organizations.py index 9be8b7a..7591f10 100644 --- a/meraki/aio/api/organizations.py +++ b/meraki/aio/api/organizations.py @@ -98,6 +98,7 @@ def updateOrganization(self, organizationId: str, **kwargs): - name (string): The name of the organization - management (object): Information about the organization's management system - api (object): API-specific settings + - privacy (object): Privacy-related settings for the organization. """ kwargs.update(locals()) @@ -113,6 +114,7 @@ def updateOrganization(self, organizationId: str, **kwargs): "name", "management", "api", + "privacy", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} @@ -2369,6 +2371,9 @@ def getOrganizationAssuranceClientsConnectedCountHistory(self, organizationId: s - organizationId (string): Organization ID - networkId (string): Network ID to query. + - serials (array): A list of serials of AP devices + - bands (array): Filter results by band. Valid bands are: 2.4, 5, and 6. + - ssidNumbers (array): Filter results by SSID number - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 14 days from today. - t1 (string): The end of the timespan for the data. t1 can be a maximum of 7 days after t0. - timespan (number): The timespan for which the information will be fetched. If specifying timespan, do not specify parameters t0 and t1. The value must be in seconds and be less than or equal to 7 days. The default is 8 hours. If interval is provided, the timespan will be autocalculated. @@ -2386,6 +2391,9 @@ def getOrganizationAssuranceClientsConnectedCountHistory(self, organizationId: s query_params = [ "networkId", + "serials", + "bands", + "ssidNumbers", "t0", "t1", "timespan", @@ -2393,8 +2401,18 @@ def getOrganizationAssuranceClientsConnectedCountHistory(self, organizationId: s ] params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + array_params = [ + "serials", + "bands", + "ssidNumbers", + ] + for k, v in kwargs.items(): + if k.strip() in array_params: + params[f"{k.strip()}[]"] = kwargs[f"{k}"] + params.pop(k.strip()) + if self._session._validate_kwargs: - all_params = query_params + all_params = query_params + array_params invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] if invalid and self._session._logger: self._session._logger.warning( @@ -8752,6 +8770,7 @@ def updateOrganizationLoginSecurity(self, organizationId: str, **kwargs): - enforceTwoFactorAuth (boolean): Boolean indicating whether users in this organization will be required to use an extra verification code when logging in to Dashboard. This code will be sent to their mobile phone via SMS, or can be generated by the authenticator application. - enforceLoginIpRanges (boolean): Boolean indicating whether organization will restrict access to Dashboard (including the API) from certain IP addresses. - loginIpRanges (array): List of acceptable IP ranges. Entries can be single IP addresses, IP address ranges, and CIDR subnets. + - enforceLockedIpSessions (boolean): Boolean indicating whether Dashboard sessions are locked to the IP address from which they were established. Only applicable to organizations that support locked-IP sessions; otherwise the parameter is ignored. - apiAuthentication (object): Details for indicating whether organization will restrict access to API (but not Dashboard) to certain IP addresses. """ @@ -8778,6 +8797,7 @@ def updateOrganizationLoginSecurity(self, organizationId: str, **kwargs): "enforceTwoFactorAuth", "enforceLoginIpRanges", "loginIpRanges", + "enforceLockedIpSessions", "apiAuthentication", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} diff --git a/meraki/aio/api/wireless.py b/meraki/aio/api/wireless.py index d33b5d8..2f79637 100644 --- a/meraki/aio/api/wireless.py +++ b/meraki/aio/api/wireless.py @@ -2686,7 +2686,7 @@ def updateNetworkWirelessSsid(self, networkId: str, number: str, **kwargs): - radiusServerTimeout (integer): The amount of time for which a RADIUS client waits for a reply from the RADIUS server (must be between 1-10 seconds). - radiusServerAttemptsLimit (integer): The maximum number of transmit attempts after which a RADIUS server is failed over (must be between 1-5). - radiusFallbackEnabled (boolean): Whether or not higher priority RADIUS servers should be retried after 60 seconds. - - radiusRadsec (object): The current settings for RADIUS RADSec + - radiusRadsec (object): The current settings for RADIUS RadSec - radiusCoaEnabled (boolean): If true, Meraki devices will act as a RADIUS Dynamic Authorization Server and will respond to RADIUS Change-of-Authorization and Disconnect messages sent by the RADIUS server. - radiusFailoverPolicy (string): This policy determines how authentication requests should be handled in the event that all of the configured RADIUS servers are unreachable ('Deny access' or 'Allow access') - radiusLoadBalancingPolicy (string): This policy determines which RADIUS server will be contacted first in an authentication attempt and the ordering of any necessary retry attempts ('Strict priority order' or 'Round robin') @@ -5429,6 +5429,49 @@ def getOrganizationAssuranceWirelessExperienceMetricsOverviewHistoryByNetwork( return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationAssuranceWirelessExperienceMostImpactedNetworks(self, organizationId: str, **kwargs): + """ + **Returns the most impacted wireless experience networks and the top failure contributor for each network.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assurance-wireless-experience-most-impacted-networks + + - organizationId (string): Organization ID + - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 14 days from today. + - t1 (string): The end of the timespan for the data. t1 can be a maximum of 14 days after t0. + - timespan (number): The timespan for which the information will be fetched. If specifying timespan, do not specify parameters t0 and t1. The value must be in seconds and be greater than or equal to 15 minutes and be less than or equal to 14 days. The default is 2 hours. + - limit (integer): Number of most impacted networks to return. Default is 5. Maximum is 10. + """ + + kwargs.update(locals()) + + if "limit" in kwargs: + options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + assert kwargs["limit"] in options, f'''"limit" cannot be "{kwargs["limit"]}", & must be set to one of: {options}''' + + metadata = { + "tags": ["wireless", "configure", "experience", "mostImpactedNetworks"], + "operation": "getOrganizationAssuranceWirelessExperienceMostImpactedNetworks", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assurance/wireless/experience/mostImpactedNetworks" + + query_params = [ + "t0", + "t1", + "timespan", + "limit", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + if self._session._validate_kwargs: + all_params = query_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationAssuranceWirelessExperienceMostImpactedNetworks: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get(metadata, resource, params) + def getOrganizationAssuranceWirelessExperienceSuccessfulConnectsByNetwork( self, organizationId: str, total_pages=1, direction="next", **kwargs ): @@ -8759,7 +8802,7 @@ def getOrganizationWirelessDevicesProvisioningRecommendationsTags(self, organiza def getOrganizationWirelessDevicesRadsecCertificatesAuthorities(self, organizationId: str, **kwargs): """ - **Query for details on the organization's RADSEC device Certificate Authority certificates (CAs)** + **Query for details on the organization's RadSec device Certificate Authority certificates (CAs)** https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-radsec-certificates-authorities - organizationId (string): Organization ID @@ -8800,7 +8843,7 @@ def getOrganizationWirelessDevicesRadsecCertificatesAuthorities(self, organizati def updateOrganizationWirelessDevicesRadsecCertificatesAuthorities(self, organizationId: str, **kwargs): """ - **Update an organization's RADSEC device Certificate Authority (CA) state** + **Update an organization's RadSec device Certificate Authority (CA) state** https://developer.cisco.com/meraki/api-v1/#!update-organization-wireless-devices-radsec-certificates-authorities - organizationId (string): Organization ID @@ -8835,7 +8878,7 @@ def updateOrganizationWirelessDevicesRadsecCertificatesAuthorities(self, organiz def createOrganizationWirelessDevicesRadsecCertificatesAuthority(self, organizationId: str): """ - **Create an organization's RADSEC device Certificate Authority (CA)** + **Create an organization's RadSec device Certificate Authority (CA)** https://developer.cisco.com/meraki/api-v1/#!create-organization-wireless-devices-radsec-certificates-authority - organizationId (string): Organization ID @@ -8852,7 +8895,7 @@ def createOrganizationWirelessDevicesRadsecCertificatesAuthority(self, organizat def getOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrls(self, organizationId: str, **kwargs): """ - **Query for certificate revocation list (CRL) for the organization's RADSEC device Certificate Authorities (CAs).** + **Query for certificate revocation list (CRL) for the organization's RadSec device Certificate Authorities (CAs).** https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-radsec-certificates-authorities-crls - organizationId (string): Organization ID @@ -8893,7 +8936,7 @@ def getOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrls(self, organi def getOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrlsDeltas(self, organizationId: str, **kwargs): """ - **Query for all delta certificate revocation list (CRL) for the organization's RADSEC device Certificate Authority (CA) with the given id.** + **Query for all delta certificate revocation list (CRL) for the organization's RadSec device Certificate Authority (CA) with the given id.** https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-radsec-certificates-authorities-crls-deltas - organizationId (string): Organization ID diff --git a/meraki/api/assistant.py b/meraki/api/assistant.py new file mode 100644 index 0000000..37e3df2 --- /dev/null +++ b/meraki/api/assistant.py @@ -0,0 +1,443 @@ +import urllib + + +class Assistant(object): + def __init__(self, session): + super(Assistant, self).__init__() + self._session = session + + + def getOrganizationAssistantCapabilities(self, organizationId: str): + """ + **List the AI assistant's available capabilities and agents for this organization.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-capabilities + + - organizationId (string): Organization ID + """ + + metadata = { + "tags": ["assistant", "configure", "capabilities"], + "operation": "getOrganizationAssistantCapabilities", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assistant/capabilities" + + return self._session.get(metadata, resource) + + + def createOrganizationAssistantChatCompletion(self, organizationId: str, **kwargs): + """ + **Create a chat completion with the AI assistant** + https://developer.cisco.com/meraki/api-v1/#!create-organization-assistant-chat-completion + + - organizationId (string): Organization ID + - query (string): Simple text question or instruction to send to the AI assistant. Provide either 'query' for text-only requests or 'content' for multi-modal input. + - content (array): List of multi-modal content blocks. Use instead of 'query' to send text or images. Supports text and image types only; for audio and file support, use the messages endpoint. Maximum 8 parts. + - threadId (string): An existing thread ID to continue a conversation. If omitted, a new thread is created. + - networkId (string): Optional network ID to scope the query to a specific network. Defaults to the user's last visited network. + - platform (string): Platform identifier. Defaults to MERAKI when omitted. Case-insensitive. + - language (string): Optional language override. Defaults to the user's preferred language. + - country (string): Optional country override. Defaults to the user's country. + """ + + kwargs.update(locals()) + + if "platform" in kwargs: + options = ['DIGITAL_TWIN', 'DNAC', 'MERAKI', 'digital_twin', 'dnac', 'meraki'] + assert kwargs["platform"] in options, f'''"platform" cannot be "{kwargs['platform']}", & must be set to one of: {options}''' + + metadata = { + "tags": ["assistant", "configure", "chat", "completions"], + "operation": "createOrganizationAssistantChatCompletion", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/completions" + + body_params = ["query", "content", "threadId", "networkId", "platform", "language", "country", ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createOrganizationAssistantChatCompletion: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + + def getOrganizationAssistantChatThreads(self, organizationId: str, total_pages=1, direction='next', **kwargs): + """ + **List all active conversation threads for the authenticated user.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-chat-threads + + - organizationId (string): Organization ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): Number of entries per page. Defaults to 100. Maximum 1000. + - sort (string): Field to sort results by. Defaults to dateModified. + - sortOrder (string): Sort direction for results. Defaults to desc. + - from (string): Filter threads modified after this timestamp. + - to (string): Filter threads modified before this timestamp. + """ + + kwargs.update(locals()) + + if "sort" in kwargs: + options = ['dateModified', 'id', 'name'] + assert kwargs["sort"] in options, f'''"sort" cannot be "{kwargs['sort']}", & must be set to one of: {options}''' + if "sortOrder" in kwargs: + options = ['asc', 'desc'] + assert kwargs["sortOrder"] in options, f'''"sortOrder" cannot be "{kwargs['sortOrder']}", & must be set to one of: {options}''' + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "getOrganizationAssistantChatThreads", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads" + + query_params = ["perPage", "sort", "sortOrder", "from", "to", ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + if self._session._validate_kwargs: + all_params = query_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationAssistantChatThreads: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + + def createOrganizationAssistantChatThread(self, organizationId: str, **kwargs): + """ + **Create a new conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!create-organization-assistant-chat-thread + + - organizationId (string): Organization ID + - threadName (string): Display name for the new thread. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "createOrganizationAssistantChatThread", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads" + + body_params = ["threadName", ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createOrganizationAssistantChatThread: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + + def getOrganizationAssistantChatThread(self, organizationId: str, threadId: str): + """ + **Return a single conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-chat-thread + + - organizationId (string): Organization ID + - threadId (string): Thread ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "getOrganizationAssistantChatThread", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}" + + return self._session.get(metadata, resource) + + + def updateOrganizationAssistantChatThread(self, organizationId: str, threadId: str, threadName: str, **kwargs): + """ + **Update the name of a conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!update-organization-assistant-chat-thread + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - threadName (string): New display name for the thread. + """ + + kwargs = locals() + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "updateOrganizationAssistantChatThread", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}" + + body_params = ["threadName", ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"updateOrganizationAssistantChatThread: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.put(metadata, resource, payload) + + + def deleteOrganizationAssistantChatThread(self, organizationId: str, threadId: str): + """ + **Delete a conversation thread and all its messages.** + https://developer.cisco.com/meraki/api-v1/#!delete-organization-assistant-chat-thread + + - organizationId (string): Organization ID + - threadId (string): Thread ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads"], + "operation": "deleteOrganizationAssistantChatThread", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}" + + return self._session.delete(metadata, resource) + + + def getOrganizationAssistantChatThreadMessages(self, organizationId: str, threadId: str, total_pages=1, direction='next', **kwargs): + """ + **List messages in a conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-chat-thread-messages + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - total_pages (integer or string): use with perPage to get total results up to total_pages*perPage; -1 or "all" for all pages + - direction (string): direction to paginate, either "next" (default) or "prev" page + - perPage (integer): Number of entries per page. Defaults to 100. Maximum 1000. + - sortOrder (string): Sort direction for results by timestamp. Defaults to asc. + """ + + kwargs.update(locals()) + + if "sortOrder" in kwargs: + options = ['asc', 'desc'] + assert kwargs["sortOrder"] in options, f'''"sortOrder" cannot be "{kwargs['sortOrder']}", & must be set to one of: {options}''' + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages"], + "operation": "getOrganizationAssistantChatThreadMessages", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}/messages" + + query_params = ["perPage", "sortOrder", ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + if self._session._validate_kwargs: + all_params = query_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationAssistantChatThreadMessages: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get_pages(metadata, resource, params, total_pages, direction) + + + def createOrganizationAssistantChatThreadMessage(self, organizationId: str, threadId: str, content: list, **kwargs): + """ + **Create a new chat message in a thread.** + https://developer.cisco.com/meraki/api-v1/#!create-organization-assistant-chat-thread-message + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - content (array): List of message content parts. Supports text, image, audio, and file types. Maximum 8 parts. + - networkName (string): Name of the target network. + - networkId (string): Optional Meraki network ID for thread context. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages"], + "operation": "createOrganizationAssistantChatThreadMessage", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}/messages" + + body_params = ["content", "networkName", "networkId", ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createOrganizationAssistantChatThreadMessage: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + + def getOrganizationAssistantChatThreadMessage(self, organizationId: str, threadId: str, messageId: str): + """ + **Return a single message in a conversation thread.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-chat-thread-message + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - messageId (string): Message ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages"], + "operation": "getOrganizationAssistantChatThreadMessage", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + messageId = urllib.parse.quote(str(messageId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}/messages/{messageId}" + + return self._session.get(metadata, resource) + + + def getOrganizationAssistantChatThreadMessageArtifacts(self, organizationId: str, threadId: str, messageId: str): + """ + **List artifacts attached to a specific message** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-chat-thread-message-artifacts + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - messageId (string): Message ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages", "artifacts"], + "operation": "getOrganizationAssistantChatThreadMessageArtifacts", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + messageId = urllib.parse.quote(str(messageId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}/messages/{messageId}/artifacts" + + return self._session.get(metadata, resource) + + + def getOrganizationAssistantChatThreadMessageArtifact(self, organizationId: str, threadId: str, messageId: str, artifactId: str): + """ + **Return a single artifact with its full content.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-chat-thread-message-artifact + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - messageId (string): Message ID + - artifactId (string): Artifact ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages", "artifacts"], + "operation": "getOrganizationAssistantChatThreadMessageArtifact", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + messageId = urllib.parse.quote(str(messageId), safe="") + artifactId = urllib.parse.quote(str(artifactId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}/messages/{messageId}/artifacts/{artifactId}" + + return self._session.get(metadata, resource) + + + def getOrganizationAssistantChatThreadMessageFeedback(self, organizationId: str, threadId: str, messageId: str): + """ + **Return all feedback entries previously submitted for a specific message in a thread.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-chat-thread-message-feedback + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - messageId (string): Message ID + """ + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages", "feedback"], + "operation": "getOrganizationAssistantChatThreadMessageFeedback", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + messageId = urllib.parse.quote(str(messageId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}/messages/{messageId}/feedback" + + return self._session.get(metadata, resource) + + + def createOrganizationAssistantChatThreadMessageFeedback(self, organizationId: str, threadId: str, messageId: str, vote: bool, **kwargs): + """ + **Submit or replace feedback for a specific assistant message.** + https://developer.cisco.com/meraki/api-v1/#!create-organization-assistant-chat-thread-message-feedback + + - organizationId (string): Organization ID + - threadId (string): Thread ID + - messageId (string): Message ID + - vote (boolean): True for positive, false for negative. + - reason (string): Optional free-text reason for the feedback (e.g., 'inaccurate', 'incomplete', 'helpful'). Not constrained to a fixed set of values. + - comment (string): Optional free-text comment providing additional detail. + - message (string): The assistant message text the feedback refers to. Captured for analytics; not required. + - prompt (string): The user prompt that produced the assistant message. Captured for analytics; not required. + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["assistant", "configure", "chat", "threads", "messages", "feedback"], + "operation": "createOrganizationAssistantChatThreadMessageFeedback", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + threadId = urllib.parse.quote(str(threadId), safe="") + messageId = urllib.parse.quote(str(messageId), safe="") + resource = f"/organizations/{organizationId}/assistant/chat/threads/{threadId}/messages/{messageId}/feedback" + + body_params = ["vote", "reason", "comment", "message", "prompt", ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"createOrganizationAssistantChatThreadMessageFeedback: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.post(metadata, resource, payload) + + + def getOrganizationAssistantQuery-limits(self, organizationId: str): + """ + **Get query limits for the AI assistant for this organization.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assistant-query--limits + + - organizationId (string): Organization ID + """ + + metadata = { + "tags": ["assistant", "configure", "query-limits"], + "operation": "getOrganizationAssistantQuery-limits", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assistant/query-limits" + + return self._session.get(metadata, resource) diff --git a/meraki/api/batch/assistant.py b/meraki/api/batch/assistant.py new file mode 100644 index 0000000..31bf678 --- /dev/null +++ b/meraki/api/batch/assistant.py @@ -0,0 +1,3 @@ +class ActionBatchAssistant(object): + def __init__(self): + super(ActionBatchAssistant, self).__init__() diff --git a/meraki/api/batch/devices.py b/meraki/api/batch/devices.py index c3c5b13..7ac069a 100644 --- a/meraki/api/batch/devices.py +++ b/meraki/api/batch/devices.py @@ -213,6 +213,31 @@ def createDeviceLiveToolsPortsStatus(self, serial: str, **kwargs): } return action + def createDeviceLiveToolsPowerUsage(self, serial: str, **kwargs): + """ + **Enqueues a live tool job that retrieves details about a device's overall power usage. This endpoint has a sustained rate limit of one request every five seconds per device, with an allowed burst of five requests.** + https://developer.cisco.com/meraki/api-v1/#!create-device-live-tools-power-usage + + - serial (string): Serial + - callback (object): Details for the callback. Please include either an httpServerId OR url and sharedSecret + """ + + kwargs.update(locals()) + + serial = urllib.parse.quote(serial, safe="") + resource = f"/devices/{serial}/liveTools/power/usage" + + body_params = [ + "callback", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + action = { + "resource": resource, + "operation": "job", + "body": payload, + } + return action + def createDeviceLiveToolsReboot(self, serial: str, **kwargs): """ **Enqueue a job to reboot a device. This endpoint has a rate limit of one request every 60 seconds.** diff --git a/meraki/api/batch/organizations.py b/meraki/api/batch/organizations.py index 202a0cc..849f46a 100644 --- a/meraki/api/batch/organizations.py +++ b/meraki/api/batch/organizations.py @@ -1737,6 +1737,7 @@ def updateOrganizationLoginSecurity(self, organizationId: str, **kwargs): - enforceTwoFactorAuth (boolean): Boolean indicating whether users in this organization will be required to use an extra verification code when logging in to Dashboard. This code will be sent to their mobile phone via SMS, or can be generated by the authenticator application. - enforceLoginIpRanges (boolean): Boolean indicating whether organization will restrict access to Dashboard (including the API) from certain IP addresses. - loginIpRanges (array): List of acceptable IP ranges. Entries can be single IP addresses, IP address ranges, and CIDR subnets. + - enforceLockedIpSessions (boolean): Boolean indicating whether Dashboard sessions are locked to the IP address from which they were established. Only applicable to organizations that support locked-IP sessions; otherwise the parameter is ignored. - apiAuthentication (object): Details for indicating whether organization will restrict access to API (but not Dashboard) to certain IP addresses. """ @@ -1759,6 +1760,7 @@ def updateOrganizationLoginSecurity(self, organizationId: str, **kwargs): "enforceTwoFactorAuth", "enforceLoginIpRanges", "loginIpRanges", + "enforceLockedIpSessions", "apiAuthentication", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} diff --git a/meraki/api/batch/wireless.py b/meraki/api/batch/wireless.py index ca73d36..cfd2acc 100644 --- a/meraki/api/batch/wireless.py +++ b/meraki/api/batch/wireless.py @@ -869,7 +869,7 @@ def updateNetworkWirelessSsid(self, networkId: str, number: str, **kwargs): - radiusServerTimeout (integer): The amount of time for which a RADIUS client waits for a reply from the RADIUS server (must be between 1-10 seconds). - radiusServerAttemptsLimit (integer): The maximum number of transmit attempts after which a RADIUS server is failed over (must be between 1-5). - radiusFallbackEnabled (boolean): Whether or not higher priority RADIUS servers should be retried after 60 seconds. - - radiusRadsec (object): The current settings for RADIUS RADSec + - radiusRadsec (object): The current settings for RADIUS RadSec - radiusCoaEnabled (boolean): If true, Meraki devices will act as a RADIUS Dynamic Authorization Server and will respond to RADIUS Change-of-Authorization and Disconnect messages sent by the RADIUS server. - radiusFailoverPolicy (string): This policy determines how authentication requests should be handled in the event that all of the configured RADIUS servers are unreachable ('Deny access' or 'Allow access') - radiusLoadBalancingPolicy (string): This policy determines which RADIUS server will be contacted first in an authentication attempt and the ordering of any necessary retry attempts ('Strict priority order' or 'Round robin') diff --git a/meraki/api/devices.py b/meraki/api/devices.py index e1f5909..d8a95e4 100644 --- a/meraki/api/devices.py +++ b/meraki/api/devices.py @@ -964,6 +964,56 @@ def getDeviceLiveToolsPortsStatus(self, serial: str, jobId: str): return self._session.get(metadata, resource) + def createDeviceLiveToolsPowerUsage(self, serial: str, **kwargs): + """ + **Enqueues a live tool job that retrieves details about a device's overall power usage** + https://developer.cisco.com/meraki/api-v1/#!create-device-live-tools-power-usage + + - serial (string): Serial + - callback (object): Details for the callback. Please include either an httpServerId OR url and sharedSecret + """ + + kwargs.update(locals()) + + metadata = { + "tags": ["devices", "liveTools", "power", "usage"], + "operation": "createDeviceLiveToolsPowerUsage", + } + serial = urllib.parse.quote(str(serial), safe="") + resource = f"/devices/{serial}/liveTools/power/usage" + + body_params = [ + "callback", + ] + payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} + + if self._session._validate_kwargs: + all_params = [] + body_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning(f"createDeviceLiveToolsPowerUsage: ignoring unrecognized kwargs: {invalid}") + + return self._session.post(metadata, resource, payload) + + def getDeviceLiveToolsPowerUsage(self, serial: str, jobId: str): + """ + **Retrieve the status and results of a previously created live tool job fetching details about a device's overall power usage.** + https://developer.cisco.com/meraki/api-v1/#!get-device-live-tools-power-usage + + - serial (string): Serial + - jobId (string): Job ID + """ + + metadata = { + "tags": ["devices", "liveTools", "power", "usage"], + "operation": "getDeviceLiveToolsPowerUsage", + } + serial = urllib.parse.quote(str(serial), safe="") + jobId = urllib.parse.quote(str(jobId), safe="") + resource = f"/devices/{serial}/liveTools/power/usage/{jobId}" + + return self._session.get(metadata, resource) + def createDeviceLiveToolsReboot(self, serial: str, **kwargs): """ **Enqueue a job to reboot a device** diff --git a/meraki/api/organizations.py b/meraki/api/organizations.py index 080ddf3..dc2fe75 100644 --- a/meraki/api/organizations.py +++ b/meraki/api/organizations.py @@ -98,6 +98,7 @@ def updateOrganization(self, organizationId: str, **kwargs): - name (string): The name of the organization - management (object): Information about the organization's management system - api (object): API-specific settings + - privacy (object): Privacy-related settings for the organization. """ kwargs.update(locals()) @@ -113,6 +114,7 @@ def updateOrganization(self, organizationId: str, **kwargs): "name", "management", "api", + "privacy", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} @@ -2369,6 +2371,9 @@ def getOrganizationAssuranceClientsConnectedCountHistory(self, organizationId: s - organizationId (string): Organization ID - networkId (string): Network ID to query. + - serials (array): A list of serials of AP devices + - bands (array): Filter results by band. Valid bands are: 2.4, 5, and 6. + - ssidNumbers (array): Filter results by SSID number - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 14 days from today. - t1 (string): The end of the timespan for the data. t1 can be a maximum of 7 days after t0. - timespan (number): The timespan for which the information will be fetched. If specifying timespan, do not specify parameters t0 and t1. The value must be in seconds and be less than or equal to 7 days. The default is 8 hours. If interval is provided, the timespan will be autocalculated. @@ -2386,6 +2391,9 @@ def getOrganizationAssuranceClientsConnectedCountHistory(self, organizationId: s query_params = [ "networkId", + "serials", + "bands", + "ssidNumbers", "t0", "t1", "timespan", @@ -2393,8 +2401,18 @@ def getOrganizationAssuranceClientsConnectedCountHistory(self, organizationId: s ] params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + array_params = [ + "serials", + "bands", + "ssidNumbers", + ] + for k, v in kwargs.items(): + if k.strip() in array_params: + params[f"{k.strip()}[]"] = kwargs[f"{k}"] + params.pop(k.strip()) + if self._session._validate_kwargs: - all_params = query_params + all_params = query_params + array_params invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] if invalid and self._session._logger: self._session._logger.warning( @@ -8752,6 +8770,7 @@ def updateOrganizationLoginSecurity(self, organizationId: str, **kwargs): - enforceTwoFactorAuth (boolean): Boolean indicating whether users in this organization will be required to use an extra verification code when logging in to Dashboard. This code will be sent to their mobile phone via SMS, or can be generated by the authenticator application. - enforceLoginIpRanges (boolean): Boolean indicating whether organization will restrict access to Dashboard (including the API) from certain IP addresses. - loginIpRanges (array): List of acceptable IP ranges. Entries can be single IP addresses, IP address ranges, and CIDR subnets. + - enforceLockedIpSessions (boolean): Boolean indicating whether Dashboard sessions are locked to the IP address from which they were established. Only applicable to organizations that support locked-IP sessions; otherwise the parameter is ignored. - apiAuthentication (object): Details for indicating whether organization will restrict access to API (but not Dashboard) to certain IP addresses. """ @@ -8778,6 +8797,7 @@ def updateOrganizationLoginSecurity(self, organizationId: str, **kwargs): "enforceTwoFactorAuth", "enforceLoginIpRanges", "loginIpRanges", + "enforceLockedIpSessions", "apiAuthentication", ] payload = {k.strip(): v for k, v in kwargs.items() if k.strip() in body_params} diff --git a/meraki/api/wireless.py b/meraki/api/wireless.py index e87ed42..fba8a5d 100644 --- a/meraki/api/wireless.py +++ b/meraki/api/wireless.py @@ -2686,7 +2686,7 @@ def updateNetworkWirelessSsid(self, networkId: str, number: str, **kwargs): - radiusServerTimeout (integer): The amount of time for which a RADIUS client waits for a reply from the RADIUS server (must be between 1-10 seconds). - radiusServerAttemptsLimit (integer): The maximum number of transmit attempts after which a RADIUS server is failed over (must be between 1-5). - radiusFallbackEnabled (boolean): Whether or not higher priority RADIUS servers should be retried after 60 seconds. - - radiusRadsec (object): The current settings for RADIUS RADSec + - radiusRadsec (object): The current settings for RADIUS RadSec - radiusCoaEnabled (boolean): If true, Meraki devices will act as a RADIUS Dynamic Authorization Server and will respond to RADIUS Change-of-Authorization and Disconnect messages sent by the RADIUS server. - radiusFailoverPolicy (string): This policy determines how authentication requests should be handled in the event that all of the configured RADIUS servers are unreachable ('Deny access' or 'Allow access') - radiusLoadBalancingPolicy (string): This policy determines which RADIUS server will be contacted first in an authentication attempt and the ordering of any necessary retry attempts ('Strict priority order' or 'Round robin') @@ -5429,6 +5429,49 @@ def getOrganizationAssuranceWirelessExperienceMetricsOverviewHistoryByNetwork( return self._session.get_pages(metadata, resource, params, total_pages, direction) + def getOrganizationAssuranceWirelessExperienceMostImpactedNetworks(self, organizationId: str, **kwargs): + """ + **Returns the most impacted wireless experience networks and the top failure contributor for each network.** + https://developer.cisco.com/meraki/api-v1/#!get-organization-assurance-wireless-experience-most-impacted-networks + + - organizationId (string): Organization ID + - t0 (string): The beginning of the timespan for the data. The maximum lookback period is 14 days from today. + - t1 (string): The end of the timespan for the data. t1 can be a maximum of 14 days after t0. + - timespan (number): The timespan for which the information will be fetched. If specifying timespan, do not specify parameters t0 and t1. The value must be in seconds and be greater than or equal to 15 minutes and be less than or equal to 14 days. The default is 2 hours. + - limit (integer): Number of most impacted networks to return. Default is 5. Maximum is 10. + """ + + kwargs.update(locals()) + + if "limit" in kwargs: + options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + assert kwargs["limit"] in options, f'''"limit" cannot be "{kwargs["limit"]}", & must be set to one of: {options}''' + + metadata = { + "tags": ["wireless", "configure", "experience", "mostImpactedNetworks"], + "operation": "getOrganizationAssuranceWirelessExperienceMostImpactedNetworks", + } + organizationId = urllib.parse.quote(str(organizationId), safe="") + resource = f"/organizations/{organizationId}/assurance/wireless/experience/mostImpactedNetworks" + + query_params = [ + "t0", + "t1", + "timespan", + "limit", + ] + params = {k.strip(): v for k, v in kwargs.items() if k.strip() in query_params} + + if self._session._validate_kwargs: + all_params = query_params + invalid = [k for k in kwargs if k.strip() not in all_params and k != "self"] + if invalid and self._session._logger: + self._session._logger.warning( + f"getOrganizationAssuranceWirelessExperienceMostImpactedNetworks: ignoring unrecognized kwargs: {invalid}" + ) + + return self._session.get(metadata, resource, params) + def getOrganizationAssuranceWirelessExperienceSuccessfulConnectsByNetwork( self, organizationId: str, total_pages=1, direction="next", **kwargs ): @@ -8759,7 +8802,7 @@ def getOrganizationWirelessDevicesProvisioningRecommendationsTags(self, organiza def getOrganizationWirelessDevicesRadsecCertificatesAuthorities(self, organizationId: str, **kwargs): """ - **Query for details on the organization's RADSEC device Certificate Authority certificates (CAs)** + **Query for details on the organization's RadSec device Certificate Authority certificates (CAs)** https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-radsec-certificates-authorities - organizationId (string): Organization ID @@ -8800,7 +8843,7 @@ def getOrganizationWirelessDevicesRadsecCertificatesAuthorities(self, organizati def updateOrganizationWirelessDevicesRadsecCertificatesAuthorities(self, organizationId: str, **kwargs): """ - **Update an organization's RADSEC device Certificate Authority (CA) state** + **Update an organization's RadSec device Certificate Authority (CA) state** https://developer.cisco.com/meraki/api-v1/#!update-organization-wireless-devices-radsec-certificates-authorities - organizationId (string): Organization ID @@ -8835,7 +8878,7 @@ def updateOrganizationWirelessDevicesRadsecCertificatesAuthorities(self, organiz def createOrganizationWirelessDevicesRadsecCertificatesAuthority(self, organizationId: str): """ - **Create an organization's RADSEC device Certificate Authority (CA)** + **Create an organization's RadSec device Certificate Authority (CA)** https://developer.cisco.com/meraki/api-v1/#!create-organization-wireless-devices-radsec-certificates-authority - organizationId (string): Organization ID @@ -8852,7 +8895,7 @@ def createOrganizationWirelessDevicesRadsecCertificatesAuthority(self, organizat def getOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrls(self, organizationId: str, **kwargs): """ - **Query for certificate revocation list (CRL) for the organization's RADSEC device Certificate Authorities (CAs).** + **Query for certificate revocation list (CRL) for the organization's RadSec device Certificate Authorities (CAs).** https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-radsec-certificates-authorities-crls - organizationId (string): Organization ID @@ -8893,7 +8936,7 @@ def getOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrls(self, organi def getOrganizationWirelessDevicesRadsecCertificatesAuthoritiesCrlsDeltas(self, organizationId: str, **kwargs): """ - **Query for all delta certificate revocation list (CRL) for the organization's RADSEC device Certificate Authority (CA) with the given id.** + **Query for all delta certificate revocation list (CRL) for the organization's RadSec device Certificate Authority (CA) with the given id.** https://developer.cisco.com/meraki/api-v1/#!get-organization-wireless-devices-radsec-certificates-authorities-crls-deltas - organizationId (string): Organization ID diff --git a/pyproject.toml b/pyproject.toml index 738b1a3..c9ceabc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "meraki" -version = "3.1.0b3" +version = "3.2.0b0" description = "Cisco Meraki Dashboard API library" authors = [ {name = "Cisco Meraki", email = "api-feedback@meraki.net"} diff --git a/uv.lock b/uv.lock index 954d57c..f7a1e81 100644 --- a/uv.lock +++ b/uv.lock @@ -537,7 +537,7 @@ wheels = [ [[package]] name = "meraki" -version = "3.1.0b3" +version = "3.2.0b0" source = { editable = "." } dependencies = [ { name = "aiohttp" },