From 66b47be0048731efcf94718e101930b818fd8a66 Mon Sep 17 00:00:00 2001 From: stlc-bot Date: Tue, 29 Sep 2026 15:24:06 +0000 Subject: [PATCH] Build SDK Stainless-Generated-From: 528318270ac3593449414f95b3e21d42e84d8c7f --- src/mobilerun_sdk/_client.py | 4 + src/mobilerun_sdk/resources/apps.py | 72 ++++- .../resources/assistant/conversations.py | 140 +++++++-- src/mobilerun_sdk/resources/carriers.py | 54 +++- .../resources/connect/proxies.py | 54 +++- src/mobilerun_sdk/resources/connect/users.py | 54 +++- .../packages/credentials/credentials.py | 36 ++- .../packages/credentials/fields.py | 54 +++- .../credentials/packages/packages.py | 18 +- .../resources/devices/actions.py | 72 ++++- src/mobilerun_sdk/resources/devices/apps.py | 116 +++++++- .../resources/devices/browser.py | 38 ++- .../resources/devices/clipboard.py | 18 +- .../resources/devices/deep_link.py | 18 +- .../resources/devices/devices.py | 265 ++++++++++++------ .../resources/devices/esim/apn.py | 36 ++- .../resources/devices/esim/esim.py | 62 +++- src/mobilerun_sdk/resources/devices/files.py | 16 ++ .../resources/devices/keyboard.py | 54 +++- src/mobilerun_sdk/resources/devices/kiosk.py | 36 ++- .../resources/devices/language.py | 18 +- .../resources/devices/location.py | 36 ++- .../resources/devices/media_sessions.py | 54 +++- .../resources/devices/profile.py | 18 +- src/mobilerun_sdk/resources/devices/proxy.py | 36 ++- .../resources/devices/recordings.py | 66 ++++- .../resources/devices/timezone.py | 18 +- .../resources/devices/traffic_sessions.py | 40 ++- src/mobilerun_sdk/resources/files.py | 96 ++++++- .../resources/mailboxes/mailboxes.py | 100 +++++-- .../resources/messages/conversations.py | 18 +- src/mobilerun_sdk/resources/notifications.py | 18 +- .../resources/numbers/numbers.py | 64 ++++- src/mobilerun_sdk/resources/profiles.py | 54 +++- src/mobilerun_sdk/resources/proxies.py | 88 +++++- src/mobilerun_sdk/resources/store/apps.py | 18 +- src/mobilerun_sdk/resources/tasks/tasks.py | 86 ++++-- .../resources/webhooks/webhooks.py | 90 +++++- .../resources/workflows/action_catalog.py | 4 +- .../resources/workflows/actions/actions.py | 58 +++- .../resources/workflows/events.py | 36 ++- .../resources/workflows/executions.py | 18 +- .../resources/workflows/flows/actions.py | 54 +++- .../resources/workflows/flows/flows.py | 122 ++++++-- .../resources/workflows/triggers.py | 98 ++++--- src/mobilerun_sdk/types/app_list_response.py | 2 +- .../types/app_list_versions_response.py | 2 +- .../assistant/conversation_create_params.py | 11 +- .../assistant/conversation_create_response.py | 2 + .../assistant/conversation_list_response.py | 4 + .../assistant/conversation_update_response.py | 2 + .../types/connect/proxy_buy_params.py | 11 +- .../types/connect/proxy_buy_response.py | 8 + .../types/connect/proxy_list_response.py | 8 + .../types/connect/proxy_retrieve_response.py | 8 + .../types/device_create_params.py | 31 +- src/mobilerun_sdk/types/device_list_params.py | 15 +- .../types/devices/recording_start_params.py | 6 +- .../devices/traffic_session_create_params.py | 4 +- .../types/file_upload_url_params.py | 2 - .../types/mailbox_create_params.py | 4 +- .../types/mailbox_create_response.py | 16 +- .../types/mailbox_delete_response.py | 16 +- .../types/mailbox_list_response.py | 16 +- .../types/mailbox_restart_response.py | 16 +- .../types/mailbox_retrieve_response.py | 16 +- .../types/mailbox_uncancel_response.py | 16 +- .../types/mailbox_update_response.py | 16 +- .../types/number_create_params.py | 3 - .../types/store/app_list_response.py | 2 +- .../types/store/app_retrieve_response.py | 4 +- .../types/task_get_trajectory_response.py | 3 + src/mobilerun_sdk/types/task_run_params.py | 4 +- .../types/task_run_streamed_params.py | 2 +- .../types/webhook_event_types_response.py | 2 + .../workflows/action_catalog_list_params.py | 2 +- .../workflows/action_catalog_list_response.py | 6 +- .../action_catalog_retrieve_response.py | 6 +- .../types/workflows/action_create_response.py | 2 +- .../types/workflows/action_list_params.py | 2 +- .../types/workflows/action_list_response.py | 2 +- .../workflows/action_retrieve_response.py | 2 +- .../types/workflows/action_update_response.py | 2 +- .../types/workflows/event_dry_run_response.py | 20 +- .../workflows/execution_retrieve_response.py | 102 ++++++- .../types/workflows/flow_clone_response.py | 18 +- .../types/workflows/flow_create_params.py | 31 +- .../types/workflows/flow_create_response.py | 18 +- .../types/workflows/flow_dry_run_response.py | 2 +- .../types/workflows/flow_list_response.py | 18 +- .../types/workflows/flow_retrieve_response.py | 18 +- .../types/workflows/flow_unblock_response.py | 18 +- .../types/workflows/flow_update_params.py | 18 +- .../types/workflows/flow_update_response.py | 18 +- .../types/workflows/trigger_fire_params.py | 12 +- .../assistant/test_conversations.py | 2 - tests/api_resources/connect/test_proxies.py | 4 +- .../devices/test_traffic_sessions.py | 10 - tests/api_resources/test_devices.py | 38 ++- tests/api_resources/test_files.py | 2 - tests/api_resources/test_mailboxes.py | 26 +- tests/api_resources/test_numbers.py | 2 - tests/api_resources/test_tasks.py | 2 - tests/api_resources/workflows/test_flows.py | 24 ++ .../api_resources/workflows/test_triggers.py | 20 -- tests/test_client.py | 62 ++++ 106 files changed, 2690 insertions(+), 596 deletions(-) diff --git a/src/mobilerun_sdk/_client.py b/src/mobilerun_sdk/_client.py index cb8ba65a..2a60300b 100644 --- a/src/mobilerun_sdk/_client.py +++ b/src/mobilerun_sdk/_client.py @@ -149,6 +149,8 @@ def __init__( _strict_response_validation=_strict_response_validation, ) + self._idempotency_header = "Idempotency-Key" + @cached_property def apps(self) -> AppsResource: from .resources.apps import AppsResource @@ -449,6 +451,8 @@ def __init__( _strict_response_validation=_strict_response_validation, ) + self._idempotency_header = "Idempotency-Key" + @cached_property def apps(self) -> AsyncAppsResource: from .resources.apps import AsyncAppsResource diff --git a/src/mobilerun_sdk/resources/apps.py b/src/mobilerun_sdk/resources/apps.py index 3f0f323f..f8e5ff6c 100644 --- a/src/mobilerun_sdk/resources/apps.py +++ b/src/mobilerun_sdk/resources/apps.py @@ -146,6 +146,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> AppDeleteResponse: """Deletes an uploaded app by ID. @@ -160,13 +161,19 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( path_template("/apps/{id}", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=AppDeleteResponse, ) @@ -181,6 +188,7 @@ def confirm_upload( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> AppConfirmUploadResponse: """ Verifies the uploaded files in R2 and sets the app version status to available. @@ -195,13 +203,19 @@ def confirm_upload( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( path_template("/apps/{id}/confirm-upload", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=AppConfirmUploadResponse, ) @@ -226,6 +240,7 @@ def create_signed_upload_url( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> AppCreateSignedUploadURLResponse: """ Creates or updates an app and returns pre-signed Cloudflare R2 upload URLs for @@ -241,6 +256,8 @@ def create_signed_upload_url( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/apps/create-signed-upload-url", @@ -261,7 +278,11 @@ def create_signed_upload_url( app_create_signed_upload_url_params.AppCreateSignedUploadURLParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=AppCreateSignedUploadURLResponse, ) @@ -310,6 +331,7 @@ def mark_failed( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> AppMarkFailedResponse: """ Sets the app status to failed. @@ -322,13 +344,19 @@ def mark_failed( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( path_template("/apps/{id}/mark-failed", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=AppMarkFailedResponse, ) @@ -471,6 +499,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> AppDeleteResponse: """Deletes an uploaded app by ID. @@ -485,13 +514,19 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( path_template("/apps/{id}", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=AppDeleteResponse, ) @@ -506,6 +541,7 @@ async def confirm_upload( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> AppConfirmUploadResponse: """ Verifies the uploaded files in R2 and sets the app version status to available. @@ -520,13 +556,19 @@ async def confirm_upload( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( path_template("/apps/{id}/confirm-upload", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=AppConfirmUploadResponse, ) @@ -551,6 +593,7 @@ async def create_signed_upload_url( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> AppCreateSignedUploadURLResponse: """ Creates or updates an app and returns pre-signed Cloudflare R2 upload URLs for @@ -566,6 +609,8 @@ async def create_signed_upload_url( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/apps/create-signed-upload-url", @@ -586,7 +631,11 @@ async def create_signed_upload_url( app_create_signed_upload_url_params.AppCreateSignedUploadURLParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=AppCreateSignedUploadURLResponse, ) @@ -635,6 +684,7 @@ async def mark_failed( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> AppMarkFailedResponse: """ Sets the app status to failed. @@ -647,13 +697,19 @@ async def mark_failed( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( path_template("/apps/{id}/mark-failed", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=AppMarkFailedResponse, ) diff --git a/src/mobilerun_sdk/resources/assistant/conversations.py b/src/mobilerun_sdk/resources/assistant/conversations.py index 3747f5dd..68df126a 100644 --- a/src/mobilerun_sdk/resources/assistant/conversations.py +++ b/src/mobilerun_sdk/resources/assistant/conversations.py @@ -8,7 +8,7 @@ import httpx from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform +from ..._utils import path_template, maybe_transform, async_maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import ( @@ -71,13 +71,13 @@ def create( title: str, agent: str | Omit = omit, description: str | Omit = omit, - idempotency_key: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationCreateResponse: """Creates a titled agent session. @@ -87,10 +87,6 @@ def create( instead of a second one. Args: - idempotency_key: Optional client key. Reusing the same key with the same request body by the same - authenticated caller within 24 hours returns the already-created session instead - of a second one. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -98,8 +94,9 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ - extra_headers = {**strip_not_given({"Idempotency-Key": idempotency_key}), **(extra_headers or {})} return self._post( "/assistant/chat/sessions", body=maybe_transform( @@ -111,7 +108,11 @@ def create( conversation_create_params.ConversationCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationCreateResponse, ) @@ -130,6 +131,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationUpdateResponse: """Rename, change status, and/or pin. @@ -148,6 +150,8 @@ def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") @@ -163,7 +167,11 @@ def update( conversation_update_params.ConversationUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationUpdateResponse, ) @@ -228,6 +236,7 @@ def abort( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationAbortResponse: """Abort the in-flight chat turn owned by `sessionId`. @@ -242,6 +251,8 @@ def abort( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/assistant/chat/abort", @@ -253,7 +264,11 @@ def abort( conversation_abort_params.ConversationAbortParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationAbortResponse, ) @@ -269,6 +284,7 @@ def answer_permission( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationAnswerPermissionResponse: """Deliver a HITL approval/rejection for an in-flight turn. @@ -287,6 +303,8 @@ def answer_permission( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/assistant/chat/permission", @@ -298,7 +316,11 @@ def answer_permission( conversation_answer_permission_params.ConversationAnswerPermissionParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationAnswerPermissionResponse, ) @@ -314,6 +336,7 @@ def answer_question( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationAnswerQuestionResponse: """Deliver the user's answers to the agent's pending question for an in-flight turn. @@ -328,6 +351,8 @@ def answer_question( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/assistant/chat/question", @@ -339,7 +364,11 @@ def answer_question( conversation_answer_question_params.ConversationAnswerQuestionParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationAnswerQuestionResponse, ) @@ -398,6 +427,7 @@ def reject_question( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationRejectQuestionResponse: """Dismiss the agent's pending question. @@ -412,6 +442,8 @@ def reject_question( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/assistant/chat/question/reject", @@ -419,7 +451,11 @@ def reject_question( {"question_id": question_id}, conversation_reject_question_params.ConversationRejectQuestionParams ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationRejectQuestionResponse, ) @@ -436,6 +472,7 @@ def send( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationSendResponse: """Send a single user message. @@ -456,6 +493,8 @@ def send( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/assistant/chat/message", @@ -468,7 +507,11 @@ def send( conversation_send_params.ConversationSendParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationSendResponse, ) @@ -543,13 +586,13 @@ async def create( title: str, agent: str | Omit = omit, description: str | Omit = omit, - idempotency_key: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationCreateResponse: """Creates a titled agent session. @@ -559,10 +602,6 @@ async def create( instead of a second one. Args: - idempotency_key: Optional client key. Reusing the same key with the same request body by the same - authenticated caller within 24 hours returns the already-created session instead - of a second one. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -570,8 +609,9 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ - extra_headers = {**strip_not_given({"Idempotency-Key": idempotency_key}), **(extra_headers or {})} return await self._post( "/assistant/chat/sessions", body=await async_maybe_transform( @@ -583,7 +623,11 @@ async def create( conversation_create_params.ConversationCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationCreateResponse, ) @@ -602,6 +646,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationUpdateResponse: """Rename, change status, and/or pin. @@ -620,6 +665,8 @@ async def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") @@ -635,7 +682,11 @@ async def update( conversation_update_params.ConversationUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationUpdateResponse, ) @@ -700,6 +751,7 @@ async def abort( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationAbortResponse: """Abort the in-flight chat turn owned by `sessionId`. @@ -714,6 +766,8 @@ async def abort( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/assistant/chat/abort", @@ -725,7 +779,11 @@ async def abort( conversation_abort_params.ConversationAbortParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationAbortResponse, ) @@ -741,6 +799,7 @@ async def answer_permission( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationAnswerPermissionResponse: """Deliver a HITL approval/rejection for an in-flight turn. @@ -759,6 +818,8 @@ async def answer_permission( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/assistant/chat/permission", @@ -770,7 +831,11 @@ async def answer_permission( conversation_answer_permission_params.ConversationAnswerPermissionParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationAnswerPermissionResponse, ) @@ -786,6 +851,7 @@ async def answer_question( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationAnswerQuestionResponse: """Deliver the user's answers to the agent's pending question for an in-flight turn. @@ -800,6 +866,8 @@ async def answer_question( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/assistant/chat/question", @@ -811,7 +879,11 @@ async def answer_question( conversation_answer_question_params.ConversationAnswerQuestionParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationAnswerQuestionResponse, ) @@ -870,6 +942,7 @@ async def reject_question( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationRejectQuestionResponse: """Dismiss the agent's pending question. @@ -884,6 +957,8 @@ async def reject_question( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/assistant/chat/question/reject", @@ -891,7 +966,11 @@ async def reject_question( {"question_id": question_id}, conversation_reject_question_params.ConversationRejectQuestionParams ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationRejectQuestionResponse, ) @@ -908,6 +987,7 @@ async def send( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationSendResponse: """Send a single user message. @@ -928,6 +1008,8 @@ async def send( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/assistant/chat/message", @@ -940,7 +1022,11 @@ async def send( conversation_send_params.ConversationSendParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationSendResponse, ) diff --git a/src/mobilerun_sdk/resources/carriers.py b/src/mobilerun_sdk/resources/carriers.py index a674b8f8..ef389bf1 100644 --- a/src/mobilerun_sdk/resources/carriers.py +++ b/src/mobilerun_sdk/resources/carriers.py @@ -73,6 +73,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> CarrierCreateResponse: """ Create a new carrier @@ -117,6 +118,8 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/carriers", @@ -142,7 +145,11 @@ def create( carrier_create_params.CarrierCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=CarrierCreateResponse, ) @@ -204,6 +211,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> CarrierUpdateResponse: """ Update a carrier @@ -246,6 +254,8 @@ def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._patch( path_template("/carriers/{carrier_id}", carrier_id=carrier_id), @@ -269,7 +279,11 @@ def update( carrier_update_params.CarrierUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=CarrierUpdateResponse, ) @@ -346,6 +360,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> CarrierDeleteResponse: """ Delete a carrier @@ -360,11 +375,17 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._delete( path_template("/carriers/{carrier_id}", carrier_id=carrier_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=CarrierDeleteResponse, ) @@ -461,6 +482,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> CarrierCreateResponse: """ Create a new carrier @@ -505,6 +527,8 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/carriers", @@ -530,7 +554,11 @@ async def create( carrier_create_params.CarrierCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=CarrierCreateResponse, ) @@ -592,6 +620,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> CarrierUpdateResponse: """ Update a carrier @@ -634,6 +663,8 @@ async def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._patch( path_template("/carriers/{carrier_id}", carrier_id=carrier_id), @@ -657,7 +688,11 @@ async def update( carrier_update_params.CarrierUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=CarrierUpdateResponse, ) @@ -734,6 +769,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> CarrierDeleteResponse: """ Delete a carrier @@ -748,11 +784,17 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._delete( path_template("/carriers/{carrier_id}", carrier_id=carrier_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=CarrierDeleteResponse, ) diff --git a/src/mobilerun_sdk/resources/connect/proxies.py b/src/mobilerun_sdk/resources/connect/proxies.py index 718dc6d6..17f897d4 100644 --- a/src/mobilerun_sdk/resources/connect/proxies.py +++ b/src/mobilerun_sdk/resources/connect/proxies.py @@ -9,7 +9,7 @@ import httpx from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given -from ..._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform +from ..._utils import path_template, maybe_transform, async_maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import ( @@ -140,13 +140,14 @@ def buy( *, country: str, type: Literal["dedicated_residential", "residential", "mobile"], - idempotency_key: str | Omit = omit, + name: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyBuyResponse: """ Provisions a proxy of the requested type for the caller in the selected country. @@ -154,6 +155,10 @@ def buy( Args: country: ISO 3166-1 alpha-2 country code to provision the proxy in. + name: Display name for the proxy, up to 64 characters excluding surrounding + whitespace, and containing no NUL. Omit it (or send only whitespace) to get a + generated label built from the country, type, and id. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -161,19 +166,25 @@ def buy( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ - extra_headers = {**strip_not_given({"Idempotency-Key": idempotency_key}), **(extra_headers or {})} return self._post( "/connect/proxies", body=maybe_transform( { "country": country, "type": type, + "name": name, }, proxy_buy_params.ProxyBuyParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProxyBuyResponse, ) @@ -188,6 +199,7 @@ def cancel( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Deletes the proxy identified by the path ID and releases its provisioning. @@ -201,6 +213,8 @@ def cancel( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") @@ -208,7 +222,11 @@ def cancel( return self._delete( path_template("/connect/proxies/{id}", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -507,13 +525,14 @@ async def buy( *, country: str, type: Literal["dedicated_residential", "residential", "mobile"], - idempotency_key: str | Omit = omit, + name: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyBuyResponse: """ Provisions a proxy of the requested type for the caller in the selected country. @@ -521,6 +540,10 @@ async def buy( Args: country: ISO 3166-1 alpha-2 country code to provision the proxy in. + name: Display name for the proxy, up to 64 characters excluding surrounding + whitespace, and containing no NUL. Omit it (or send only whitespace) to get a + generated label built from the country, type, and id. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -528,19 +551,25 @@ async def buy( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ - extra_headers = {**strip_not_given({"Idempotency-Key": idempotency_key}), **(extra_headers or {})} return await self._post( "/connect/proxies", body=await async_maybe_transform( { "country": country, "type": type, + "name": name, }, proxy_buy_params.ProxyBuyParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProxyBuyResponse, ) @@ -555,6 +584,7 @@ async def cancel( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Deletes the proxy identified by the path ID and releases its provisioning. @@ -568,6 +598,8 @@ async def cancel( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") @@ -575,7 +607,11 @@ async def cancel( return await self._delete( path_template("/connect/proxies/{id}", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) diff --git a/src/mobilerun_sdk/resources/connect/users.py b/src/mobilerun_sdk/resources/connect/users.py index 2a030aae..ea55b1f3 100644 --- a/src/mobilerun_sdk/resources/connect/users.py +++ b/src/mobilerun_sdk/resources/connect/users.py @@ -63,6 +63,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> UserCreateResponse: """ Creates a SOCKS5 credential, optionally bound to a proxy for dedicated routing. @@ -82,6 +83,8 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/connect/users", @@ -94,7 +97,11 @@ def create( user_create_params.UserCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=UserCreateResponse, ) @@ -145,6 +152,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> UserUpdateResponse: """ Rebind the user to a different proxy (or detach it by passing null). @@ -160,6 +168,8 @@ def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") @@ -167,7 +177,11 @@ def update( path_template("/connect/users/{id}", id=id), body=maybe_transform({"proxy_id": proxy_id}, user_update_params.UserUpdateParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=UserUpdateResponse, ) @@ -234,6 +248,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Deletes the SOCKS5 user identified by the path ID, revoking its credentials and @@ -247,6 +262,8 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") @@ -254,7 +271,11 @@ def delete( return self._delete( path_template("/connect/users/{id}", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -440,6 +461,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> UserCreateResponse: """ Creates a SOCKS5 credential, optionally bound to a proxy for dedicated routing. @@ -459,6 +481,8 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/connect/users", @@ -471,7 +495,11 @@ async def create( user_create_params.UserCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=UserCreateResponse, ) @@ -522,6 +550,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> UserUpdateResponse: """ Rebind the user to a different proxy (or detach it by passing null). @@ -537,6 +566,8 @@ async def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") @@ -544,7 +575,11 @@ async def update( path_template("/connect/users/{id}", id=id), body=await async_maybe_transform({"proxy_id": proxy_id}, user_update_params.UserUpdateParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=UserUpdateResponse, ) @@ -611,6 +646,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Deletes the SOCKS5 user identified by the path ID, revoking its credentials and @@ -624,6 +660,8 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") @@ -631,7 +669,11 @@ async def delete( return await self._delete( path_template("/connect/users/{id}", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) diff --git a/src/mobilerun_sdk/resources/credentials/packages/credentials/credentials.py b/src/mobilerun_sdk/resources/credentials/packages/credentials/credentials.py index afbe1bca..80de6019 100644 --- a/src/mobilerun_sdk/resources/credentials/packages/credentials/credentials.py +++ b/src/mobilerun_sdk/resources/credentials/packages/credentials/credentials.py @@ -69,6 +69,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> CredentialCreateResponse: """ Creates a credential under the given package with a `credentialName` and at @@ -83,6 +84,8 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not package_name: raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") @@ -96,7 +99,11 @@ def create( credential_create_params.CredentialCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=CredentialCreateResponse, ) @@ -153,6 +160,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> CredentialDeleteResponse: """ Permanently deletes the credential identified by `packageName` and @@ -166,6 +174,8 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not package_name: raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") @@ -178,7 +188,11 @@ def delete( credential_name=credential_name, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=CredentialDeleteResponse, ) @@ -220,6 +234,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> CredentialCreateResponse: """ Creates a credential under the given package with a `credentialName` and at @@ -234,6 +249,8 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not package_name: raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") @@ -247,7 +264,11 @@ async def create( credential_create_params.CredentialCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=CredentialCreateResponse, ) @@ -304,6 +325,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> CredentialDeleteResponse: """ Permanently deletes the credential identified by `packageName` and @@ -317,6 +339,8 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not package_name: raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") @@ -329,7 +353,11 @@ async def delete( credential_name=credential_name, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=CredentialDeleteResponse, ) diff --git a/src/mobilerun_sdk/resources/credentials/packages/credentials/fields.py b/src/mobilerun_sdk/resources/credentials/packages/credentials/fields.py index 34acdff4..d687a94c 100644 --- a/src/mobilerun_sdk/resources/credentials/packages/credentials/fields.py +++ b/src/mobilerun_sdk/resources/credentials/packages/credentials/fields.py @@ -60,6 +60,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FieldCreateResponse: """Adds a single field to an existing credential. @@ -75,6 +76,8 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not package_name: raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") @@ -94,7 +97,11 @@ def create( field_create_params.FieldCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FieldCreateResponse, ) @@ -114,6 +121,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FieldUpdateResponse: """ Updates the value of an existing field on a credential, identified by @@ -128,6 +136,8 @@ def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not package_name: raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") @@ -144,7 +154,11 @@ def update( ), body=maybe_transform({"value": value}, field_update_params.FieldUpdateParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FieldUpdateResponse, ) @@ -163,6 +177,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FieldDeleteResponse: """ Removes a single field of the given `fieldType` from the specified credential @@ -176,6 +191,8 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not package_name: raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") @@ -191,7 +208,11 @@ def delete( field_type=field_type, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FieldDeleteResponse, ) @@ -232,6 +253,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FieldCreateResponse: """Adds a single field to an existing credential. @@ -247,6 +269,8 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not package_name: raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") @@ -266,7 +290,11 @@ async def create( field_create_params.FieldCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FieldCreateResponse, ) @@ -286,6 +314,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FieldUpdateResponse: """ Updates the value of an existing field on a credential, identified by @@ -300,6 +329,8 @@ async def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not package_name: raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") @@ -316,7 +347,11 @@ async def update( ), body=await async_maybe_transform({"value": value}, field_update_params.FieldUpdateParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FieldUpdateResponse, ) @@ -335,6 +370,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FieldDeleteResponse: """ Removes a single field of the given `fieldType` from the specified credential @@ -348,6 +384,8 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not package_name: raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") @@ -363,7 +401,11 @@ async def delete( field_type=field_type, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FieldDeleteResponse, ) diff --git a/src/mobilerun_sdk/resources/credentials/packages/packages.py b/src/mobilerun_sdk/resources/credentials/packages/packages.py index ba676828..3476d7f5 100644 --- a/src/mobilerun_sdk/resources/credentials/packages/packages.py +++ b/src/mobilerun_sdk/resources/credentials/packages/packages.py @@ -65,6 +65,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> PackageCreateResponse: """ Creates a new package (identified by `packageName`) under which credentials can @@ -79,12 +80,18 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/credentials/packages", body=maybe_transform({"package_name": package_name}, package_create_params.PackageCreateParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=PackageCreateResponse, ) @@ -182,6 +189,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> PackageCreateResponse: """ Creates a new package (identified by `packageName`) under which credentials can @@ -196,12 +204,18 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/credentials/packages", body=await async_maybe_transform({"package_name": package_name}, package_create_params.PackageCreateParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=PackageCreateResponse, ) diff --git a/src/mobilerun_sdk/resources/devices/actions.py b/src/mobilerun_sdk/resources/devices/actions.py index 8ebefb67..2290a2b8 100644 --- a/src/mobilerun_sdk/resources/devices/actions.py +++ b/src/mobilerun_sdk/resources/devices/actions.py @@ -58,6 +58,7 @@ def global_( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Performs a global system action on the device, such as navigating back or going @@ -71,6 +72,8 @@ def global_( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -85,7 +88,11 @@ def global_( path_template("/devices/{device_id}/global", device_id=device_id), body=maybe_transform({"action": action}, action_global_params.ActionGlobalParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -142,6 +149,7 @@ def set_overlay_visible( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Shows or hides the accessibility overlay on the device based on the visibility @@ -155,6 +163,8 @@ def set_overlay_visible( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -169,7 +179,11 @@ def set_overlay_visible( path_template("/devices/{device_id}/overlay", device_id=device_id), body=maybe_transform({"visible": visible}, action_set_overlay_visible_params.ActionSetOverlayVisibleParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -191,6 +205,7 @@ def swipe( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Swipes from a start coordinate to an end coordinate over the given duration in @@ -207,6 +222,8 @@ def swipe( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -231,7 +248,11 @@ def swipe( action_swipe_params.ActionSwipeParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -250,6 +271,7 @@ def tap( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Taps the device screen at the given x/y coordinates. @@ -264,6 +286,8 @@ def tap( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -285,7 +309,11 @@ def tap( action_tap_params.ActionTapParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -323,6 +351,7 @@ async def global_( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Performs a global system action on the device, such as navigating back or going @@ -336,6 +365,8 @@ async def global_( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -350,7 +381,11 @@ async def global_( path_template("/devices/{device_id}/global", device_id=device_id), body=await async_maybe_transform({"action": action}, action_global_params.ActionGlobalParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -407,6 +442,7 @@ async def set_overlay_visible( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Shows or hides the accessibility overlay on the device based on the visibility @@ -420,6 +456,8 @@ async def set_overlay_visible( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -436,7 +474,11 @@ async def set_overlay_visible( {"visible": visible}, action_set_overlay_visible_params.ActionSetOverlayVisibleParams ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -458,6 +500,7 @@ async def swipe( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Swipes from a start coordinate to an end coordinate over the given duration in @@ -474,6 +517,8 @@ async def swipe( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -498,7 +543,11 @@ async def swipe( action_swipe_params.ActionSwipeParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -517,6 +566,7 @@ async def tap( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Taps the device screen at the given x/y coordinates. @@ -531,6 +581,8 @@ async def tap( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -552,7 +604,11 @@ async def tap( action_tap_params.ActionTapParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) diff --git a/src/mobilerun_sdk/resources/devices/apps.py b/src/mobilerun_sdk/resources/devices/apps.py index e672a017..2f069d0a 100644 --- a/src/mobilerun_sdk/resources/devices/apps.py +++ b/src/mobilerun_sdk/resources/devices/apps.py @@ -111,6 +111,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Uninstalls the app identified by the path package name from the device. @@ -124,6 +125,8 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -139,7 +142,11 @@ def delete( return self._delete( path_template("/devices/{device_id}/apps/{package_name}", device_id=device_id, package_name=package_name), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -157,6 +164,7 @@ def grant_permission( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Grants an Android runtime permission to the package named in the path. @@ -173,6 +181,8 @@ def grant_permission( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -195,7 +205,11 @@ def grant_permission( permission=permission, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -217,6 +231,7 @@ def install( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Requests an app install on the device. @@ -253,6 +268,8 @@ def install( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ ... @@ -273,6 +290,7 @@ def install( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Requests an app install on the device. @@ -309,6 +327,8 @@ def install( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ ... @@ -329,6 +349,7 @@ def install( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -352,7 +373,11 @@ def install( app_install_params.AppInstallParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -414,6 +439,7 @@ def revoke_permission( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Revokes an Android runtime permission from the package named in the path. @@ -430,6 +456,8 @@ def revoke_permission( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -452,7 +480,11 @@ def revoke_permission( permission=permission, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -470,6 +502,7 @@ def start( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Launches the app identified by the path package name, optionally starting a @@ -484,6 +517,8 @@ def start( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -500,7 +535,11 @@ def start( path_template("/devices/{device_id}/apps/{package_name}", device_id=device_id, package_name=package_name), body=maybe_transform({"activity": activity}, app_start_params.AppStartParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -518,6 +557,7 @@ def stop( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Force-stops the app identified by the path package name. @@ -535,6 +575,8 @@ def stop( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -551,7 +593,11 @@ def stop( path_template("/devices/{device_id}/apps/{package_name}", device_id=device_id, package_name=package_name), body=maybe_transform({"clear_data": clear_data}, app_stop_params.AppStopParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -643,6 +689,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Uninstalls the app identified by the path package name from the device. @@ -656,6 +703,8 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -671,7 +720,11 @@ async def delete( return await self._delete( path_template("/devices/{device_id}/apps/{package_name}", device_id=device_id, package_name=package_name), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -689,6 +742,7 @@ async def grant_permission( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Grants an Android runtime permission to the package named in the path. @@ -705,6 +759,8 @@ async def grant_permission( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -727,7 +783,11 @@ async def grant_permission( permission=permission, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -749,6 +809,7 @@ async def install( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Requests an app install on the device. @@ -785,6 +846,8 @@ async def install( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ ... @@ -805,6 +868,7 @@ async def install( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Requests an app install on the device. @@ -841,6 +905,8 @@ async def install( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ ... @@ -861,6 +927,7 @@ async def install( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -884,7 +951,11 @@ async def install( app_install_params.AppInstallParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -946,6 +1017,7 @@ async def revoke_permission( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Revokes an Android runtime permission from the package named in the path. @@ -962,6 +1034,8 @@ async def revoke_permission( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -984,7 +1058,11 @@ async def revoke_permission( permission=permission, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -1002,6 +1080,7 @@ async def start( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Launches the app identified by the path package name, optionally starting a @@ -1016,6 +1095,8 @@ async def start( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -1032,7 +1113,11 @@ async def start( path_template("/devices/{device_id}/apps/{package_name}", device_id=device_id, package_name=package_name), body=await async_maybe_transform({"activity": activity}, app_start_params.AppStartParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -1050,6 +1135,7 @@ async def stop( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Force-stops the app identified by the path package name. @@ -1067,6 +1153,8 @@ async def stop( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -1083,7 +1171,11 @@ async def stop( path_template("/devices/{device_id}/apps/{package_name}", device_id=device_id, package_name=package_name), body=await async_maybe_transform({"clear_data": clear_data}, app_stop_params.AppStopParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) diff --git a/src/mobilerun_sdk/resources/devices/browser.py b/src/mobilerun_sdk/resources/devices/browser.py index 42eca5bb..2c6db374 100644 --- a/src/mobilerun_sdk/resources/devices/browser.py +++ b/src/mobilerun_sdk/resources/devices/browser.py @@ -53,11 +53,16 @@ def execute_script( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> BrowserExecuteScriptResponse: """ - Evaluates a JavaScript expression in the device's foreground Chrome tab via the - Chrome DevTools Protocol and returns its JSON-serialized result. Devices without - browser support return an unsupported-feature error. + Evaluates a JavaScript expression exactly once in the device's single, confirmed + foreground Chrome tab via the Chrome DevTools Protocol and returns its + JSON-serialized result. A responsive browser state without exactly one visible + page returns DEVICE_NO_BROWSER_TARGET (400). Transient discovery or target-probe + transport failures return CDP_TRANSPORT_UNAVAILABLE (503) with Retry-After and + an executionOutcome; the service never retries a user script after sending it. + Devices without browser support return an unsupported-feature error. Args: script: JavaScript expression to evaluate in the device's foreground Chrome tab (CDP @@ -72,6 +77,8 @@ def execute_script( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -85,7 +92,11 @@ def execute_script( path_template("/devices/{device_id}/browser/execute-script", device_id=device_id), body=maybe_transform({"script": script}, browser_execute_script_params.BrowserExecuteScriptParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=BrowserExecuteScriptResponse, ) @@ -123,11 +134,16 @@ async def execute_script( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> BrowserExecuteScriptResponse: """ - Evaluates a JavaScript expression in the device's foreground Chrome tab via the - Chrome DevTools Protocol and returns its JSON-serialized result. Devices without - browser support return an unsupported-feature error. + Evaluates a JavaScript expression exactly once in the device's single, confirmed + foreground Chrome tab via the Chrome DevTools Protocol and returns its + JSON-serialized result. A responsive browser state without exactly one visible + page returns DEVICE_NO_BROWSER_TARGET (400). Transient discovery or target-probe + transport failures return CDP_TRANSPORT_UNAVAILABLE (503) with Retry-After and + an executionOutcome; the service never retries a user script after sending it. + Devices without browser support return an unsupported-feature error. Args: script: JavaScript expression to evaluate in the device's foreground Chrome tab (CDP @@ -142,6 +158,8 @@ async def execute_script( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -157,7 +175,11 @@ async def execute_script( {"script": script}, browser_execute_script_params.BrowserExecuteScriptParams ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=BrowserExecuteScriptResponse, ) diff --git a/src/mobilerun_sdk/resources/devices/clipboard.py b/src/mobilerun_sdk/resources/devices/clipboard.py index 7c641500..f3f1a041 100644 --- a/src/mobilerun_sdk/resources/devices/clipboard.py +++ b/src/mobilerun_sdk/resources/devices/clipboard.py @@ -95,6 +95,7 @@ def set( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Replaces the device's clipboard content with the text in the request body; an @@ -109,6 +110,8 @@ def set( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -123,7 +126,11 @@ def set( path_template("/devices/{device_id}/clipboard", device_id=device_id), body=maybe_transform({"text": text}, clipboard_set_params.ClipboardSetParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -203,6 +210,7 @@ async def set( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Replaces the device's clipboard content with the text in the request body; an @@ -217,6 +225,8 @@ async def set( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -231,7 +241,11 @@ async def set( path_template("/devices/{device_id}/clipboard", device_id=device_id), body=await async_maybe_transform({"text": text}, clipboard_set_params.ClipboardSetParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) diff --git a/src/mobilerun_sdk/resources/devices/deep_link.py b/src/mobilerun_sdk/resources/devices/deep_link.py index ceee3bb9..cc5cbd45 100644 --- a/src/mobilerun_sdk/resources/devices/deep_link.py +++ b/src/mobilerun_sdk/resources/devices/deep_link.py @@ -55,6 +55,7 @@ def execute_deep_link( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Opens a deep link on the device. @@ -80,6 +81,8 @@ def execute_deep_link( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -102,7 +105,11 @@ def execute_deep_link( deep_link_execute_deep_link_params.DeepLinkExecuteDeepLinkParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -143,6 +150,7 @@ async def execute_deep_link( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Opens a deep link on the device. @@ -168,6 +176,8 @@ async def execute_deep_link( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -190,7 +200,11 @@ async def execute_deep_link( deep_link_execute_deep_link_params.DeepLinkExecuteDeepLinkParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) diff --git a/src/mobilerun_sdk/resources/devices/devices.py b/src/mobilerun_sdk/resources/devices/devices.py index beb5138b..55ce66d1 100644 --- a/src/mobilerun_sdk/resources/devices/devices.py +++ b/src/mobilerun_sdk/resources/devices/devices.py @@ -2,6 +2,7 @@ from __future__ import annotations +import typing_extensions from typing import List, Union, Optional from datetime import datetime from typing_extensions import Literal @@ -300,14 +301,7 @@ def create( *, billing: Literal["auto", "subscription", "minute"] | Omit = omit, query_country: str | Omit = omit, - device_type: Literal[ - "android_cloud_phone", - "dedicated_premium_device", - "dedicated_physical_device", - "dedicated_ios_device", - "dedicated_emulated_device", - ] - | Omit = omit, + device_type: str | Omit = omit, profile_id: str | Omit = omit, android_version: int | Omit = omit, apps: Optional[SequenceNotStr[str]] | Omit = omit, @@ -326,28 +320,31 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> DeviceCreateResponse: - """ - Requests a new device for the authenticated user from the device spec in the - request body. Optional query parameters select the canonical device type, target - country, billing mode, and a profile to use as the base spec; deprecated - device-type aliases remain accepted only during the documented compatibility - grace period. The response returns the device and its stream token. + """Requests a new device from the specification in the request body. + + Optional query + parameters select the canonical device type, country, billing mode, and base + profile. Returns the device, its resolved billing strategy, and its stream + token. Args: - billing: Billing mode. 'auto' uses a subscription slot when available and otherwise bills - per minute; 'subscription' requires an available subscription slot; 'minute' - bills per minute. Only cloud phone and cloud emulator devices support per-minute - billing. + billing: Billing mode. 'auto' tries subscription first, then minute billing if no + subscription entitlement exists or all subscription slots are in use, provided + minute billing is enabled. When subscription billing is disabled, auto uses + minutes directly. Billing-service failures never trigger fallback. + 'subscription' requires an available subscription slot and never falls back. + 'minute' uses minute billing only, subject to balance and concurrency checks. + Modes depend on the device type's billing configuration. query_country: ISO 3166-1 alpha-2 country code. If omitted the system picks the country with the most availability. - device_type: - Deprecated device type aliases are accepted during a compatibility grace period: - dedicated_premium_device maps to android_cloud_phone, dedicated_physical_device - maps to android_physical_phone, dedicated_ios_device maps to ios_stealth_phone, - and dedicated_emulated_device maps to android_emulator. + device_type: Use android*cloud_phone for a cloud Android phone. Only canonical identifiers + are accepted. Other backends are deployment-specific; recognized but unavailable + types return DEVICE_TYPE_UNAVAILABLE (422). Retired dedicated*\\** aliases are + rejected with a canonical replacement. profile_id: Profile ID to use as device spec @@ -358,6 +355,8 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/devices", @@ -382,6 +381,7 @@ def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, + idempotency_key=idempotency_key, query=maybe_transform( { "billing": billing, @@ -460,11 +460,7 @@ def list( ] | Omit = omit, type: Literal[ - "android_cloud_phone", - "dedicated_premium_device", - "dedicated_physical_device", - "dedicated_ios_device", - "dedicated_emulated_device", + "android_cloud_phone", "android_physical_phone", "ios_stealth_phone", "android_emulator", "ios_simulator" ] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -483,11 +479,8 @@ def list( mine: When true, only return devices created by the calling user (resolved from X-User-ID, never a client-supplied id). - type: - Deprecated device type aliases are accepted during a compatibility grace period: - dedicated_premium_device maps to android_cloud_phone, dedicated_physical_device - maps to android_physical_phone, dedicated_ios_device maps to ios_stealth_phone, - and dedicated_emulated_device maps to android_emulator. + type: Canonical device type. Retired dedicated\\__\\** aliases are no longer accepted. + Availability depends on the deployment. extra_headers: Send extra headers @@ -524,6 +517,7 @@ def list( cast_to=DeviceListResponse, ) + @typing_extensions.deprecated("deprecated") def count( self, *, @@ -534,7 +528,12 @@ def count( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DeviceCountResponse: - """Returns the number of claimed devices for the user, broken down by device type.""" + """Deprecated: use GET /devices/summary instead. + + Returns the number of active + claimed devices for the user, broken down by device type, in the legacy response + shape. + """ return self._get( "/devices/count", options=make_request_options( @@ -595,6 +594,7 @@ def reboot( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Triggers a reboot of the device. @@ -609,6 +609,8 @@ def reboot( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -616,7 +618,11 @@ def reboot( return self._post( path_template("/devices/{device_id}/reboot", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -631,6 +637,7 @@ def reset( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Resets the device back to a clean state, clearing installed apps and user data @@ -645,6 +652,8 @@ def reset( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -652,7 +661,11 @@ def reset( return self._post( path_template("/devices/{device_id}/reset", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -667,6 +680,7 @@ def resume( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Wakes a parked device: backend readiness and any required capacity are @@ -681,6 +695,8 @@ def resume( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -688,7 +704,11 @@ def resume( return self._post( path_template("/devices/{device_id}/resume", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -742,6 +762,7 @@ def set_name( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> DeviceSetNameResponse: """ Sets the display name for a device from the name in the request body and returns @@ -755,6 +776,8 @@ def set_name( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -762,7 +785,11 @@ def set_name( path_template("/devices/{device_id}/name", device_id=device_id), body=maybe_transform({"name": name}, device_set_name_params.DeviceSetNameParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=DeviceSetNameResponse, ) @@ -777,6 +804,7 @@ def stop( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Parks the device: its data, apps and identity are kept, but nothing runs and @@ -791,6 +819,8 @@ def stop( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -798,7 +828,11 @@ def stop( return self._post( path_template("/devices/{device_id}/stop", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -815,6 +849,7 @@ def terminate( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Terminates the device and releases its resources. @@ -830,6 +865,8 @@ def terminate( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -844,7 +881,11 @@ def terminate( device_terminate_params.DeviceTerminateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -990,14 +1031,7 @@ async def create( *, billing: Literal["auto", "subscription", "minute"] | Omit = omit, query_country: str | Omit = omit, - device_type: Literal[ - "android_cloud_phone", - "dedicated_premium_device", - "dedicated_physical_device", - "dedicated_ios_device", - "dedicated_emulated_device", - ] - | Omit = omit, + device_type: str | Omit = omit, profile_id: str | Omit = omit, android_version: int | Omit = omit, apps: Optional[SequenceNotStr[str]] | Omit = omit, @@ -1016,28 +1050,31 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> DeviceCreateResponse: - """ - Requests a new device for the authenticated user from the device spec in the - request body. Optional query parameters select the canonical device type, target - country, billing mode, and a profile to use as the base spec; deprecated - device-type aliases remain accepted only during the documented compatibility - grace period. The response returns the device and its stream token. + """Requests a new device from the specification in the request body. + + Optional query + parameters select the canonical device type, country, billing mode, and base + profile. Returns the device, its resolved billing strategy, and its stream + token. Args: - billing: Billing mode. 'auto' uses a subscription slot when available and otherwise bills - per minute; 'subscription' requires an available subscription slot; 'minute' - bills per minute. Only cloud phone and cloud emulator devices support per-minute - billing. + billing: Billing mode. 'auto' tries subscription first, then minute billing if no + subscription entitlement exists or all subscription slots are in use, provided + minute billing is enabled. When subscription billing is disabled, auto uses + minutes directly. Billing-service failures never trigger fallback. + 'subscription' requires an available subscription slot and never falls back. + 'minute' uses minute billing only, subject to balance and concurrency checks. + Modes depend on the device type's billing configuration. query_country: ISO 3166-1 alpha-2 country code. If omitted the system picks the country with the most availability. - device_type: - Deprecated device type aliases are accepted during a compatibility grace period: - dedicated_premium_device maps to android_cloud_phone, dedicated_physical_device - maps to android_physical_phone, dedicated_ios_device maps to ios_stealth_phone, - and dedicated_emulated_device maps to android_emulator. + device_type: Use android*cloud_phone for a cloud Android phone. Only canonical identifiers + are accepted. Other backends are deployment-specific; recognized but unavailable + types return DEVICE_TYPE_UNAVAILABLE (422). Retired dedicated*\\** aliases are + rejected with a canonical replacement. profile_id: Profile ID to use as device spec @@ -1048,6 +1085,8 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/devices", @@ -1072,6 +1111,7 @@ async def create( extra_query=extra_query, extra_body=extra_body, timeout=timeout, + idempotency_key=idempotency_key, query=await async_maybe_transform( { "billing": billing, @@ -1150,11 +1190,7 @@ async def list( ] | Omit = omit, type: Literal[ - "android_cloud_phone", - "dedicated_premium_device", - "dedicated_physical_device", - "dedicated_ios_device", - "dedicated_emulated_device", + "android_cloud_phone", "android_physical_phone", "ios_stealth_phone", "android_emulator", "ios_simulator" ] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -1173,11 +1209,8 @@ async def list( mine: When true, only return devices created by the calling user (resolved from X-User-ID, never a client-supplied id). - type: - Deprecated device type aliases are accepted during a compatibility grace period: - dedicated_premium_device maps to android_cloud_phone, dedicated_physical_device - maps to android_physical_phone, dedicated_ios_device maps to ios_stealth_phone, - and dedicated_emulated_device maps to android_emulator. + type: Canonical device type. Retired dedicated\\__\\** aliases are no longer accepted. + Availability depends on the deployment. extra_headers: Send extra headers @@ -1214,6 +1247,7 @@ async def list( cast_to=DeviceListResponse, ) + @typing_extensions.deprecated("deprecated") async def count( self, *, @@ -1224,7 +1258,12 @@ async def count( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DeviceCountResponse: - """Returns the number of claimed devices for the user, broken down by device type.""" + """Deprecated: use GET /devices/summary instead. + + Returns the number of active + claimed devices for the user, broken down by device type, in the legacy response + shape. + """ return await self._get( "/devices/count", options=make_request_options( @@ -1285,6 +1324,7 @@ async def reboot( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Triggers a reboot of the device. @@ -1299,6 +1339,8 @@ async def reboot( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -1306,7 +1348,11 @@ async def reboot( return await self._post( path_template("/devices/{device_id}/reboot", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -1321,6 +1367,7 @@ async def reset( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Resets the device back to a clean state, clearing installed apps and user data @@ -1335,6 +1382,8 @@ async def reset( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -1342,7 +1391,11 @@ async def reset( return await self._post( path_template("/devices/{device_id}/reset", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -1357,6 +1410,7 @@ async def resume( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Wakes a parked device: backend readiness and any required capacity are @@ -1371,6 +1425,8 @@ async def resume( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -1378,7 +1434,11 @@ async def resume( return await self._post( path_template("/devices/{device_id}/resume", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -1432,6 +1492,7 @@ async def set_name( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> DeviceSetNameResponse: """ Sets the display name for a device from the name in the request body and returns @@ -1445,6 +1506,8 @@ async def set_name( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -1452,7 +1515,11 @@ async def set_name( path_template("/devices/{device_id}/name", device_id=device_id), body=await async_maybe_transform({"name": name}, device_set_name_params.DeviceSetNameParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=DeviceSetNameResponse, ) @@ -1467,6 +1534,7 @@ async def stop( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Parks the device: its data, apps and identity are kept, but nothing runs and @@ -1481,6 +1549,8 @@ async def stop( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -1488,7 +1558,11 @@ async def stop( return await self._post( path_template("/devices/{device_id}/stop", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -1505,6 +1579,7 @@ async def terminate( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Terminates the device and releases its resources. @@ -1520,6 +1595,8 @@ async def terminate( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -1534,7 +1611,11 @@ async def terminate( device_terminate_params.DeviceTerminateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -1588,8 +1669,10 @@ def __init__(self, devices: DevicesResource) -> None: self.list = to_raw_response_wrapper( devices.list, ) - self.count = to_raw_response_wrapper( - devices.count, + self.count = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + devices.count, # pyright: ignore[reportDeprecated], + ) ) self.fingerprint = to_raw_response_wrapper( devices.fingerprint, @@ -1713,8 +1796,10 @@ def __init__(self, devices: AsyncDevicesResource) -> None: self.list = async_to_raw_response_wrapper( devices.list, ) - self.count = async_to_raw_response_wrapper( - devices.count, + self.count = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + devices.count, # pyright: ignore[reportDeprecated], + ) ) self.fingerprint = async_to_raw_response_wrapper( devices.fingerprint, @@ -1838,8 +1923,10 @@ def __init__(self, devices: DevicesResource) -> None: self.list = to_streamed_response_wrapper( devices.list, ) - self.count = to_streamed_response_wrapper( - devices.count, + self.count = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + devices.count, # pyright: ignore[reportDeprecated], + ) ) self.fingerprint = to_streamed_response_wrapper( devices.fingerprint, @@ -1963,8 +2050,10 @@ def __init__(self, devices: AsyncDevicesResource) -> None: self.list = async_to_streamed_response_wrapper( devices.list, ) - self.count = async_to_streamed_response_wrapper( - devices.count, + self.count = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + devices.count, # pyright: ignore[reportDeprecated], + ) ) self.fingerprint = async_to_streamed_response_wrapper( devices.fingerprint, diff --git a/src/mobilerun_sdk/resources/devices/esim/apn.py b/src/mobilerun_sdk/resources/devices/esim/apn.py index 38703c1f..1ca493a8 100644 --- a/src/mobilerun_sdk/resources/devices/esim/apn.py +++ b/src/mobilerun_sdk/resources/devices/esim/apn.py @@ -97,6 +97,7 @@ def select( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Marks an existing APN, identified by apnId, as the preferred APN for the given @@ -110,6 +111,8 @@ def select( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -130,7 +133,11 @@ def select( apn_select_params.ApnSelectParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -154,6 +161,7 @@ def set( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Creates an access point name (APN) from the request body and applies it to the @@ -168,6 +176,8 @@ def set( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -194,7 +204,11 @@ def set( apn_set_params.ApnSetParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -274,6 +288,7 @@ async def select( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Marks an existing APN, identified by apnId, as the preferred APN for the given @@ -287,6 +302,8 @@ async def select( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -307,7 +324,11 @@ async def select( apn_select_params.ApnSelectParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -331,6 +352,7 @@ async def set( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Creates an access point name (APN) from the request body and applies it to the @@ -345,6 +367,8 @@ async def set( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -371,7 +395,11 @@ async def set( apn_set_params.ApnSetParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) diff --git a/src/mobilerun_sdk/resources/devices/esim/esim.py b/src/mobilerun_sdk/resources/devices/esim/esim.py index 924d895c..99a01d8f 100644 --- a/src/mobilerun_sdk/resources/devices/esim/esim.py +++ b/src/mobilerun_sdk/resources/devices/esim/esim.py @@ -112,6 +112,7 @@ def activate( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> EsimActivateResponse: """ Download profile and/or enable subscription. @@ -128,6 +129,8 @@ def activate( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -149,7 +152,11 @@ def activate( esim_activate_params.EsimActivateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=EsimActivateResponse, ) @@ -166,6 +173,7 @@ def enable( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Enables the eSIM subscription identified by the subId in the request body so it @@ -179,6 +187,8 @@ def enable( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -193,7 +203,11 @@ def enable( path_template("/devices/{device_id}/esim", device_id=device_id), body=maybe_transform({"sub_id": sub_id}, esim_enable_params.EsimEnableParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -210,6 +224,7 @@ def remove( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Deletes the eSIM subscription identified by the subId query parameter from the @@ -223,6 +238,8 @@ def remove( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -240,6 +257,7 @@ def remove( extra_query=extra_query, extra_body=extra_body, timeout=timeout, + idempotency_key=idempotency_key, query=maybe_transform({"sub_id": sub_id}, esim_remove_params.EsimRemoveParams), ), cast_to=NoneType, @@ -257,6 +275,7 @@ def set_roaming( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Enables or disables data roaming for the device's eSIM based on the enabled flag @@ -270,6 +289,8 @@ def set_roaming( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -284,7 +305,11 @@ def set_roaming( path_template("/devices/{device_id}/esim/roaming", device_id=device_id), body=maybe_transform({"enabled": enabled}, esim_set_roaming_params.EsimSetRoamingParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -409,6 +434,7 @@ async def activate( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> EsimActivateResponse: """ Download profile and/or enable subscription. @@ -425,6 +451,8 @@ async def activate( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -446,7 +474,11 @@ async def activate( esim_activate_params.EsimActivateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=EsimActivateResponse, ) @@ -463,6 +495,7 @@ async def enable( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Enables the eSIM subscription identified by the subId in the request body so it @@ -476,6 +509,8 @@ async def enable( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -490,7 +525,11 @@ async def enable( path_template("/devices/{device_id}/esim", device_id=device_id), body=await async_maybe_transform({"sub_id": sub_id}, esim_enable_params.EsimEnableParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -507,6 +546,7 @@ async def remove( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Deletes the eSIM subscription identified by the subId query parameter from the @@ -520,6 +560,8 @@ async def remove( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -537,6 +579,7 @@ async def remove( extra_query=extra_query, extra_body=extra_body, timeout=timeout, + idempotency_key=idempotency_key, query=await async_maybe_transform({"sub_id": sub_id}, esim_remove_params.EsimRemoveParams), ), cast_to=NoneType, @@ -554,6 +597,7 @@ async def set_roaming( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Enables or disables data roaming for the device's eSIM based on the enabled flag @@ -567,6 +611,8 @@ async def set_roaming( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -581,7 +627,11 @@ async def set_roaming( path_template("/devices/{device_id}/esim/roaming", device_id=device_id), body=await async_maybe_transform({"enabled": enabled}, esim_set_roaming_params.EsimSetRoamingParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) diff --git a/src/mobilerun_sdk/resources/devices/files.py b/src/mobilerun_sdk/resources/devices/files.py index d39f4a3d..3568090d 100644 --- a/src/mobilerun_sdk/resources/devices/files.py +++ b/src/mobilerun_sdk/resources/devices/files.py @@ -102,6 +102,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Deletes the file at the path given in the path query parameter from the device. @@ -114,6 +115,8 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -131,6 +134,7 @@ def delete( extra_query=extra_query, extra_body=extra_body, timeout=timeout, + idempotency_key=idempotency_key, query=maybe_transform({"path": path}, file_delete_params.FileDeleteParams), ), cast_to=NoneType, @@ -195,6 +199,7 @@ def upload( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Uploads a file to the device via multipart form data, writing it into the @@ -208,6 +213,8 @@ def upload( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -233,6 +240,7 @@ def upload( extra_query=extra_query, extra_body=extra_body, timeout=timeout, + idempotency_key=idempotency_key, query=maybe_transform({"path": path}, file_upload_params.FileUploadParams), ), cast_to=NoneType, @@ -317,6 +325,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Deletes the file at the path given in the path query parameter from the device. @@ -329,6 +338,8 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -346,6 +357,7 @@ async def delete( extra_query=extra_query, extra_body=extra_body, timeout=timeout, + idempotency_key=idempotency_key, query=await async_maybe_transform({"path": path}, file_delete_params.FileDeleteParams), ), cast_to=NoneType, @@ -410,6 +422,7 @@ async def upload( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Uploads a file to the device via multipart form data, writing it into the @@ -423,6 +436,8 @@ async def upload( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -448,6 +463,7 @@ async def upload( extra_query=extra_query, extra_body=extra_body, timeout=timeout, + idempotency_key=idempotency_key, query=await async_maybe_transform({"path": path}, file_upload_params.FileUploadParams), ), cast_to=NoneType, diff --git a/src/mobilerun_sdk/resources/devices/keyboard.py b/src/mobilerun_sdk/resources/devices/keyboard.py index dd5439ce..aaacee83 100644 --- a/src/mobilerun_sdk/resources/devices/keyboard.py +++ b/src/mobilerun_sdk/resources/devices/keyboard.py @@ -53,6 +53,7 @@ def clear( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Clears the contents of the currently focused text input field. @@ -65,6 +66,8 @@ def clear( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -78,7 +81,11 @@ def clear( return self._delete( path_template("/devices/{device_id}/keyboard", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -95,6 +102,7 @@ def key( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Sends a single Android key event to the device, identified by its key code. @@ -107,6 +115,8 @@ def key( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -121,7 +131,11 @@ def key( path_template("/devices/{device_id}/keyboard", device_id=device_id), body=maybe_transform({"key": key}, keyboard_key_params.KeyboardKeyParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -143,6 +157,7 @@ def write( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Types text into the focused input field. @@ -166,6 +181,8 @@ def write( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -190,7 +207,11 @@ def write( keyboard_write_params.KeyboardWriteParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -227,6 +248,7 @@ async def clear( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Clears the contents of the currently focused text input field. @@ -239,6 +261,8 @@ async def clear( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -252,7 +276,11 @@ async def clear( return await self._delete( path_template("/devices/{device_id}/keyboard", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -269,6 +297,7 @@ async def key( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Sends a single Android key event to the device, identified by its key code. @@ -281,6 +310,8 @@ async def key( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -295,7 +326,11 @@ async def key( path_template("/devices/{device_id}/keyboard", device_id=device_id), body=await async_maybe_transform({"key": key}, keyboard_key_params.KeyboardKeyParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -317,6 +352,7 @@ async def write( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Types text into the focused input field. @@ -340,6 +376,8 @@ async def write( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -364,7 +402,11 @@ async def write( keyboard_write_params.KeyboardWriteParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) diff --git a/src/mobilerun_sdk/resources/devices/kiosk.py b/src/mobilerun_sdk/resources/devices/kiosk.py index 8739ddca..ea95d93f 100644 --- a/src/mobilerun_sdk/resources/devices/kiosk.py +++ b/src/mobilerun_sdk/resources/devices/kiosk.py @@ -51,6 +51,7 @@ def disable( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Disables Android lock-task (kiosk) mode on the device, releasing it from the @@ -64,6 +65,8 @@ def disable( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -77,7 +80,11 @@ def disable( return self._delete( path_template("/devices/{device_id}/kiosk", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -94,6 +101,7 @@ def enable( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Locks the device to the package named in the request body using Android @@ -109,6 +117,8 @@ def enable( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -123,7 +133,11 @@ def enable( path_template("/devices/{device_id}/kiosk", device_id=device_id), body=maybe_transform({"package_name": package_name}, kiosk_enable_params.KioskEnableParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -160,6 +174,7 @@ async def disable( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Disables Android lock-task (kiosk) mode on the device, releasing it from the @@ -173,6 +188,8 @@ async def disable( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -186,7 +203,11 @@ async def disable( return await self._delete( path_template("/devices/{device_id}/kiosk", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -203,6 +224,7 @@ async def enable( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Locks the device to the package named in the request body using Android @@ -218,6 +240,8 @@ async def enable( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -232,7 +256,11 @@ async def enable( path_template("/devices/{device_id}/kiosk", device_id=device_id), body=await async_maybe_transform({"package_name": package_name}, kiosk_enable_params.KioskEnableParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) diff --git a/src/mobilerun_sdk/resources/devices/language.py b/src/mobilerun_sdk/resources/devices/language.py index 608f612a..5b49b5e4 100644 --- a/src/mobilerun_sdk/resources/devices/language.py +++ b/src/mobilerun_sdk/resources/devices/language.py @@ -94,6 +94,7 @@ def set( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Sets the device language/locale to the BCP-47 locale in the request body. @@ -115,6 +116,8 @@ def set( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -135,7 +138,11 @@ def set( language_set_params.LanguageSetParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -214,6 +221,7 @@ async def set( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Sets the device language/locale to the BCP-47 locale in the request body. @@ -235,6 +243,8 @@ async def set( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -255,7 +265,11 @@ async def set( language_set_params.LanguageSetParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) diff --git a/src/mobilerun_sdk/resources/devices/location.py b/src/mobilerun_sdk/resources/devices/location.py index c63dd1d7..3975a8d1 100644 --- a/src/mobilerun_sdk/resources/devices/location.py +++ b/src/mobilerun_sdk/resources/devices/location.py @@ -93,6 +93,7 @@ def reset( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Clears any simulated GPS location and restores the device's default location @@ -106,6 +107,8 @@ def reset( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -119,7 +122,11 @@ def reset( return self._delete( path_template("/devices/{device_id}/location", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -137,6 +144,7 @@ def set( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Sets the device's simulated GPS location to the latitude and longitude in the @@ -150,6 +158,8 @@ def set( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -170,7 +180,11 @@ def set( location_set_params.LocationSetParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -248,6 +262,7 @@ async def reset( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Clears any simulated GPS location and restores the device's default location @@ -261,6 +276,8 @@ async def reset( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -274,7 +291,11 @@ async def reset( return await self._delete( path_template("/devices/{device_id}/location", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -292,6 +313,7 @@ async def set( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Sets the device's simulated GPS location to the latitude and longitude in the @@ -305,6 +327,8 @@ async def set( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -325,7 +349,11 @@ async def set( location_set_params.LocationSetParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) diff --git a/src/mobilerun_sdk/resources/devices/media_sessions.py b/src/mobilerun_sdk/resources/devices/media_sessions.py index ab9161e2..6255b573 100644 --- a/src/mobilerun_sdk/resources/devices/media_sessions.py +++ b/src/mobilerun_sdk/resources/devices/media_sessions.py @@ -55,6 +55,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> MediaSessionCreateResponse: """ Allocates an exclusive relay path and returns one-time publish and control @@ -73,6 +74,8 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -86,7 +89,11 @@ def create( media_session_create_params.MediaSessionCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=MediaSessionCreateResponse, ) @@ -103,6 +110,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Immediately revokes relay authorization, detaches virtual media inputs, and @@ -116,6 +124,8 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -128,7 +138,11 @@ def delete( "/devices/{device_id}/media-sessions/{session_id}", device_id=device_id, session_id=session_id ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -145,6 +159,7 @@ def activate( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> MediaSessionActivateResponse: """ Validates relay codecs and attaches one private RTSP source to either the @@ -158,6 +173,8 @@ def activate( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -169,7 +186,11 @@ def activate( "/devices/{device_id}/media-sessions/{session_id}/activate", device_id=device_id, session_id=session_id ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=MediaSessionActivateResponse, ) @@ -242,6 +263,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> MediaSessionCreateResponse: """ Allocates an exclusive relay path and returns one-time publish and control @@ -260,6 +282,8 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -273,7 +297,11 @@ async def create( media_session_create_params.MediaSessionCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=MediaSessionCreateResponse, ) @@ -290,6 +318,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Immediately revokes relay authorization, detaches virtual media inputs, and @@ -303,6 +332,8 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -315,7 +346,11 @@ async def delete( "/devices/{device_id}/media-sessions/{session_id}", device_id=device_id, session_id=session_id ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -332,6 +367,7 @@ async def activate( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> MediaSessionActivateResponse: """ Validates relay codecs and attaches one private RTSP source to either the @@ -345,6 +381,8 @@ async def activate( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -356,7 +394,11 @@ async def activate( "/devices/{device_id}/media-sessions/{session_id}/activate", device_id=device_id, session_id=session_id ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=MediaSessionActivateResponse, ) diff --git a/src/mobilerun_sdk/resources/devices/profile.py b/src/mobilerun_sdk/resources/devices/profile.py index d48b0924..c2b5ad54 100644 --- a/src/mobilerun_sdk/resources/devices/profile.py +++ b/src/mobilerun_sdk/resources/devices/profile.py @@ -52,6 +52,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Apply a profile to a device @@ -66,6 +67,8 @@ def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -80,7 +83,11 @@ def update( path_template("/devices/{device_id}/profile", device_id=device_id), body=maybe_transform({"profile_id": profile_id}, profile_update_params.ProfileUpdateParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -118,6 +125,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Apply a profile to a device @@ -132,6 +140,8 @@ async def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -146,7 +156,11 @@ async def update( path_template("/devices/{device_id}/profile", device_id=device_id), body=await async_maybe_transform({"profile_id": profile_id}, profile_update_params.ProfileUpdateParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) diff --git a/src/mobilerun_sdk/resources/devices/proxy.py b/src/mobilerun_sdk/resources/devices/proxy.py index f3cc14b3..2b978aba 100644 --- a/src/mobilerun_sdk/resources/devices/proxy.py +++ b/src/mobilerun_sdk/resources/devices/proxy.py @@ -60,6 +60,7 @@ def connect( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Routes the device's traffic through a SOCKS5 proxy supplied in the request body, @@ -82,6 +83,8 @@ def connect( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -108,7 +111,11 @@ def connect( proxy_connect_params.ProxyConnectParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -124,6 +131,7 @@ def disconnect( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Disconnects the device's active proxy connection and clears its stored proxy @@ -137,6 +145,8 @@ def disconnect( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -150,7 +160,11 @@ def disconnect( return self._delete( path_template("/devices/{device_id}/proxy", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -236,6 +250,7 @@ async def connect( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Routes the device's traffic through a SOCKS5 proxy supplied in the request body, @@ -258,6 +273,8 @@ async def connect( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -284,7 +301,11 @@ async def connect( proxy_connect_params.ProxyConnectParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -300,6 +321,7 @@ async def disconnect( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Disconnects the device's active proxy connection and clears its stored proxy @@ -313,6 +335,8 @@ async def disconnect( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -326,7 +350,11 @@ async def disconnect( return await self._delete( path_template("/devices/{device_id}/proxy", device_id=device_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) diff --git a/src/mobilerun_sdk/resources/devices/recordings.py b/src/mobilerun_sdk/resources/devices/recordings.py index 1591a3b8..7d9b1e38 100644 --- a/src/mobilerun_sdk/resources/devices/recordings.py +++ b/src/mobilerun_sdk/resources/devices/recordings.py @@ -102,6 +102,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Delete a device recording @@ -114,6 +115,8 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -125,7 +128,11 @@ def delete( "/devices/{device_id}/recordings/{recording_id}", device_id=device_id, recording_id=recording_id ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -144,6 +151,7 @@ def start( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> RecordingStartResponse: """ Start a device recording @@ -153,9 +161,11 @@ def start( device's full quality. Honored by devices recording through the portal stream bridge. - types: Artifacts to capture: trajectory (input actions), video, and audio (captured + types: Artifacts to capture: trajectory (input actions; on portal stream-bridge devices + only when the handset announces trajectory capture), video, and audio (captured into the video artifact, so it requires video; honored by portal stream-bridge - recorders). Defaults to trajectory and video. + recorders). Defaults to trajectory and video, narrowed to what the device + produces. extra_headers: Send extra headers @@ -164,6 +174,8 @@ def start( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -179,7 +191,11 @@ def start( recording_start_params.RecordingStartParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=RecordingStartResponse, ) @@ -233,6 +249,7 @@ def stop( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> RecordingStopResponse: """ Stop a device recording @@ -245,6 +262,8 @@ def stop( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -255,7 +274,11 @@ def stop( "/devices/{device_id}/recordings/{recording_id}", device_id=device_id, recording_id=recording_id ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=RecordingStopResponse, ) @@ -417,6 +440,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """ Delete a device recording @@ -429,6 +453,8 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -440,7 +466,11 @@ async def delete( "/devices/{device_id}/recordings/{recording_id}", device_id=device_id, recording_id=recording_id ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -459,6 +489,7 @@ async def start( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> RecordingStartResponse: """ Start a device recording @@ -468,9 +499,11 @@ async def start( device's full quality. Honored by devices recording through the portal stream bridge. - types: Artifacts to capture: trajectory (input actions), video, and audio (captured + types: Artifacts to capture: trajectory (input actions; on portal stream-bridge devices + only when the handset announces trajectory capture), video, and audio (captured into the video artifact, so it requires video; honored by portal stream-bridge - recorders). Defaults to trajectory and video. + recorders). Defaults to trajectory and video, narrowed to what the device + produces. extra_headers: Send extra headers @@ -479,6 +512,8 @@ async def start( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -494,7 +529,11 @@ async def start( recording_start_params.RecordingStartParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=RecordingStartResponse, ) @@ -548,6 +587,7 @@ async def stop( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> RecordingStopResponse: """ Stop a device recording @@ -560,6 +600,8 @@ async def stop( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -570,7 +612,11 @@ async def stop( "/devices/{device_id}/recordings/{recording_id}", device_id=device_id, recording_id=recording_id ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=RecordingStopResponse, ) diff --git a/src/mobilerun_sdk/resources/devices/timezone.py b/src/mobilerun_sdk/resources/devices/timezone.py index 0ac8240b..1e79eeb2 100644 --- a/src/mobilerun_sdk/resources/devices/timezone.py +++ b/src/mobilerun_sdk/resources/devices/timezone.py @@ -95,6 +95,7 @@ def set( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Sets the device timezone to the identifier in the request body. @@ -109,6 +110,8 @@ def set( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -123,7 +126,11 @@ def set( path_template("/devices/{device_id}/timezone", device_id=device_id), body=maybe_transform({"timezone": timezone}, timezone_set_params.TimezoneSetParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -203,6 +210,7 @@ async def set( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Sets the device timezone to the identifier in the request body. @@ -217,6 +225,8 @@ async def set( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -231,7 +241,11 @@ async def set( path_template("/devices/{device_id}/timezone", device_id=device_id), body=await async_maybe_transform({"timezone": timezone}, timezone_set_params.TimezoneSetParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) diff --git a/src/mobilerun_sdk/resources/devices/traffic_sessions.py b/src/mobilerun_sdk/resources/devices/traffic_sessions.py index 3a23caaf..866aa93c 100644 --- a/src/mobilerun_sdk/resources/devices/traffic_sessions.py +++ b/src/mobilerun_sdk/resources/devices/traffic_sessions.py @@ -48,7 +48,6 @@ def create( self, device_id: str, *, - idempotency_key: str, expires_in_seconds: int | Omit = omit, max_body_bytes: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -57,6 +56,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TrafficSessionCreateResponse: """ Starts one live-only decoded HTTP/1.1, HTTP/2, HTTP/3 and WebSocket traffic @@ -70,10 +70,11 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") - extra_headers = {"Idempotency-Key": idempotency_key, **(extra_headers or {})} return self._post( path_template("/devices/{device_id}/traffic/sessions", device_id=device_id), body=maybe_transform( @@ -84,7 +85,11 @@ def create( traffic_session_create_params.TrafficSessionCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TrafficSessionCreateResponse, ) @@ -183,6 +188,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TrafficSessionDeleteResponse: """ Stop device traffic inspection @@ -195,6 +201,8 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -205,7 +213,11 @@ def delete( "/devices/{device_id}/traffic/sessions/{session_id}", device_id=device_id, session_id=session_id ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TrafficSessionDeleteResponse, ) @@ -235,7 +247,6 @@ async def create( self, device_id: str, *, - idempotency_key: str, expires_in_seconds: int | Omit = omit, max_body_bytes: int | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -244,6 +255,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TrafficSessionCreateResponse: """ Starts one live-only decoded HTTP/1.1, HTTP/2, HTTP/3 and WebSocket traffic @@ -257,10 +269,11 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") - extra_headers = {"Idempotency-Key": idempotency_key, **(extra_headers or {})} return await self._post( path_template("/devices/{device_id}/traffic/sessions", device_id=device_id), body=await async_maybe_transform( @@ -271,7 +284,11 @@ async def create( traffic_session_create_params.TrafficSessionCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TrafficSessionCreateResponse, ) @@ -370,6 +387,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TrafficSessionDeleteResponse: """ Stop device traffic inspection @@ -382,6 +400,8 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not device_id: raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") @@ -392,7 +412,11 @@ async def delete( "/devices/{device_id}/traffic/sessions/{session_id}", device_id=device_id, session_id=session_id ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TrafficSessionDeleteResponse, ) diff --git a/src/mobilerun_sdk/resources/files.py b/src/mobilerun_sdk/resources/files.py index 739ba6f8..93d9b9b4 100644 --- a/src/mobilerun_sdk/resources/files.py +++ b/src/mobilerun_sdk/resources/files.py @@ -9,7 +9,7 @@ from ..types import file_list_params, file_update_params, file_upload_url_params from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given -from .._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform +from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -61,6 +61,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FileUpdateResponse: """Partial update of `displayName` and/or `enabled`. @@ -75,6 +76,8 @@ def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not file_id: raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}") @@ -88,7 +91,11 @@ def update( file_update_params.FileUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FileUpdateResponse, ) @@ -138,6 +145,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FileDeleteResponse: """ Hard-delete a file @@ -150,13 +158,19 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not file_id: raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}") return self._delete( path_template("/agents/files/{file_id}", file_id=file_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FileDeleteResponse, ) @@ -171,6 +185,7 @@ def cancel_pending( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FileCancelPendingResponse: """Soft-cancels an in-flight upload before confirm. @@ -186,13 +201,19 @@ def cancel_pending( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not file_id: raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}") return self._delete( path_template("/agents/files/{file_id}/pending", file_id=file_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FileCancelPendingResponse, ) @@ -207,6 +228,7 @@ def confirm( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FileConfirmResponse: """ Confirm a file upload by server-side HEAD validation @@ -219,13 +241,19 @@ def confirm( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not file_id: raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}") return self._post( path_template("/agents/files/{file_id}/confirm", file_id=file_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FileConfirmResponse, ) @@ -273,13 +301,13 @@ def upload_url( mime_type: str, size_bytes: int, zone: Literal["user", "skills"] | Omit = omit, - idempotency_key: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FileUploadURLResponse: """ Mint a presigned PUT URL for a user file upload @@ -292,8 +320,9 @@ def upload_url( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ - extra_headers = {**strip_not_given({"Idempotency-Key": idempotency_key}), **(extra_headers or {})} return self._post( "/agents/files/upload-url", body=maybe_transform( @@ -306,7 +335,11 @@ def upload_url( file_upload_url_params.FileUploadURLParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FileUploadURLResponse, ) @@ -344,6 +377,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FileUpdateResponse: """Partial update of `displayName` and/or `enabled`. @@ -358,6 +392,8 @@ async def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not file_id: raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}") @@ -371,7 +407,11 @@ async def update( file_update_params.FileUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FileUpdateResponse, ) @@ -421,6 +461,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FileDeleteResponse: """ Hard-delete a file @@ -433,13 +474,19 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not file_id: raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}") return await self._delete( path_template("/agents/files/{file_id}", file_id=file_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FileDeleteResponse, ) @@ -454,6 +501,7 @@ async def cancel_pending( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FileCancelPendingResponse: """Soft-cancels an in-flight upload before confirm. @@ -469,13 +517,19 @@ async def cancel_pending( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not file_id: raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}") return await self._delete( path_template("/agents/files/{file_id}/pending", file_id=file_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FileCancelPendingResponse, ) @@ -490,6 +544,7 @@ async def confirm( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FileConfirmResponse: """ Confirm a file upload by server-side HEAD validation @@ -502,13 +557,19 @@ async def confirm( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not file_id: raise ValueError(f"Expected a non-empty value for `file_id` but received {file_id!r}") return await self._post( path_template("/agents/files/{file_id}/confirm", file_id=file_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FileConfirmResponse, ) @@ -556,13 +617,13 @@ async def upload_url( mime_type: str, size_bytes: int, zone: Literal["user", "skills"] | Omit = omit, - idempotency_key: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FileUploadURLResponse: """ Mint a presigned PUT URL for a user file upload @@ -575,8 +636,9 @@ async def upload_url( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ - extra_headers = {**strip_not_given({"Idempotency-Key": idempotency_key}), **(extra_headers or {})} return await self._post( "/agents/files/upload-url", body=await async_maybe_transform( @@ -589,7 +651,11 @@ async def upload_url( file_upload_url_params.FileUploadURLParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FileUploadURLResponse, ) diff --git a/src/mobilerun_sdk/resources/mailboxes/mailboxes.py b/src/mobilerun_sdk/resources/mailboxes/mailboxes.py index 50e03570..8396f603 100644 --- a/src/mobilerun_sdk/resources/mailboxes/mailboxes.py +++ b/src/mobilerun_sdk/resources/mailboxes/mailboxes.py @@ -74,7 +74,6 @@ def with_streaming_response(self) -> MailboxesResourceWithStreamingResponse: def create( self, *, - client_request_id: str, billing_preference: Literal["included", "included_only", "rent"] | Omit = omit, domain_id: str | Omit = omit, label: str | Omit = omit, @@ -85,6 +84,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> MailboxCreateResponse: """Creates a mailbox on the default domain or a connected custom domain. @@ -110,12 +110,13 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/mailboxes", body=maybe_transform( { - "client_request_id": client_request_id, "billing_preference": billing_preference, "domain_id": domain_id, "label": label, @@ -124,7 +125,11 @@ def create( mailbox_create_params.MailboxCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=MailboxCreateResponse, ) @@ -173,6 +178,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> MailboxUpdateResponse: """ Updates the label of a mailbox. @@ -185,6 +191,8 @@ def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not mailbox_id: raise ValueError(f"Expected a non-empty value for `mailbox_id` but received {mailbox_id!r}") @@ -192,7 +200,11 @@ def update( path_template("/mailboxes/{mailbox_id}", mailbox_id=mailbox_id), body=maybe_transform({"label": label}, mailbox_update_params.MailboxUpdateParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=MailboxUpdateResponse, ) @@ -249,10 +261,12 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> MailboxDeleteResponse: """ Cancels a pending mailbox or schedules an active paid mailbox for cancellation. - Existing addresses and messages are retained. Repeating the request is safe. + Existing addresses and messages are retained. Repeating the request is safe. An + external inbox (Gmail) cannot be cancelled here; disconnect the link instead. Args: extra_headers: Send extra headers @@ -262,13 +276,19 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not mailbox_id: raise ValueError(f"Expected a non-empty value for `mailbox_id` but received {mailbox_id!r}") return self._delete( path_template("/mailboxes/{mailbox_id}", mailbox_id=mailbox_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=MailboxDeleteResponse, ) @@ -354,6 +374,7 @@ def restart( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> MailboxRestartResponse: """Restarts an archived mailbox with the same address. @@ -372,6 +393,8 @@ def restart( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not mailbox_id: raise ValueError(f"Expected a non-empty value for `mailbox_id` but received {mailbox_id!r}") @@ -381,7 +404,11 @@ def restart( {"billing_preference": billing_preference}, mailbox_restart_params.MailboxRestartParams ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=MailboxRestartResponse, ) @@ -396,6 +423,7 @@ def uncancel( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> MailboxUncancelResponse: """Withdraws a scheduled cancellation. @@ -410,13 +438,19 @@ def uncancel( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not mailbox_id: raise ValueError(f"Expected a non-empty value for `mailbox_id` but received {mailbox_id!r}") return self._post( path_template("/mailboxes/{mailbox_id}/uncancel", mailbox_id=mailbox_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=MailboxUncancelResponse, ) @@ -449,7 +483,6 @@ def with_streaming_response(self) -> AsyncMailboxesResourceWithStreamingResponse async def create( self, *, - client_request_id: str, billing_preference: Literal["included", "included_only", "rent"] | Omit = omit, domain_id: str | Omit = omit, label: str | Omit = omit, @@ -460,6 +493,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> MailboxCreateResponse: """Creates a mailbox on the default domain or a connected custom domain. @@ -485,12 +519,13 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/mailboxes", body=await async_maybe_transform( { - "client_request_id": client_request_id, "billing_preference": billing_preference, "domain_id": domain_id, "label": label, @@ -499,7 +534,11 @@ async def create( mailbox_create_params.MailboxCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=MailboxCreateResponse, ) @@ -548,6 +587,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> MailboxUpdateResponse: """ Updates the label of a mailbox. @@ -560,6 +600,8 @@ async def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not mailbox_id: raise ValueError(f"Expected a non-empty value for `mailbox_id` but received {mailbox_id!r}") @@ -567,7 +609,11 @@ async def update( path_template("/mailboxes/{mailbox_id}", mailbox_id=mailbox_id), body=await async_maybe_transform({"label": label}, mailbox_update_params.MailboxUpdateParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=MailboxUpdateResponse, ) @@ -624,10 +670,12 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> MailboxDeleteResponse: """ Cancels a pending mailbox or schedules an active paid mailbox for cancellation. - Existing addresses and messages are retained. Repeating the request is safe. + Existing addresses and messages are retained. Repeating the request is safe. An + external inbox (Gmail) cannot be cancelled here; disconnect the link instead. Args: extra_headers: Send extra headers @@ -637,13 +685,19 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not mailbox_id: raise ValueError(f"Expected a non-empty value for `mailbox_id` but received {mailbox_id!r}") return await self._delete( path_template("/mailboxes/{mailbox_id}", mailbox_id=mailbox_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=MailboxDeleteResponse, ) @@ -729,6 +783,7 @@ async def restart( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> MailboxRestartResponse: """Restarts an archived mailbox with the same address. @@ -747,6 +802,8 @@ async def restart( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not mailbox_id: raise ValueError(f"Expected a non-empty value for `mailbox_id` but received {mailbox_id!r}") @@ -756,7 +813,11 @@ async def restart( {"billing_preference": billing_preference}, mailbox_restart_params.MailboxRestartParams ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=MailboxRestartResponse, ) @@ -771,6 +832,7 @@ async def uncancel( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> MailboxUncancelResponse: """Withdraws a scheduled cancellation. @@ -785,13 +847,19 @@ async def uncancel( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not mailbox_id: raise ValueError(f"Expected a non-empty value for `mailbox_id` but received {mailbox_id!r}") return await self._post( path_template("/mailboxes/{mailbox_id}/uncancel", mailbox_id=mailbox_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=MailboxUncancelResponse, ) diff --git a/src/mobilerun_sdk/resources/messages/conversations.py b/src/mobilerun_sdk/resources/messages/conversations.py index 397a5a3e..50d032e8 100644 --- a/src/mobilerun_sdk/resources/messages/conversations.py +++ b/src/mobilerun_sdk/resources/messages/conversations.py @@ -107,6 +107,7 @@ def mark_read( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationMarkReadResponse: """ Marks inbound messages in a conversation as read through the supplied cursor. @@ -125,6 +126,8 @@ def mark_read( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/numbers/messages/conversations/read", @@ -137,7 +140,11 @@ def mark_read( conversation_mark_read_params.ConversationMarkReadParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationMarkReadResponse, ) @@ -225,6 +232,7 @@ async def mark_read( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ConversationMarkReadResponse: """ Marks inbound messages in a conversation as read through the supplied cursor. @@ -243,6 +251,8 @@ async def mark_read( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/numbers/messages/conversations/read", @@ -255,7 +265,11 @@ async def mark_read( conversation_mark_read_params.ConversationMarkReadParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ConversationMarkReadResponse, ) diff --git a/src/mobilerun_sdk/resources/notifications.py b/src/mobilerun_sdk/resources/notifications.py index 80c615c8..f0edfdf3 100644 --- a/src/mobilerun_sdk/resources/notifications.py +++ b/src/mobilerun_sdk/resources/notifications.py @@ -100,6 +100,7 @@ def update_preferences( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> NotificationUpdatePreferencesResponse: """Replaces your set of muted event types with the supplied list. @@ -115,6 +116,8 @@ def update_preferences( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._patch( "/notifications/preferences", @@ -122,7 +125,11 @@ def update_preferences( {"muted_types": muted_types}, notification_update_preferences_params.NotificationUpdatePreferencesParams ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NotificationUpdatePreferencesResponse, ) @@ -205,6 +212,7 @@ async def update_preferences( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> NotificationUpdatePreferencesResponse: """Replaces your set of muted event types with the supplied list. @@ -220,6 +228,8 @@ async def update_preferences( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._patch( "/notifications/preferences", @@ -227,7 +237,11 @@ async def update_preferences( {"muted_types": muted_types}, notification_update_preferences_params.NotificationUpdatePreferencesParams ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NotificationUpdatePreferencesResponse, ) diff --git a/src/mobilerun_sdk/resources/numbers/numbers.py b/src/mobilerun_sdk/resources/numbers/numbers.py index 76972e69..b0e9e904 100644 --- a/src/mobilerun_sdk/resources/numbers/numbers.py +++ b/src/mobilerun_sdk/resources/numbers/numbers.py @@ -9,7 +9,7 @@ from ...types import number_list_params, number_create_params, number_update_params, number_capacity_params from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform +from ..._utils import path_template, maybe_transform, async_maybe_transform from .messages import ( MessagesResource, AsyncMessagesResource, @@ -70,13 +70,13 @@ def create( country: str | Omit = omit, label: Optional[str] | Omit = omit, purpose: str | Omit = omit, - idempotency_key: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> NumberCreateResponse: """Starts a phone-number purchase. @@ -96,8 +96,6 @@ def create( purpose: Optional purpose from GET /numbers/phones/purposes. - idempotency_key: Optional request idempotency key. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -105,8 +103,9 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ - extra_headers = {**strip_not_given({"Idempotency-Key": idempotency_key}), **(extra_headers or {})} return self._post( "/numbers/phones", body=maybe_transform( @@ -119,7 +118,11 @@ def create( number_create_params.NumberCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NumberCreateResponse, ) @@ -168,6 +171,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> NumberUpdateResponse: """Updates the display label. @@ -186,6 +190,8 @@ def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") @@ -193,7 +199,11 @@ def update( path_template("/numbers/phones/{id}", id=id), body=maybe_transform({"label": label}, number_update_params.NumberUpdateParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NumberUpdateResponse, ) @@ -250,6 +260,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> NumberDeleteResponse: """ Cancels a pending purchase or schedules cancellation of an active paid phone @@ -264,13 +275,19 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._delete( path_template("/numbers/phones/{id}", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NumberDeleteResponse, ) @@ -384,13 +401,13 @@ async def create( country: str | Omit = omit, label: Optional[str] | Omit = omit, purpose: str | Omit = omit, - idempotency_key: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> NumberCreateResponse: """Starts a phone-number purchase. @@ -410,8 +427,6 @@ async def create( purpose: Optional purpose from GET /numbers/phones/purposes. - idempotency_key: Optional request idempotency key. - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -419,8 +434,9 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ - extra_headers = {**strip_not_given({"Idempotency-Key": idempotency_key}), **(extra_headers or {})} return await self._post( "/numbers/phones", body=await async_maybe_transform( @@ -433,7 +449,11 @@ async def create( number_create_params.NumberCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NumberCreateResponse, ) @@ -482,6 +502,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> NumberUpdateResponse: """Updates the display label. @@ -500,6 +521,8 @@ async def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") @@ -507,7 +530,11 @@ async def update( path_template("/numbers/phones/{id}", id=id), body=await async_maybe_transform({"label": label}, number_update_params.NumberUpdateParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NumberUpdateResponse, ) @@ -564,6 +591,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> NumberDeleteResponse: """ Cancels a pending purchase or schedules cancellation of an active paid phone @@ -578,13 +606,19 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._delete( path_template("/numbers/phones/{id}", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NumberDeleteResponse, ) diff --git a/src/mobilerun_sdk/resources/profiles.py b/src/mobilerun_sdk/resources/profiles.py index 00eb2114..f36e0758 100644 --- a/src/mobilerun_sdk/resources/profiles.py +++ b/src/mobilerun_sdk/resources/profiles.py @@ -59,6 +59,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProfileCreateResponse: """ Create a new device profile @@ -75,6 +76,8 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/profiles", @@ -86,7 +89,11 @@ def create( profile_create_params.ProfileCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProfileCreateResponse, ) @@ -136,6 +143,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProfileUpdateResponse: """ Update a device profile @@ -152,6 +160,8 @@ def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not profile_id: raise ValueError(f"Expected a non-empty value for `profile_id` but received {profile_id!r}") @@ -165,7 +175,11 @@ def update( profile_update_params.ProfileUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProfileUpdateResponse, ) @@ -233,6 +247,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProfileDeleteResponse: """ Delete a device profile @@ -245,13 +260,19 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not profile_id: raise ValueError(f"Expected a non-empty value for `profile_id` but received {profile_id!r}") return self._delete( path_template("/profiles/{profile_id}", profile_id=profile_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProfileDeleteResponse, ) @@ -288,6 +309,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProfileCreateResponse: """ Create a new device profile @@ -304,6 +326,8 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/profiles", @@ -315,7 +339,11 @@ async def create( profile_create_params.ProfileCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProfileCreateResponse, ) @@ -365,6 +393,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProfileUpdateResponse: """ Update a device profile @@ -381,6 +410,8 @@ async def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not profile_id: raise ValueError(f"Expected a non-empty value for `profile_id` but received {profile_id!r}") @@ -394,7 +425,11 @@ async def update( profile_update_params.ProfileUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProfileUpdateResponse, ) @@ -462,6 +497,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProfileDeleteResponse: """ Delete a device profile @@ -474,13 +510,19 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not profile_id: raise ValueError(f"Expected a non-empty value for `profile_id` but received {profile_id!r}") return await self._delete( path_template("/profiles/{profile_id}", profile_id=profile_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProfileDeleteResponse, ) diff --git a/src/mobilerun_sdk/resources/proxies.py b/src/mobilerun_sdk/resources/proxies.py index 45a990d5..9a5b7f3e 100644 --- a/src/mobilerun_sdk/resources/proxies.py +++ b/src/mobilerun_sdk/resources/proxies.py @@ -64,6 +64,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyCreateResponse: """Creates a proxy config. @@ -80,6 +81,8 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ ... @@ -96,6 +99,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyCreateResponse: """Creates a proxy config. @@ -112,6 +116,8 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ ... @@ -132,6 +138,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyCreateResponse: return self._post( "/proxies", @@ -148,7 +155,11 @@ def create( proxy_create_params.ProxyCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProxyCreateResponse, ) @@ -206,6 +217,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyUpdateResponse: """Replaces the proxy config identified by `proxyId` with the provided body. @@ -221,6 +233,8 @@ def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ ... @@ -238,6 +252,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyUpdateResponse: """Replaces the proxy config identified by `proxyId` with the provided body. @@ -253,6 +268,8 @@ def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ ... @@ -274,6 +291,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyUpdateResponse: if not proxy_id: raise ValueError(f"Expected a non-empty value for `proxy_id` but received {proxy_id!r}") @@ -292,7 +310,11 @@ def update( proxy_update_params.ProxyUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProxyUpdateResponse, ) @@ -344,6 +366,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyDeleteResponse: """ Permanently deletes the proxy config identified by `proxyId` and returns the @@ -357,13 +380,19 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not proxy_id: raise ValueError(f"Expected a non-empty value for `proxy_id` but received {proxy_id!r}") return self._delete( path_template("/proxies/{proxy_id}", proxy_id=proxy_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProxyDeleteResponse, ) @@ -378,6 +407,7 @@ def lookup( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyLookupResponse: """ Lookup proxy location @@ -392,12 +422,18 @@ def lookup( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/proxies/lookup", body=maybe_transform({"socks5": socks5}, proxy_lookup_params.ProxyLookupParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProxyLookupResponse, ) @@ -439,6 +475,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyCreateResponse: """Creates a proxy config. @@ -455,6 +492,8 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ ... @@ -471,6 +510,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyCreateResponse: """Creates a proxy config. @@ -487,6 +527,8 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ ... @@ -507,6 +549,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyCreateResponse: return await self._post( "/proxies", @@ -523,7 +566,11 @@ async def create( proxy_create_params.ProxyCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProxyCreateResponse, ) @@ -581,6 +628,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyUpdateResponse: """Replaces the proxy config identified by `proxyId` with the provided body. @@ -596,6 +644,8 @@ async def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ ... @@ -613,6 +663,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyUpdateResponse: """Replaces the proxy config identified by `proxyId` with the provided body. @@ -628,6 +679,8 @@ async def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ ... @@ -649,6 +702,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyUpdateResponse: if not proxy_id: raise ValueError(f"Expected a non-empty value for `proxy_id` but received {proxy_id!r}") @@ -667,7 +721,11 @@ async def update( proxy_update_params.ProxyUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProxyUpdateResponse, ) @@ -719,6 +777,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyDeleteResponse: """ Permanently deletes the proxy config identified by `proxyId` and returns the @@ -732,13 +791,19 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not proxy_id: raise ValueError(f"Expected a non-empty value for `proxy_id` but received {proxy_id!r}") return await self._delete( path_template("/proxies/{proxy_id}", proxy_id=proxy_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProxyDeleteResponse, ) @@ -753,6 +818,7 @@ async def lookup( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ProxyLookupResponse: """ Lookup proxy location @@ -767,12 +833,18 @@ async def lookup( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/proxies/lookup", body=await async_maybe_transform({"socks5": socks5}, proxy_lookup_params.ProxyLookupParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ProxyLookupResponse, ) diff --git a/src/mobilerun_sdk/resources/store/apps.py b/src/mobilerun_sdk/resources/store/apps.py index 8dc41c15..fcfb3198 100644 --- a/src/mobilerun_sdk/resources/store/apps.py +++ b/src/mobilerun_sdk/resources/store/apps.py @@ -134,6 +134,7 @@ def add_to_workspace( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> AppAddToWorkspaceResponse: """ Installs a published store app into the caller's workspace — the existing @@ -147,13 +148,19 @@ def add_to_workspace( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not app_id: raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}") return self._post( path_template("/store/apps/{app_id}/add", app_id=app_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=AppAddToWorkspaceResponse, ) @@ -270,6 +277,7 @@ async def add_to_workspace( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> AppAddToWorkspaceResponse: """ Installs a published store app into the caller's workspace — the existing @@ -283,13 +291,19 @@ async def add_to_workspace( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not app_id: raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}") return await self._post( path_template("/store/apps/{app_id}/add", app_id=app_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=AppAddToWorkspaceResponse, ) diff --git a/src/mobilerun_sdk/resources/tasks/tasks.py b/src/mobilerun_sdk/resources/tasks/tasks.py index c6656997..c93af9c6 100644 --- a/src/mobilerun_sdk/resources/tasks/tasks.py +++ b/src/mobilerun_sdk/resources/tasks/tasks.py @@ -9,7 +9,7 @@ from ...types import task_run_params, task_list_params, task_run_streamed_params, task_send_message_params from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given -from ..._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform +from ..._utils import path_template, maybe_transform, async_maybe_transform from ..._compat import cached_property from .ui_states import ( UiStatesResource, @@ -301,13 +301,13 @@ def run( temperature: float | Omit = omit, vision: bool | Omit = omit, vpn_country: Optional[Literal["US", "BR", "FR", "DE", "IN", "JP", "KR", "ZA"]] | Omit = omit, - idempotency_key: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TaskRunResponse: """Create and dispatch a new agent task. @@ -321,7 +321,7 @@ def run( execution_timeout: Maximum agent execution time in seconds (1–2700). - llm_model: The LLM model identifier to use for the task (e.g. 'openai/gpt-5.6-luna') + llm_model: The LLM model identifier to use for the task (e.g. 'openai/gpt-6-luna') recording_enabled: Record device video for the whole task and persist a retrievable reference @@ -339,8 +339,9 @@ def run( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ - extra_headers = {**strip_not_given({"Idempotency-Key": idempotency_key}), **(extra_headers or {})} return self._post( "/tasks", body=maybe_transform( @@ -369,7 +370,11 @@ def run( task_run_params.TaskRunParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TaskRunResponse, ) @@ -403,6 +408,7 @@ def run_streamed( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> object: """ Create and dispatch a new agent task, returning an SSE stream of task events. @@ -415,7 +421,7 @@ def run_streamed( execution_timeout: Maximum agent execution time in seconds (1–2700). - llm_model: The LLM model identifier to use for the task (e.g. 'openai/gpt-5.6-luna') + llm_model: The LLM model identifier to use for the task (e.g. 'openai/gpt-6-luna') recording_enabled: Record device video for the whole task and persist a retrievable reference @@ -433,6 +439,8 @@ def run_streamed( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/tasks/stream", @@ -462,7 +470,11 @@ def run_streamed( task_run_streamed_params.TaskRunStreamedParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=object, ) @@ -478,6 +490,7 @@ def send_message( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TaskSendMessageResponse: """Send a message to a running agent task. @@ -494,6 +507,8 @@ def send_message( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not task_id: raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}") @@ -501,7 +516,11 @@ def send_message( path_template("/tasks/{task_id}/message", task_id=task_id), body=maybe_transform({"message": message}, task_send_message_params.TaskSendMessageParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TaskSendMessageResponse, ) @@ -516,6 +535,7 @@ def stop( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TaskStopResponse: """Cancel a running task. @@ -530,13 +550,19 @@ def stop( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not task_id: raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}") return self._post( path_template("/tasks/{task_id}/cancel", task_id=task_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TaskStopResponse, ) @@ -797,13 +823,13 @@ async def run( temperature: float | Omit = omit, vision: bool | Omit = omit, vpn_country: Optional[Literal["US", "BR", "FR", "DE", "IN", "JP", "KR", "ZA"]] | Omit = omit, - idempotency_key: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TaskRunResponse: """Create and dispatch a new agent task. @@ -817,7 +843,7 @@ async def run( execution_timeout: Maximum agent execution time in seconds (1–2700). - llm_model: The LLM model identifier to use for the task (e.g. 'openai/gpt-5.6-luna') + llm_model: The LLM model identifier to use for the task (e.g. 'openai/gpt-6-luna') recording_enabled: Record device video for the whole task and persist a retrievable reference @@ -835,8 +861,9 @@ async def run( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ - extra_headers = {**strip_not_given({"Idempotency-Key": idempotency_key}), **(extra_headers or {})} return await self._post( "/tasks", body=await async_maybe_transform( @@ -865,7 +892,11 @@ async def run( task_run_params.TaskRunParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TaskRunResponse, ) @@ -899,6 +930,7 @@ async def run_streamed( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> object: """ Create and dispatch a new agent task, returning an SSE stream of task events. @@ -911,7 +943,7 @@ async def run_streamed( execution_timeout: Maximum agent execution time in seconds (1–2700). - llm_model: The LLM model identifier to use for the task (e.g. 'openai/gpt-5.6-luna') + llm_model: The LLM model identifier to use for the task (e.g. 'openai/gpt-6-luna') recording_enabled: Record device video for the whole task and persist a retrievable reference @@ -929,6 +961,8 @@ async def run_streamed( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/tasks/stream", @@ -958,7 +992,11 @@ async def run_streamed( task_run_streamed_params.TaskRunStreamedParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=object, ) @@ -974,6 +1012,7 @@ async def send_message( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TaskSendMessageResponse: """Send a message to a running agent task. @@ -990,6 +1029,8 @@ async def send_message( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not task_id: raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}") @@ -997,7 +1038,11 @@ async def send_message( path_template("/tasks/{task_id}/message", task_id=task_id), body=await async_maybe_transform({"message": message}, task_send_message_params.TaskSendMessageParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TaskSendMessageResponse, ) @@ -1012,6 +1057,7 @@ async def stop( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TaskStopResponse: """Cancel a running task. @@ -1026,13 +1072,19 @@ async def stop( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not task_id: raise ValueError(f"Expected a non-empty value for `task_id` but received {task_id!r}") return await self._post( path_template("/tasks/{task_id}/cancel", task_id=task_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TaskStopResponse, ) diff --git a/src/mobilerun_sdk/resources/webhooks/webhooks.py b/src/mobilerun_sdk/resources/webhooks/webhooks.py index dd33580a..e4bbc4b1 100644 --- a/src/mobilerun_sdk/resources/webhooks/webhooks.py +++ b/src/mobilerun_sdk/resources/webhooks/webhooks.py @@ -74,6 +74,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> WebhookCreateResponse: """ Creates a webhook subscription with a delivery URL and an optional list of event @@ -89,6 +90,8 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/webhooks", @@ -101,7 +104,11 @@ def create( webhook_create_params.WebhookCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=WebhookCreateResponse, ) @@ -154,6 +161,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> WebhookUpdateResponse: """Updates a webhook subscription. @@ -170,6 +178,8 @@ def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") @@ -184,7 +194,11 @@ def update( webhook_update_params.WebhookUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=WebhookUpdateResponse, ) @@ -258,6 +272,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Deletes a webhook subscription so it stops receiving deliveries. @@ -272,6 +287,8 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") @@ -279,7 +296,11 @@ def delete( return self._delete( path_template("/webhooks/{id}", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -317,6 +338,7 @@ def rotate_secret( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> WebhookRotateSecretResponse: """ Generates a new signing secret for the webhook subscription and returns it once @@ -331,13 +353,19 @@ def rotate_secret( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( path_template("/webhooks/{id}/rotate-secret", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=WebhookRotateSecretResponse, ) @@ -352,6 +380,7 @@ def test_delivery( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> WebhookTestDeliveryResponse: """ Sends a single test payload to the webhook subscription URL to verify @@ -366,13 +395,19 @@ def test_delivery( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return self._post( path_template("/webhooks/{id}/test", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=WebhookTestDeliveryResponse, ) @@ -414,6 +449,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> WebhookCreateResponse: """ Creates a webhook subscription with a delivery URL and an optional list of event @@ -429,6 +465,8 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/webhooks", @@ -441,7 +479,11 @@ async def create( webhook_create_params.WebhookCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=WebhookCreateResponse, ) @@ -494,6 +536,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> WebhookUpdateResponse: """Updates a webhook subscription. @@ -510,6 +553,8 @@ async def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") @@ -524,7 +569,11 @@ async def update( webhook_update_params.WebhookUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=WebhookUpdateResponse, ) @@ -598,6 +647,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> None: """Deletes a webhook subscription so it stops receiving deliveries. @@ -612,6 +662,8 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") @@ -619,7 +671,11 @@ async def delete( return await self._delete( path_template("/webhooks/{id}", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=NoneType, ) @@ -657,6 +713,7 @@ async def rotate_secret( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> WebhookRotateSecretResponse: """ Generates a new signing secret for the webhook subscription and returns it once @@ -671,13 +728,19 @@ async def rotate_secret( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( path_template("/webhooks/{id}/rotate-secret", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=WebhookRotateSecretResponse, ) @@ -692,6 +755,7 @@ async def test_delivery( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> WebhookTestDeliveryResponse: """ Sends a single test payload to the webhook subscription URL to verify @@ -706,13 +770,19 @@ async def test_delivery( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not id: raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") return await self._post( path_template("/webhooks/{id}/test", id=id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=WebhookTestDeliveryResponse, ) diff --git a/src/mobilerun_sdk/resources/workflows/action_catalog.py b/src/mobilerun_sdk/resources/workflows/action_catalog.py index da75896c..2fc99f7d 100644 --- a/src/mobilerun_sdk/resources/workflows/action_catalog.py +++ b/src/mobilerun_sdk/resources/workflows/action_catalog.py @@ -83,7 +83,7 @@ def list( *, page: int | Omit = omit, page_size: int | Omit = omit, - service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] | Omit = omit, + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks", "integrations_api"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -184,7 +184,7 @@ async def list( *, page: int | Omit = omit, page_size: int | Omit = omit, - service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] | Omit = omit, + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks", "integrations_api"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, diff --git a/src/mobilerun_sdk/resources/workflows/actions/actions.py b/src/mobilerun_sdk/resources/workflows/actions/actions.py index d99bbf4e..28d5296f 100644 --- a/src/mobilerun_sdk/resources/workflows/actions/actions.py +++ b/src/mobilerun_sdk/resources/workflows/actions/actions.py @@ -73,6 +73,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ActionCreateResponse: """ Create a reusable action from a catalog entry (`catalogEntryId`), with an @@ -87,6 +88,8 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/actions", @@ -100,7 +103,11 @@ def create( action_create_params.ActionCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ActionCreateResponse, ) @@ -152,6 +159,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ActionUpdateResponse: """ Partially update an action's name, description, or params; all fields are @@ -165,6 +173,8 @@ def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not action_id: raise ValueError(f"Expected a non-empty value for `action_id` but received {action_id!r}") @@ -179,7 +189,11 @@ def update( action_update_params.ActionUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ActionUpdateResponse, ) @@ -192,7 +206,7 @@ def list( page: int | Omit = omit, page_size: int | Omit = omit, search: str | Omit = omit, - service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] | Omit = omit, + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks", "integrations_api"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -246,6 +260,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ActionDeleteResponse: """Delete an action by its ID. @@ -259,13 +274,19 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not action_id: raise ValueError(f"Expected a non-empty value for `action_id` but received {action_id!r}") return self._delete( path_template("/actions/{action_id}", action_id=action_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ActionDeleteResponse, ) @@ -308,6 +329,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ActionCreateResponse: """ Create a reusable action from a catalog entry (`catalogEntryId`), with an @@ -322,6 +344,8 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/actions", @@ -335,7 +359,11 @@ async def create( action_create_params.ActionCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ActionCreateResponse, ) @@ -387,6 +415,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ActionUpdateResponse: """ Partially update an action's name, description, or params; all fields are @@ -400,6 +429,8 @@ async def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not action_id: raise ValueError(f"Expected a non-empty value for `action_id` but received {action_id!r}") @@ -414,7 +445,11 @@ async def update( action_update_params.ActionUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ActionUpdateResponse, ) @@ -427,7 +462,7 @@ async def list( page: int | Omit = omit, page_size: int | Omit = omit, search: str | Omit = omit, - service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] | Omit = omit, + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks", "integrations_api"] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -481,6 +516,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ActionDeleteResponse: """Delete an action by its ID. @@ -494,13 +530,19 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not action_id: raise ValueError(f"Expected a non-empty value for `action_id` but received {action_id!r}") return await self._delete( path_template("/actions/{action_id}", action_id=action_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ActionDeleteResponse, ) diff --git a/src/mobilerun_sdk/resources/workflows/events.py b/src/mobilerun_sdk/resources/workflows/events.py index b585ec6d..d60f0f8d 100644 --- a/src/mobilerun_sdk/resources/workflows/events.py +++ b/src/mobilerun_sdk/resources/workflows/events.py @@ -56,6 +56,7 @@ def dry_run( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> EventDryRunResponse: """Simulate an event against all configured flows. @@ -70,6 +71,8 @@ def dry_run( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/events/dry-run", @@ -82,7 +85,11 @@ def dry_run( event_dry_run_params.EventDryRunParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=EventDryRunResponse, ) @@ -99,6 +106,7 @@ def ingest( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> EventIngestResponse: """Ingest an event for trigger evaluation. @@ -112,6 +120,8 @@ def ingest( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/events/ingest", @@ -124,7 +134,11 @@ def ingest( event_ingest_params.EventIngestParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=EventIngestResponse, ) @@ -162,6 +176,7 @@ async def dry_run( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> EventDryRunResponse: """Simulate an event against all configured flows. @@ -176,6 +191,8 @@ async def dry_run( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/events/dry-run", @@ -188,7 +205,11 @@ async def dry_run( event_dry_run_params.EventDryRunParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=EventDryRunResponse, ) @@ -205,6 +226,7 @@ async def ingest( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> EventIngestResponse: """Ingest an event for trigger evaluation. @@ -218,6 +240,8 @@ async def ingest( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/events/ingest", @@ -230,7 +254,11 @@ async def ingest( event_ingest_params.EventIngestParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=EventIngestResponse, ) diff --git a/src/mobilerun_sdk/resources/workflows/executions.py b/src/mobilerun_sdk/resources/workflows/executions.py index cc3f03bd..9f47ddcc 100644 --- a/src/mobilerun_sdk/resources/workflows/executions.py +++ b/src/mobilerun_sdk/resources/workflows/executions.py @@ -155,6 +155,7 @@ def abort( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ExecutionAbortResponse: """ Signals the worker to stop the execution between steps and marks it cancelled. @@ -168,13 +169,19 @@ def abort( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not execution_id: raise ValueError(f"Expected a non-empty value for `execution_id` but received {execution_id!r}") return self._post( path_template("/executions/{execution_id}/abort", execution_id=execution_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ExecutionAbortResponse, ) @@ -356,6 +363,7 @@ async def abort( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ExecutionAbortResponse: """ Signals the worker to stop the execution between steps and marks it cancelled. @@ -369,13 +377,19 @@ async def abort( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not execution_id: raise ValueError(f"Expected a non-empty value for `execution_id` but received {execution_id!r}") return await self._post( path_template("/executions/{execution_id}/abort", execution_id=execution_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ExecutionAbortResponse, ) diff --git a/src/mobilerun_sdk/resources/workflows/flows/actions.py b/src/mobilerun_sdk/resources/workflows/flows/actions.py index 26ca8773..87c3311e 100644 --- a/src/mobilerun_sdk/resources/workflows/flows/actions.py +++ b/src/mobilerun_sdk/resources/workflows/flows/actions.py @@ -98,6 +98,7 @@ def add( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ActionAddResponse: """ Append a single action to a flow at the given `position`, optionally nesting it @@ -113,6 +114,8 @@ def add( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") @@ -132,7 +135,11 @@ def add( action_add_params.ActionAddParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ActionAddResponse, ) @@ -148,6 +155,7 @@ def remove( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ActionRemoveResponse: """Remove a single action from a flow by its `flowActionId`. @@ -162,6 +170,8 @@ def remove( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") @@ -170,7 +180,11 @@ def remove( return self._delete( path_template("/flows/{flow_id}/actions/{flow_action_id}", flow_id=flow_id, flow_action_id=flow_action_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ActionRemoveResponse, ) @@ -186,6 +200,7 @@ def replace( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ActionReplaceResponse: """ Replace a flow's entire action list with the supplied set (at least one @@ -201,6 +216,8 @@ def replace( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") @@ -208,7 +225,11 @@ def replace( path_template("/flows/{flow_id}/actions", flow_id=flow_id), body=maybe_transform({"actions": actions}, action_replace_params.ActionReplaceParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ActionReplaceResponse, ) @@ -286,6 +307,7 @@ async def add( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ActionAddResponse: """ Append a single action to a flow at the given `position`, optionally nesting it @@ -301,6 +323,8 @@ async def add( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") @@ -320,7 +344,11 @@ async def add( action_add_params.ActionAddParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ActionAddResponse, ) @@ -336,6 +364,7 @@ async def remove( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ActionRemoveResponse: """Remove a single action from a flow by its `flowActionId`. @@ -350,6 +379,8 @@ async def remove( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") @@ -358,7 +389,11 @@ async def remove( return await self._delete( path_template("/flows/{flow_id}/actions/{flow_action_id}", flow_id=flow_id, flow_action_id=flow_action_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ActionRemoveResponse, ) @@ -374,6 +409,7 @@ async def replace( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> ActionReplaceResponse: """ Replace a flow's entire action list with the supplied set (at least one @@ -389,6 +425,8 @@ async def replace( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") @@ -396,7 +434,11 @@ async def replace( path_template("/flows/{flow_id}/actions", flow_id=flow_id), body=await async_maybe_transform({"actions": actions}, action_replace_params.ActionReplaceParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=ActionReplaceResponse, ) diff --git a/src/mobilerun_sdk/resources/workflows/flows/flows.py b/src/mobilerun_sdk/resources/workflows/flows/flows.py index 1faf5913..58b579bb 100644 --- a/src/mobilerun_sdk/resources/workflows/flows/flows.py +++ b/src/mobilerun_sdk/resources/workflows/flows/flows.py @@ -79,6 +79,7 @@ def create( trigger_id: str, cooldown_scope: Literal["flow", "device"] | Omit = omit, cooldown_seconds: Optional[int] | Omit = omit, + delivery: flow_create_params.Delivery | Omit = omit, description: str | Omit = omit, device_ids: SequenceNotStr[str] | Omit = omit, enabled: bool | Omit = omit, @@ -96,6 +97,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FlowCreateResponse: """ Create a flow that binds a trigger (`triggerId`) to an ordered list of actions, @@ -104,9 +106,6 @@ def create( success or failure. Args: - recording_enabled: Deprecated compatibility field. true maps to recordingPolicy.mode="flow"; false - maps to "off". - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -114,6 +113,8 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/flows", @@ -124,6 +125,7 @@ def create( "trigger_id": trigger_id, "cooldown_scope": cooldown_scope, "cooldown_seconds": cooldown_seconds, + "delivery": delivery, "description": description, "device_ids": device_ids, "enabled": enabled, @@ -139,7 +141,11 @@ def create( flow_create_params.FlowCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FlowCreateResponse, ) @@ -184,6 +190,7 @@ def update( *, cooldown_scope: Literal["flow", "device"] | Omit = omit, cooldown_seconds: Optional[int] | Omit = omit, + delivery: Optional[flow_update_params.Delivery] | Omit = omit, description: str | Omit = omit, device_ids: SequenceNotStr[str] | Omit = omit, enabled: bool | Omit = omit, @@ -204,6 +211,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FlowUpdateResponse: """ Partially update a flow's settings — name, trigger binding, enabled state, @@ -224,6 +232,8 @@ def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") @@ -233,6 +243,7 @@ def update( { "cooldown_scope": cooldown_scope, "cooldown_seconds": cooldown_seconds, + "delivery": delivery, "description": description, "device_ids": device_ids, "enabled": enabled, @@ -251,7 +262,11 @@ def update( flow_update_params.FlowUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FlowUpdateResponse, ) @@ -332,6 +347,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FlowDeleteResponse: """Terminally archive a flow by its ID. @@ -346,13 +362,19 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") return self._delete( path_template("/flows/{flow_id}", flow_id=flow_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FlowDeleteResponse, ) @@ -393,6 +415,7 @@ def clone( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FlowCloneResponse: """Create a copy of an existing flow, including its actions and settings. @@ -408,6 +431,8 @@ def clone( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") @@ -421,7 +446,11 @@ def clone( flow_clone_params.FlowCloneParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FlowCloneResponse, ) @@ -437,6 +466,7 @@ def dry_run( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FlowDryRunResponse: """ Simulate this flow firing without storing events, enqueuing jobs, or consuming @@ -462,6 +492,8 @@ def dry_run( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") @@ -469,7 +501,11 @@ def dry_run( path_template("/flows/{flow_id}/dry-run", flow_id=flow_id), body=maybe_transform({"payload": payload}, flow_dry_run_params.FlowDryRunParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FlowDryRunResponse, ) @@ -517,6 +553,7 @@ def unblock( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FlowUnblockResponse: """Clear a flow's blocked status after fixing the underlying issue. @@ -531,13 +568,19 @@ def unblock( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") return self._post( path_template("/flows/{flow_id}/unblock", flow_id=flow_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FlowUnblockResponse, ) @@ -575,6 +618,7 @@ async def create( trigger_id: str, cooldown_scope: Literal["flow", "device"] | Omit = omit, cooldown_seconds: Optional[int] | Omit = omit, + delivery: flow_create_params.Delivery | Omit = omit, description: str | Omit = omit, device_ids: SequenceNotStr[str] | Omit = omit, enabled: bool | Omit = omit, @@ -592,6 +636,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FlowCreateResponse: """ Create a flow that binds a trigger (`triggerId`) to an ordered list of actions, @@ -600,9 +645,6 @@ async def create( success or failure. Args: - recording_enabled: Deprecated compatibility field. true maps to recordingPolicy.mode="flow"; false - maps to "off". - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -610,6 +652,8 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/flows", @@ -620,6 +664,7 @@ async def create( "trigger_id": trigger_id, "cooldown_scope": cooldown_scope, "cooldown_seconds": cooldown_seconds, + "delivery": delivery, "description": description, "device_ids": device_ids, "enabled": enabled, @@ -635,7 +680,11 @@ async def create( flow_create_params.FlowCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FlowCreateResponse, ) @@ -680,6 +729,7 @@ async def update( *, cooldown_scope: Literal["flow", "device"] | Omit = omit, cooldown_seconds: Optional[int] | Omit = omit, + delivery: Optional[flow_update_params.Delivery] | Omit = omit, description: str | Omit = omit, device_ids: SequenceNotStr[str] | Omit = omit, enabled: bool | Omit = omit, @@ -700,6 +750,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FlowUpdateResponse: """ Partially update a flow's settings — name, trigger binding, enabled state, @@ -720,6 +771,8 @@ async def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") @@ -729,6 +782,7 @@ async def update( { "cooldown_scope": cooldown_scope, "cooldown_seconds": cooldown_seconds, + "delivery": delivery, "description": description, "device_ids": device_ids, "enabled": enabled, @@ -747,7 +801,11 @@ async def update( flow_update_params.FlowUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FlowUpdateResponse, ) @@ -828,6 +886,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FlowDeleteResponse: """Terminally archive a flow by its ID. @@ -842,13 +901,19 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") return await self._delete( path_template("/flows/{flow_id}", flow_id=flow_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FlowDeleteResponse, ) @@ -889,6 +954,7 @@ async def clone( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FlowCloneResponse: """Create a copy of an existing flow, including its actions and settings. @@ -904,6 +970,8 @@ async def clone( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") @@ -917,7 +985,11 @@ async def clone( flow_clone_params.FlowCloneParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FlowCloneResponse, ) @@ -933,6 +1005,7 @@ async def dry_run( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FlowDryRunResponse: """ Simulate this flow firing without storing events, enqueuing jobs, or consuming @@ -958,6 +1031,8 @@ async def dry_run( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") @@ -965,7 +1040,11 @@ async def dry_run( path_template("/flows/{flow_id}/dry-run", flow_id=flow_id), body=await async_maybe_transform({"payload": payload}, flow_dry_run_params.FlowDryRunParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FlowDryRunResponse, ) @@ -1013,6 +1092,7 @@ async def unblock( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> FlowUnblockResponse: """Clear a flow's blocked status after fixing the underlying issue. @@ -1027,13 +1107,19 @@ async def unblock( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not flow_id: raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") return await self._post( path_template("/flows/{flow_id}/unblock", flow_id=flow_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=FlowUnblockResponse, ) diff --git a/src/mobilerun_sdk/resources/workflows/triggers.py b/src/mobilerun_sdk/resources/workflows/triggers.py index 752cd1dd..837188ec 100644 --- a/src/mobilerun_sdk/resources/workflows/triggers.py +++ b/src/mobilerun_sdk/resources/workflows/triggers.py @@ -66,6 +66,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TriggerCreateResponse: """ Create a trigger with an activation type of `event`, `schedule`, or `custom`. @@ -83,6 +84,8 @@ def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return self._post( "/triggers", @@ -100,7 +103,11 @@ def create( trigger_create_params.TriggerCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TriggerCreateResponse, ) @@ -157,6 +164,7 @@ def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TriggerUpdateResponse: """Partially update a trigger; all fields are optional. @@ -174,6 +182,8 @@ def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not trigger_id: raise ValueError(f"Expected a non-empty value for `trigger_id` but received {trigger_id!r}") @@ -193,7 +203,11 @@ def update( trigger_update_params.TriggerUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TriggerUpdateResponse, ) @@ -262,6 +276,7 @@ def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TriggerDeleteResponse: """Delete a trigger by its ID. @@ -275,13 +290,19 @@ def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not trigger_id: raise ValueError(f"Expected a non-empty value for `trigger_id` but received {trigger_id!r}") return self._delete( path_template("/triggers/{trigger_id}", trigger_id=trigger_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TriggerDeleteResponse, ) @@ -291,13 +312,13 @@ def fire( trigger_id: str, *, payload: Dict[str, object], - invocation_id: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TriggerFireResponse: """ Invoke a custom trigger directly with an arbitrary JSON payload. @@ -323,10 +344,6 @@ def fire( Validated against the trigger's customPayloadSchema when one is configured; otherwise only "must be a JSON object" is enforced. - invocation_id: Optional client-supplied idempotency key. When provided, a flow that already has - an execution for this (flow, invocationId) is skipped and `deduplicated` is - true. When omitted a fresh server-side id is generated (no dedup). - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -334,20 +351,20 @@ def fire( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not trigger_id: raise ValueError(f"Expected a non-empty value for `trigger_id` but received {trigger_id!r}") return self._post( path_template("/triggers/{trigger_id}/fire", trigger_id=trigger_id), - body=maybe_transform( - { - "payload": payload, - "invocation_id": invocation_id, - }, - trigger_fire_params.TriggerFireParams, - ), + body=maybe_transform({"payload": payload}, trigger_fire_params.TriggerFireParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TriggerFireResponse, ) @@ -390,6 +407,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TriggerCreateResponse: """ Create a trigger with an activation type of `event`, `schedule`, or `custom`. @@ -407,6 +425,8 @@ async def create( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ return await self._post( "/triggers", @@ -424,7 +444,11 @@ async def create( trigger_create_params.TriggerCreateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TriggerCreateResponse, ) @@ -481,6 +505,7 @@ async def update( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TriggerUpdateResponse: """Partially update a trigger; all fields are optional. @@ -498,6 +523,8 @@ async def update( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not trigger_id: raise ValueError(f"Expected a non-empty value for `trigger_id` but received {trigger_id!r}") @@ -517,7 +544,11 @@ async def update( trigger_update_params.TriggerUpdateParams, ), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TriggerUpdateResponse, ) @@ -586,6 +617,7 @@ async def delete( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TriggerDeleteResponse: """Delete a trigger by its ID. @@ -599,13 +631,19 @@ async def delete( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not trigger_id: raise ValueError(f"Expected a non-empty value for `trigger_id` but received {trigger_id!r}") return await self._delete( path_template("/triggers/{trigger_id}", trigger_id=trigger_id), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TriggerDeleteResponse, ) @@ -615,13 +653,13 @@ async def fire( trigger_id: str, *, payload: Dict[str, object], - invocation_id: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, + idempotency_key: str | None = None, ) -> TriggerFireResponse: """ Invoke a custom trigger directly with an arbitrary JSON payload. @@ -647,10 +685,6 @@ async def fire( Validated against the trigger's customPayloadSchema when one is configured; otherwise only "must be a JSON object" is enforced. - invocation_id: Optional client-supplied idempotency key. When provided, a flow that already has - an execution for this (flow, invocationId) is skipped and `deduplicated` is - true. When omitted a fresh server-side id is generated (no dedup). - extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -658,20 +692,20 @@ async def fire( extra_body: Add additional JSON properties to the request timeout: Override the client-level default timeout for this request, in seconds + + idempotency_key: Specify a custom idempotency key for this request """ if not trigger_id: raise ValueError(f"Expected a non-empty value for `trigger_id` but received {trigger_id!r}") return await self._post( path_template("/triggers/{trigger_id}/fire", trigger_id=trigger_id), - body=await async_maybe_transform( - { - "payload": payload, - "invocation_id": invocation_id, - }, - trigger_fire_params.TriggerFireParams, - ), + body=await async_maybe_transform({"payload": payload}, trigger_fire_params.TriggerFireParams), options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, ), cast_to=TriggerFireResponse, ) diff --git a/src/mobilerun_sdk/types/app_list_response.py b/src/mobilerun_sdk/types/app_list_response.py index c7088c0c..5d85ac9c 100644 --- a/src/mobilerun_sdk/types/app_list_response.py +++ b/src/mobilerun_sdk/types/app_list_response.py @@ -292,7 +292,7 @@ class ItemVersion(BaseModel): size_bytes: Optional[int] = FieldInfo(alias="sizeBytes", default=None) - source: Literal["user", "system", "portal", "store", "catalog"] + source: Literal["user", "system", "portal", "store"] status: Literal["queued", "available", "failed"] diff --git a/src/mobilerun_sdk/types/app_list_versions_response.py b/src/mobilerun_sdk/types/app_list_versions_response.py index a4181ed7..a2bfedbd 100644 --- a/src/mobilerun_sdk/types/app_list_versions_response.py +++ b/src/mobilerun_sdk/types/app_list_versions_response.py @@ -281,7 +281,7 @@ class Data(BaseModel): size_bytes: Optional[int] = FieldInfo(alias="sizeBytes", default=None) - source: Literal["user", "system", "portal", "store", "catalog"] + source: Literal["user", "system", "portal", "store"] status: Literal["queued", "available", "failed"] diff --git a/src/mobilerun_sdk/types/assistant/conversation_create_params.py b/src/mobilerun_sdk/types/assistant/conversation_create_params.py index 96755aa4..e3937f4d 100644 --- a/src/mobilerun_sdk/types/assistant/conversation_create_params.py +++ b/src/mobilerun_sdk/types/assistant/conversation_create_params.py @@ -2,9 +2,7 @@ from __future__ import annotations -from typing_extensions import Required, Annotated, TypedDict - -from ..._utils import PropertyInfo +from typing_extensions import Required, TypedDict __all__ = ["ConversationCreateParams"] @@ -15,10 +13,3 @@ class ConversationCreateParams(TypedDict, total=False): agent: str description: str - - idempotency_key: Annotated[str, PropertyInfo(alias="Idempotency-Key")] - """Optional client key. - - Reusing the same key with the same request body by the same authenticated caller - within 24 hours returns the already-created session instead of a second one. - """ diff --git a/src/mobilerun_sdk/types/assistant/conversation_create_response.py b/src/mobilerun_sdk/types/assistant/conversation_create_response.py index 34341512..9c701f3f 100644 --- a/src/mobilerun_sdk/types/assistant/conversation_create_response.py +++ b/src/mobilerun_sdk/types/assistant/conversation_create_response.py @@ -25,6 +25,8 @@ class Session(BaseModel): created_at: str = FieldInfo(alias="createdAt") + credits_used: Optional[float] = FieldInfo(alias="creditsUsed", default=None) + description: Optional[str] = None last_active_at: str = FieldInfo(alias="lastActiveAt") diff --git a/src/mobilerun_sdk/types/assistant/conversation_list_response.py b/src/mobilerun_sdk/types/assistant/conversation_list_response.py index 3f3ba16a..efa428bd 100644 --- a/src/mobilerun_sdk/types/assistant/conversation_list_response.py +++ b/src/mobilerun_sdk/types/assistant/conversation_list_response.py @@ -25,6 +25,8 @@ class SessionUnionMember0(BaseModel): created_at: str = FieldInfo(alias="createdAt") + credits_used: Optional[float] = FieldInfo(alias="creditsUsed", default=None) + description: Optional[str] = None episode: int @@ -69,6 +71,8 @@ class SessionUnionMember1(BaseModel): created_at: str = FieldInfo(alias="createdAt") + credits_used: Optional[float] = FieldInfo(alias="creditsUsed", default=None) + description: Optional[str] = None episode: int diff --git a/src/mobilerun_sdk/types/assistant/conversation_update_response.py b/src/mobilerun_sdk/types/assistant/conversation_update_response.py index 514fad09..7cd37fe1 100644 --- a/src/mobilerun_sdk/types/assistant/conversation_update_response.py +++ b/src/mobilerun_sdk/types/assistant/conversation_update_response.py @@ -25,6 +25,8 @@ class Session(BaseModel): created_at: str = FieldInfo(alias="createdAt") + credits_used: Optional[float] = FieldInfo(alias="creditsUsed", default=None) + description: Optional[str] = None last_active_at: str = FieldInfo(alias="lastActiveAt") diff --git a/src/mobilerun_sdk/types/connect/proxy_buy_params.py b/src/mobilerun_sdk/types/connect/proxy_buy_params.py index 8426ebeb..b228449f 100644 --- a/src/mobilerun_sdk/types/connect/proxy_buy_params.py +++ b/src/mobilerun_sdk/types/connect/proxy_buy_params.py @@ -2,9 +2,7 @@ from __future__ import annotations -from typing_extensions import Literal, Required, Annotated, TypedDict - -from ..._utils import PropertyInfo +from typing_extensions import Literal, Required, TypedDict __all__ = ["ProxyBuyParams"] @@ -15,4 +13,9 @@ class ProxyBuyParams(TypedDict, total=False): type: Required[Literal["dedicated_residential", "residential", "mobile"]] - idempotency_key: Annotated[str, PropertyInfo(alias="Idempotency-Key")] + name: str + """ + Display name for the proxy, up to 64 characters excluding surrounding + whitespace, and containing no NUL. Omit it (or send only whitespace) to get a + generated label built from the country, type, and id. + """ diff --git a/src/mobilerun_sdk/types/connect/proxy_buy_response.py b/src/mobilerun_sdk/types/connect/proxy_buy_response.py index d512bbef..410cd95f 100644 --- a/src/mobilerun_sdk/types/connect/proxy_buy_response.py +++ b/src/mobilerun_sdk/types/connect/proxy_buy_response.py @@ -23,6 +23,14 @@ class ProxyBuyResponse(BaseModel): host: str + name: str + """Display name for the proxy. + + Set it on create or change it with PATCH; when no name has been set, a label + generated from the proxy's country, type, and id is returned instead — so this + is never empty. + """ + password: str port: int diff --git a/src/mobilerun_sdk/types/connect/proxy_list_response.py b/src/mobilerun_sdk/types/connect/proxy_list_response.py index e68fd457..04aba83a 100644 --- a/src/mobilerun_sdk/types/connect/proxy_list_response.py +++ b/src/mobilerun_sdk/types/connect/proxy_list_response.py @@ -23,6 +23,14 @@ class Item(BaseModel): host: str + name: str + """Display name for the proxy. + + Set it on create or change it with PATCH; when no name has been set, a label + generated from the proxy's country, type, and id is returned instead — so this + is never empty. + """ + port: int status: Literal["checking", "pending_payment", "provisioning", "active", "cancelling", "ended", "error"] diff --git a/src/mobilerun_sdk/types/connect/proxy_retrieve_response.py b/src/mobilerun_sdk/types/connect/proxy_retrieve_response.py index 41014606..d4607b03 100644 --- a/src/mobilerun_sdk/types/connect/proxy_retrieve_response.py +++ b/src/mobilerun_sdk/types/connect/proxy_retrieve_response.py @@ -23,6 +23,14 @@ class ProxyRetrieveResponse(BaseModel): host: str + name: str + """Display name for the proxy. + + Set it on create or change it with PATCH; when no name has been set, a label + generated from the proxy's country, type, and id is returned instead — so this + is never empty. + """ + password: str port: int diff --git a/src/mobilerun_sdk/types/device_create_params.py b/src/mobilerun_sdk/types/device_create_params.py index 4596899e..c8169523 100644 --- a/src/mobilerun_sdk/types/device_create_params.py +++ b/src/mobilerun_sdk/types/device_create_params.py @@ -18,9 +18,13 @@ class DeviceCreateParams(TypedDict, total=False): billing: Literal["auto", "subscription", "minute"] """Billing mode. - 'auto' uses a subscription slot when available and otherwise bills per minute; - 'subscription' requires an available subscription slot; 'minute' bills per - minute. Only cloud phone and cloud emulator devices support per-minute billing. + 'auto' tries subscription first, then minute billing if no subscription + entitlement exists or all subscription slots are in use, provided minute billing + is enabled. When subscription billing is disabled, auto uses minutes directly. + Billing-service failures never trigger fallback. 'subscription' requires an + available subscription slot and never falls back. 'minute' uses minute billing + only, subject to balance and concurrency checks. Modes depend on the device + type's billing configuration. """ query_country: Annotated[str, PropertyInfo(alias="country")] @@ -29,21 +33,12 @@ class DeviceCreateParams(TypedDict, total=False): If omitted the system picks the country with the most availability. """ - device_type: Annotated[ - Literal[ - "android_cloud_phone", - "dedicated_premium_device", - "dedicated_physical_device", - "dedicated_ios_device", - "dedicated_emulated_device", - ], - PropertyInfo(alias="deviceType"), - ] - """ - Deprecated device type aliases are accepted during a compatibility grace period: - dedicated_premium_device maps to android_cloud_phone, dedicated_physical_device - maps to android_physical_phone, dedicated_ios_device maps to ios_stealth_phone, - and dedicated_emulated_device maps to android_emulator. + device_type: Annotated[str, PropertyInfo(alias="deviceType")] + """Use android_cloud_phone for a cloud Android phone. + + Only canonical identifiers are accepted. Other backends are deployment-specific; + recognized but unavailable types return DEVICE*TYPE_UNAVAILABLE (422). Retired + dedicated*\\** aliases are rejected with a canonical replacement. """ profile_id: Annotated[str, PropertyInfo(alias="profileId")] diff --git a/src/mobilerun_sdk/types/device_list_params.py b/src/mobilerun_sdk/types/device_list_params.py index 2f102f82..a3eedfdb 100644 --- a/src/mobilerun_sdk/types/device_list_params.py +++ b/src/mobilerun_sdk/types/device_list_params.py @@ -52,15 +52,10 @@ class DeviceListParams(TypedDict, total=False): ] type: Literal[ - "android_cloud_phone", - "dedicated_premium_device", - "dedicated_physical_device", - "dedicated_ios_device", - "dedicated_emulated_device", + "android_cloud_phone", "android_physical_phone", "ios_stealth_phone", "android_emulator", "ios_simulator" ] - """ - Deprecated device type aliases are accepted during a compatibility grace period: - dedicated_premium_device maps to android_cloud_phone, dedicated_physical_device - maps to android_physical_phone, dedicated_ios_device maps to ios_stealth_phone, - and dedicated_emulated_device maps to android_emulator. + """Canonical device type. + + Retired dedicated\\__\\** aliases are no longer accepted. Availability depends on + the deployment. """ diff --git a/src/mobilerun_sdk/types/devices/recording_start_params.py b/src/mobilerun_sdk/types/devices/recording_start_params.py index 007181d3..f2b6fefc 100644 --- a/src/mobilerun_sdk/types/devices/recording_start_params.py +++ b/src/mobilerun_sdk/types/devices/recording_start_params.py @@ -25,7 +25,9 @@ class RecordingStartParams(TypedDict, total=False): types: Optional[SequenceNotStr[str]] """ - Artifacts to capture: trajectory (input actions), video, and audio (captured + Artifacts to capture: trajectory (input actions; on portal stream-bridge devices + only when the handset announces trajectory capture), video, and audio (captured into the video artifact, so it requires video; honored by portal stream-bridge - recorders). Defaults to trajectory and video. + recorders). Defaults to trajectory and video, narrowed to what the device + produces. """ diff --git a/src/mobilerun_sdk/types/devices/traffic_session_create_params.py b/src/mobilerun_sdk/types/devices/traffic_session_create_params.py index 20d0df0a..39f0eb3e 100644 --- a/src/mobilerun_sdk/types/devices/traffic_session_create_params.py +++ b/src/mobilerun_sdk/types/devices/traffic_session_create_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing_extensions import Required, Annotated, TypedDict +from typing_extensions import Annotated, TypedDict from ..._utils import PropertyInfo @@ -10,8 +10,6 @@ class TrafficSessionCreateParams(TypedDict, total=False): - idempotency_key: Required[Annotated[str, PropertyInfo(alias="Idempotency-Key")]] - expires_in_seconds: Annotated[int, PropertyInfo(alias="expiresInSeconds")] max_body_bytes: Annotated[int, PropertyInfo(alias="maxBodyBytes")] diff --git a/src/mobilerun_sdk/types/file_upload_url_params.py b/src/mobilerun_sdk/types/file_upload_url_params.py index 98c7f0c0..7207b9ac 100644 --- a/src/mobilerun_sdk/types/file_upload_url_params.py +++ b/src/mobilerun_sdk/types/file_upload_url_params.py @@ -17,5 +17,3 @@ class FileUploadURLParams(TypedDict, total=False): size_bytes: Required[Annotated[int, PropertyInfo(alias="sizeBytes")]] zone: Literal["user", "skills"] - - idempotency_key: Annotated[str, PropertyInfo(alias="Idempotency-Key")] diff --git a/src/mobilerun_sdk/types/mailbox_create_params.py b/src/mobilerun_sdk/types/mailbox_create_params.py index 68cf68f8..77cc7737 100644 --- a/src/mobilerun_sdk/types/mailbox_create_params.py +++ b/src/mobilerun_sdk/types/mailbox_create_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing_extensions import Literal, Required, Annotated, TypedDict +from typing_extensions import Literal, Annotated, TypedDict from .._utils import PropertyInfo @@ -10,8 +10,6 @@ class MailboxCreateParams(TypedDict, total=False): - client_request_id: Required[Annotated[str, PropertyInfo(alias="clientRequestId")]] - billing_preference: Annotated[Literal["included", "included_only", "rent"], PropertyInfo(alias="billingPreference")] """ included uses package capacity when available and otherwise starts paid diff --git a/src/mobilerun_sdk/types/mailbox_create_response.py b/src/mobilerun_sdk/types/mailbox_create_response.py index 2bb8b3c9..e900323c 100644 --- a/src/mobilerun_sdk/types/mailbox_create_response.py +++ b/src/mobilerun_sdk/types/mailbox_create_response.py @@ -26,7 +26,7 @@ class Data(BaseModel): address: Optional[str] = None - billing_mode: Literal["rent", "included", "domain"] = FieldInfo(alias="billingMode") + billing_mode: Literal["rent", "included", "domain", "external"] = FieldInfo(alias="billingMode") cancel_at_period_end: bool = FieldInfo(alias="cancelAtPeriodEnd") @@ -44,7 +44,19 @@ class Data(BaseModel): label: Optional[str] = None - status: Literal["provisioning", "awaiting_payment", "active", "cancel_scheduled", "archived", "billing_error"] + provider: Literal["matix", "gmail"] + + status: Literal[ + "provisioning", + "awaiting_payment", + "active", + "cancel_scheduled", + "archived", + "billing_error", + "pending_connection", + "connection_expired", + "connection_removed", + ] class MailboxCreateResponse(BaseModel): diff --git a/src/mobilerun_sdk/types/mailbox_delete_response.py b/src/mobilerun_sdk/types/mailbox_delete_response.py index ac6cd9b8..4ef6563d 100644 --- a/src/mobilerun_sdk/types/mailbox_delete_response.py +++ b/src/mobilerun_sdk/types/mailbox_delete_response.py @@ -26,7 +26,7 @@ class Data(BaseModel): address: Optional[str] = None - billing_mode: Literal["rent", "included", "domain"] = FieldInfo(alias="billingMode") + billing_mode: Literal["rent", "included", "domain", "external"] = FieldInfo(alias="billingMode") cancel_at_period_end: bool = FieldInfo(alias="cancelAtPeriodEnd") @@ -44,7 +44,19 @@ class Data(BaseModel): label: Optional[str] = None - status: Literal["provisioning", "awaiting_payment", "active", "cancel_scheduled", "archived", "billing_error"] + provider: Literal["matix", "gmail"] + + status: Literal[ + "provisioning", + "awaiting_payment", + "active", + "cancel_scheduled", + "archived", + "billing_error", + "pending_connection", + "connection_expired", + "connection_removed", + ] class MailboxDeleteResponse(BaseModel): diff --git a/src/mobilerun_sdk/types/mailbox_list_response.py b/src/mobilerun_sdk/types/mailbox_list_response.py index 70ace920..8bde5500 100644 --- a/src/mobilerun_sdk/types/mailbox_list_response.py +++ b/src/mobilerun_sdk/types/mailbox_list_response.py @@ -27,7 +27,7 @@ class Item(BaseModel): address: Optional[str] = None - billing_mode: Literal["rent", "included", "domain"] = FieldInfo(alias="billingMode") + billing_mode: Literal["rent", "included", "domain", "external"] = FieldInfo(alias="billingMode") cancel_at_period_end: bool = FieldInfo(alias="cancelAtPeriodEnd") @@ -45,7 +45,19 @@ class Item(BaseModel): label: Optional[str] = None - status: Literal["provisioning", "awaiting_payment", "active", "cancel_scheduled", "archived", "billing_error"] + provider: Literal["matix", "gmail"] + + status: Literal[ + "provisioning", + "awaiting_payment", + "active", + "cancel_scheduled", + "archived", + "billing_error", + "pending_connection", + "connection_expired", + "connection_removed", + ] class MailboxListResponse(BaseModel): diff --git a/src/mobilerun_sdk/types/mailbox_restart_response.py b/src/mobilerun_sdk/types/mailbox_restart_response.py index ab9e1d79..316f0c79 100644 --- a/src/mobilerun_sdk/types/mailbox_restart_response.py +++ b/src/mobilerun_sdk/types/mailbox_restart_response.py @@ -26,7 +26,7 @@ class Data(BaseModel): address: Optional[str] = None - billing_mode: Literal["rent", "included", "domain"] = FieldInfo(alias="billingMode") + billing_mode: Literal["rent", "included", "domain", "external"] = FieldInfo(alias="billingMode") cancel_at_period_end: bool = FieldInfo(alias="cancelAtPeriodEnd") @@ -44,7 +44,19 @@ class Data(BaseModel): label: Optional[str] = None - status: Literal["provisioning", "awaiting_payment", "active", "cancel_scheduled", "archived", "billing_error"] + provider: Literal["matix", "gmail"] + + status: Literal[ + "provisioning", + "awaiting_payment", + "active", + "cancel_scheduled", + "archived", + "billing_error", + "pending_connection", + "connection_expired", + "connection_removed", + ] class MailboxRestartResponse(BaseModel): diff --git a/src/mobilerun_sdk/types/mailbox_retrieve_response.py b/src/mobilerun_sdk/types/mailbox_retrieve_response.py index ed490495..d9106311 100644 --- a/src/mobilerun_sdk/types/mailbox_retrieve_response.py +++ b/src/mobilerun_sdk/types/mailbox_retrieve_response.py @@ -26,7 +26,7 @@ class Data(BaseModel): address: Optional[str] = None - billing_mode: Literal["rent", "included", "domain"] = FieldInfo(alias="billingMode") + billing_mode: Literal["rent", "included", "domain", "external"] = FieldInfo(alias="billingMode") cancel_at_period_end: bool = FieldInfo(alias="cancelAtPeriodEnd") @@ -44,7 +44,19 @@ class Data(BaseModel): label: Optional[str] = None - status: Literal["provisioning", "awaiting_payment", "active", "cancel_scheduled", "archived", "billing_error"] + provider: Literal["matix", "gmail"] + + status: Literal[ + "provisioning", + "awaiting_payment", + "active", + "cancel_scheduled", + "archived", + "billing_error", + "pending_connection", + "connection_expired", + "connection_removed", + ] class MailboxRetrieveResponse(BaseModel): diff --git a/src/mobilerun_sdk/types/mailbox_uncancel_response.py b/src/mobilerun_sdk/types/mailbox_uncancel_response.py index fc6b588e..9c613702 100644 --- a/src/mobilerun_sdk/types/mailbox_uncancel_response.py +++ b/src/mobilerun_sdk/types/mailbox_uncancel_response.py @@ -26,7 +26,7 @@ class Data(BaseModel): address: Optional[str] = None - billing_mode: Literal["rent", "included", "domain"] = FieldInfo(alias="billingMode") + billing_mode: Literal["rent", "included", "domain", "external"] = FieldInfo(alias="billingMode") cancel_at_period_end: bool = FieldInfo(alias="cancelAtPeriodEnd") @@ -44,7 +44,19 @@ class Data(BaseModel): label: Optional[str] = None - status: Literal["provisioning", "awaiting_payment", "active", "cancel_scheduled", "archived", "billing_error"] + provider: Literal["matix", "gmail"] + + status: Literal[ + "provisioning", + "awaiting_payment", + "active", + "cancel_scheduled", + "archived", + "billing_error", + "pending_connection", + "connection_expired", + "connection_removed", + ] class MailboxUncancelResponse(BaseModel): diff --git a/src/mobilerun_sdk/types/mailbox_update_response.py b/src/mobilerun_sdk/types/mailbox_update_response.py index 99de186b..43419175 100644 --- a/src/mobilerun_sdk/types/mailbox_update_response.py +++ b/src/mobilerun_sdk/types/mailbox_update_response.py @@ -26,7 +26,7 @@ class Data(BaseModel): address: Optional[str] = None - billing_mode: Literal["rent", "included", "domain"] = FieldInfo(alias="billingMode") + billing_mode: Literal["rent", "included", "domain", "external"] = FieldInfo(alias="billingMode") cancel_at_period_end: bool = FieldInfo(alias="cancelAtPeriodEnd") @@ -44,7 +44,19 @@ class Data(BaseModel): label: Optional[str] = None - status: Literal["provisioning", "awaiting_payment", "active", "cancel_scheduled", "archived", "billing_error"] + provider: Literal["matix", "gmail"] + + status: Literal[ + "provisioning", + "awaiting_payment", + "active", + "cancel_scheduled", + "archived", + "billing_error", + "pending_connection", + "connection_expired", + "connection_removed", + ] class MailboxUpdateResponse(BaseModel): diff --git a/src/mobilerun_sdk/types/number_create_params.py b/src/mobilerun_sdk/types/number_create_params.py index 353cd5fb..1d190a8e 100644 --- a/src/mobilerun_sdk/types/number_create_params.py +++ b/src/mobilerun_sdk/types/number_create_params.py @@ -32,6 +32,3 @@ class NumberCreateParams(TypedDict, total=False): purpose: str """Optional purpose from GET /numbers/phones/purposes.""" - - idempotency_key: Annotated[str, PropertyInfo(alias="Idempotency-Key")] - """Optional request idempotency key.""" diff --git a/src/mobilerun_sdk/types/store/app_list_response.py b/src/mobilerun_sdk/types/store/app_list_response.py index c8dce76d..7ee43700 100644 --- a/src/mobilerun_sdk/types/store/app_list_response.py +++ b/src/mobilerun_sdk/types/store/app_list_response.py @@ -282,7 +282,7 @@ class ItemVersion(BaseModel): size_bytes: Optional[int] = FieldInfo(alias="sizeBytes", default=None) - source: Literal["user", "system", "portal", "store", "catalog"] + source: Literal["user", "system", "portal", "store"] status: Literal["queued", "available", "failed"] diff --git a/src/mobilerun_sdk/types/store/app_retrieve_response.py b/src/mobilerun_sdk/types/store/app_retrieve_response.py index c9461110..a7e430e6 100644 --- a/src/mobilerun_sdk/types/store/app_retrieve_response.py +++ b/src/mobilerun_sdk/types/store/app_retrieve_response.py @@ -281,7 +281,7 @@ class DataVersion(BaseModel): size_bytes: Optional[int] = FieldInfo(alias="sizeBytes", default=None) - source: Literal["user", "system", "portal", "store", "catalog"] + source: Literal["user", "system", "portal", "store"] status: Literal["queued", "available", "failed"] @@ -324,6 +324,8 @@ class Data(BaseModel): version: DataVersion + versions: List[DataVersion] + class AppRetrieveResponse(BaseModel): data: Data diff --git a/src/mobilerun_sdk/types/task_get_trajectory_response.py b/src/mobilerun_sdk/types/task_get_trajectory_response.py index b078d881..2afe64a6 100644 --- a/src/mobilerun_sdk/types/task_get_trajectory_response.py +++ b/src/mobilerun_sdk/types/task_get_trajectory_response.py @@ -298,6 +298,9 @@ class TrajectoryTrajectoryFastAgentResponseEventData(BaseModel): code: Optional[str] = None + tool_call_status: Optional[Literal["valid", "no_markup", "malformed"]] = None + """Classification of tool-call markup in an LLM response.""" + usage: Optional[TrajectoryTrajectoryFastAgentResponseEventDataUsage] = None diff --git a/src/mobilerun_sdk/types/task_run_params.py b/src/mobilerun_sdk/types/task_run_params.py index e0b99bc9..4251b359 100644 --- a/src/mobilerun_sdk/types/task_run_params.py +++ b/src/mobilerun_sdk/types/task_run_params.py @@ -34,7 +34,7 @@ class TaskRunParams(TypedDict, total=False): files: SequenceNotStr[str] llm_model: Annotated[str, PropertyInfo(alias="llmModel")] - """The LLM model identifier to use for the task (e.g. 'openai/gpt-5.6-luna')""" + """The LLM model identifier to use for the task (e.g. 'openai/gpt-6-luna')""" max_steps: Annotated[int, PropertyInfo(alias="maxSteps")] @@ -65,8 +65,6 @@ class TaskRunParams(TypedDict, total=False): Optional[Literal["US", "BR", "FR", "DE", "IN", "JP", "KR", "ZA"]], PropertyInfo(alias="vpnCountry") ] - idempotency_key: Annotated[str, PropertyInfo(alias="Idempotency-Key")] - class Credential(TypedDict, total=False): credential_names: Required[Annotated[SequenceNotStr[str], PropertyInfo(alias="credentialNames")]] diff --git a/src/mobilerun_sdk/types/task_run_streamed_params.py b/src/mobilerun_sdk/types/task_run_streamed_params.py index 5de0656e..64267509 100644 --- a/src/mobilerun_sdk/types/task_run_streamed_params.py +++ b/src/mobilerun_sdk/types/task_run_streamed_params.py @@ -34,7 +34,7 @@ class TaskRunStreamedParams(TypedDict, total=False): files: SequenceNotStr[str] llm_model: Annotated[str, PropertyInfo(alias="llmModel")] - """The LLM model identifier to use for the task (e.g. 'openai/gpt-5.6-luna')""" + """The LLM model identifier to use for the task (e.g. 'openai/gpt-6-luna')""" max_steps: Annotated[int, PropertyInfo(alias="maxSteps")] diff --git a/src/mobilerun_sdk/types/webhook_event_types_response.py b/src/mobilerun_sdk/types/webhook_event_types_response.py index 9c7439d7..749cdcf3 100644 --- a/src/mobilerun_sdk/types/webhook_event_types_response.py +++ b/src/mobilerun_sdk/types/webhook_event_types_response.py @@ -19,6 +19,8 @@ class DataSourceEventSurfaces(BaseModel): agent: Optional[bool] = None + live: Optional[bool] = None + class DataSourceEvent(BaseModel): description: str diff --git a/src/mobilerun_sdk/types/workflows/action_catalog_list_params.py b/src/mobilerun_sdk/types/workflows/action_catalog_list_params.py index 4e756a96..1e8cfead 100644 --- a/src/mobilerun_sdk/types/workflows/action_catalog_list_params.py +++ b/src/mobilerun_sdk/types/workflows/action_catalog_list_params.py @@ -14,4 +14,4 @@ class ActionCatalogListParams(TypedDict, total=False): page_size: Annotated[int, PropertyInfo(alias="pageSize")] - service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks", "integrations_api"] diff --git a/src/mobilerun_sdk/types/workflows/action_catalog_list_response.py b/src/mobilerun_sdk/types/workflows/action_catalog_list_response.py index 231b0240..b79983ea 100644 --- a/src/mobilerun_sdk/types/workflows/action_catalog_list_response.py +++ b/src/mobilerun_sdk/types/workflows/action_catalog_list_response.py @@ -22,10 +22,14 @@ class Item(BaseModel): name: str - service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] + provider: Literal["mobilerun", "oneDrive", "googleDrive"] + + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks", "integrations_api"] updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) + output_schema: Optional[object] = FieldInfo(alias="outputSchema", default=None) + params_schema: Optional[object] = FieldInfo(alias="paramsSchema", default=None) diff --git a/src/mobilerun_sdk/types/workflows/action_catalog_retrieve_response.py b/src/mobilerun_sdk/types/workflows/action_catalog_retrieve_response.py index 8769f574..3b7fa39c 100644 --- a/src/mobilerun_sdk/types/workflows/action_catalog_retrieve_response.py +++ b/src/mobilerun_sdk/types/workflows/action_catalog_retrieve_response.py @@ -21,10 +21,14 @@ class Data(BaseModel): name: str - service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] + provider: Literal["mobilerun", "oneDrive", "googleDrive"] + + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks", "integrations_api"] updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) + output_schema: Optional[object] = FieldInfo(alias="outputSchema", default=None) + params_schema: Optional[object] = FieldInfo(alias="paramsSchema", default=None) diff --git a/src/mobilerun_sdk/types/workflows/action_create_response.py b/src/mobilerun_sdk/types/workflows/action_create_response.py index 3a44b0a6..a1cef28a 100644 --- a/src/mobilerun_sdk/types/workflows/action_create_response.py +++ b/src/mobilerun_sdk/types/workflows/action_create_response.py @@ -27,7 +27,7 @@ class Data(BaseModel): owner_id: str = FieldInfo(alias="ownerId") - service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks", "integrations_api"] updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) diff --git a/src/mobilerun_sdk/types/workflows/action_list_params.py b/src/mobilerun_sdk/types/workflows/action_list_params.py index 9873843d..a5c3ac22 100644 --- a/src/mobilerun_sdk/types/workflows/action_list_params.py +++ b/src/mobilerun_sdk/types/workflows/action_list_params.py @@ -20,4 +20,4 @@ class ActionListParams(TypedDict, total=False): search: str - service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks", "integrations_api"] diff --git a/src/mobilerun_sdk/types/workflows/action_list_response.py b/src/mobilerun_sdk/types/workflows/action_list_response.py index 9fc8ce86..b9ee463b 100644 --- a/src/mobilerun_sdk/types/workflows/action_list_response.py +++ b/src/mobilerun_sdk/types/workflows/action_list_response.py @@ -28,7 +28,7 @@ class Item(BaseModel): owner_id: str = FieldInfo(alias="ownerId") - service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks", "integrations_api"] updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) diff --git a/src/mobilerun_sdk/types/workflows/action_retrieve_response.py b/src/mobilerun_sdk/types/workflows/action_retrieve_response.py index 61d45f65..54b7cea0 100644 --- a/src/mobilerun_sdk/types/workflows/action_retrieve_response.py +++ b/src/mobilerun_sdk/types/workflows/action_retrieve_response.py @@ -27,7 +27,7 @@ class Data(BaseModel): owner_id: str = FieldInfo(alias="ownerId") - service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks", "integrations_api"] updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) diff --git a/src/mobilerun_sdk/types/workflows/action_update_response.py b/src/mobilerun_sdk/types/workflows/action_update_response.py index 1b5a53b4..273952b5 100644 --- a/src/mobilerun_sdk/types/workflows/action_update_response.py +++ b/src/mobilerun_sdk/types/workflows/action_update_response.py @@ -27,7 +27,7 @@ class Data(BaseModel): owner_id: str = FieldInfo(alias="ownerId") - service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks", "integrations_api"] updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) diff --git a/src/mobilerun_sdk/types/workflows/event_dry_run_response.py b/src/mobilerun_sdk/types/workflows/event_dry_run_response.py index e7bb6eee..51478752 100644 --- a/src/mobilerun_sdk/types/workflows/event_dry_run_response.py +++ b/src/mobilerun_sdk/types/workflows/event_dry_run_response.py @@ -13,6 +13,8 @@ "DataMatchedFlow", "DataMatchedFlowAction", "DataMatchedFlowFlow", + "DataMatchedFlowFlowDelivery", + "DataMatchedFlowFlowDeliveryRecording", "DataMatchedFlowFlowRecordingPolicy", "DataMatchedFlowGates", "DataMatchedFlowTrigger", @@ -32,7 +34,7 @@ class DataMatchedFlowAction(BaseModel): recording_enabled: bool = FieldInfo(alias="recordingEnabled") - service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks", "integrations_api"] children: Optional[List[object]] = None """ @@ -43,6 +45,20 @@ class DataMatchedFlowAction(BaseModel): params: Optional[Dict[str, object]] = None +class DataMatchedFlowFlowDeliveryRecording(BaseModel): + filename: str + + +class DataMatchedFlowFlowDelivery(BaseModel): + destination: Literal["one_drive", "google_drive"] + + folder: Optional[str] = None + + recording: Optional[DataMatchedFlowFlowDeliveryRecording] = None + + screenshots: Optional[object] = None + + class DataMatchedFlowFlowRecordingPolicy(BaseModel): mode: Literal["off", "flow", "selected_steps"] @@ -64,6 +80,8 @@ class DataMatchedFlowFlow(BaseModel): created_by: Optional[str] = FieldInfo(alias="createdBy", default=None) + delivery: Optional[DataMatchedFlowFlowDelivery] = None + description: Optional[str] = None device_ids: List[str] = FieldInfo(alias="deviceIds") diff --git a/src/mobilerun_sdk/types/workflows/execution_retrieve_response.py b/src/mobilerun_sdk/types/workflows/execution_retrieve_response.py index 9af89a42..1a5fd5a3 100644 --- a/src/mobilerun_sdk/types/workflows/execution_retrieve_response.py +++ b/src/mobilerun_sdk/types/workflows/execution_retrieve_response.py @@ -1,13 +1,45 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Optional +from datetime import datetime from typing_extensions import Literal from pydantic import Field as FieldInfo from ..._models import BaseModel -__all__ = ["ExecutionRetrieveResponse", "Data", "DataFile", "DataRecording"] +__all__ = [ + "ExecutionRetrieveResponse", + "Data", + "DataDelivery", + "DataFile", + "DataProgress", + "DataProgressStep", + "DataRecording", + "DataScreenshot", +] + + +class DataDelivery(BaseModel): + artifact: Literal["recording", "file", "screenshot"] + + destination: Literal["one_drive", "google_drive"] + + error_code: Optional[str] = FieldInfo(alias="errorCode", default=None) + + filename: str + + finished_at: Optional[str] = FieldInfo(alias="finishedAt", default=None) + + folder: Optional[str] = None + + started_at: Optional[str] = FieldInfo(alias="startedAt", default=None) + + status: Literal["waiting", "uploading", "succeeded", "failed", "unknown", "cancelled"] + + step_index: Optional[int] = FieldInfo(alias="stepIndex", default=None) + + web_url: Optional[str] = FieldInfo(alias="webUrl", default=None) class DataFile(BaseModel): @@ -20,6 +52,36 @@ class DataFile(BaseModel): size_bytes: int = FieldInfo(alias="sizeBytes") +class DataProgressStep(BaseModel): + finished_at: Optional[datetime] = FieldInfo(alias="finishedAt", default=None) + + index: int + + method: str + + name: str + + service: str + + session_id: Optional[str] = FieldInfo(alias="sessionId", default=None) + + started_at: Optional[datetime] = FieldInfo(alias="startedAt", default=None) + + status: Literal["pending", "running", "success", "failed", "skipped", "cancelled"] + + +class DataProgress(BaseModel): + """ + Live progress read from step_progress; null for runs started before this feature. + """ + + current_index: Optional[int] = FieldInfo(alias="currentIndex", default=None) + + steps: List[DataProgressStep] + + total: int + + class DataRecording(BaseModel): id: str @@ -50,11 +112,36 @@ class DataRecording(BaseModel): stopped_at: Optional[str] = FieldInfo(alias="stoppedAt", default=None) +class DataScreenshot(BaseModel): + id: str + + captured_at: Optional[str] = FieldInfo(alias="capturedAt", default=None) + + iteration_index: int = FieldInfo(alias="iterationIndex") + + mime_type: str = FieldInfo(alias="mimeType") + + seq: int + + source: Literal["task", "agent"] + + step_index: int = FieldInfo(alias="stepIndex") + + step_name: str = FieldInfo(alias="stepName") + + class Data(BaseModel): id: str created_by: Optional[str] = FieldInfo(alias="createdBy", default=None) + deliveries: List[DataDelivery] + """ + OneDrive/Google Drive delivery lifecycle for this run's recording, file, and + screenshot uploads, ordered by startedAt. Empty when the flow has no delivery + configured. + """ + device_id: Optional[str] = FieldInfo(alias="deviceId", default=None) """Device this execution targets (the job's deviceId). @@ -87,6 +174,12 @@ class Data(BaseModel): kind: Literal["live", "dry_run", "verification"] + progress: Optional[DataProgress] = None + """ + Live progress read from step_progress; null for runs started before this + feature. + """ + recording_device_id: Optional[str] = FieldInfo(alias="recordingDeviceId", default=None) recording_id: Optional[str] = FieldInfo(alias="recordingId", default=None) @@ -102,6 +195,13 @@ class Data(BaseModel): Whole-flow recordings use -1 for every coordinate. """ + screenshots: List[DataScreenshot] + """Screenshots captured by tasks.run/agent.run steps, ordered by seq. + + Image bytes are never returned here — fetch a fresh signed URL via GET + /executions/{id}/screenshots/{screenshotId}. + """ + started_at: Optional[str] = FieldInfo(alias="startedAt", default=None) status: Optional[Literal["pending", "running", "success", "failed", "cancelled", "skipped", "invalid"]] = None diff --git a/src/mobilerun_sdk/types/workflows/flow_clone_response.py b/src/mobilerun_sdk/types/workflows/flow_clone_response.py index e08b73dd..ce1ec237 100644 --- a/src/mobilerun_sdk/types/workflows/flow_clone_response.py +++ b/src/mobilerun_sdk/types/workflows/flow_clone_response.py @@ -7,7 +7,21 @@ from ..._models import BaseModel -__all__ = ["FlowCloneResponse", "Data", "DataRecordingPolicy"] +__all__ = ["FlowCloneResponse", "Data", "DataDelivery", "DataDeliveryRecording", "DataRecordingPolicy"] + + +class DataDeliveryRecording(BaseModel): + filename: str + + +class DataDelivery(BaseModel): + destination: Literal["one_drive", "google_drive"] + + folder: Optional[str] = None + + recording: Optional[DataDeliveryRecording] = None + + screenshots: Optional[object] = None class DataRecordingPolicy(BaseModel): @@ -31,6 +45,8 @@ class Data(BaseModel): created_by: Optional[str] = FieldInfo(alias="createdBy", default=None) + delivery: Optional[DataDelivery] = None + description: Optional[str] = None device_ids: List[str] = FieldInfo(alias="deviceIds") diff --git a/src/mobilerun_sdk/types/workflows/flow_create_params.py b/src/mobilerun_sdk/types/workflows/flow_create_params.py index 1a292cf5..c6df47e9 100644 --- a/src/mobilerun_sdk/types/workflows/flow_create_params.py +++ b/src/mobilerun_sdk/types/workflows/flow_create_params.py @@ -8,7 +8,16 @@ from ..._types import SequenceNotStr from ..._utils import PropertyInfo -__all__ = ["FlowCreateParams", "Action", "ActionChild", "ActionChildOverrides", "ActionOverrides", "RecordingPolicy"] +__all__ = [ + "FlowCreateParams", + "Action", + "ActionChild", + "ActionChildOverrides", + "ActionOverrides", + "Delivery", + "DeliveryRecording", + "RecordingPolicy", +] class FlowCreateParams(TypedDict, total=False): @@ -22,6 +31,8 @@ class FlowCreateParams(TypedDict, total=False): cooldown_seconds: Annotated[Optional[int], PropertyInfo(alias="cooldownSeconds")] + delivery: Delivery + description: str device_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="deviceIds")] @@ -37,10 +48,6 @@ class FlowCreateParams(TypedDict, total=False): notify_webhook_id: Annotated[Optional[str], PropertyInfo(alias="notifyWebhookId")] recording_enabled: Annotated[bool, PropertyInfo(alias="recordingEnabled")] - """Deprecated compatibility field. - - true maps to recordingPolicy.mode="flow"; false maps to "off". - """ recording_policy: Annotated[RecordingPolicy, PropertyInfo(alias="recordingPolicy")] @@ -87,5 +94,19 @@ class Action(TypedDict, total=False): recording_enabled: Annotated[bool, PropertyInfo(alias="recordingEnabled")] +class DeliveryRecording(TypedDict, total=False): + filename: Required[str] + + +class Delivery(TypedDict, total=False): + destination: Required[Literal["one_drive", "google_drive"]] + + folder: str + + recording: DeliveryRecording + + screenshots: object + + class RecordingPolicy(TypedDict, total=False): mode: Required[Literal["off", "flow", "selected_steps"]] diff --git a/src/mobilerun_sdk/types/workflows/flow_create_response.py b/src/mobilerun_sdk/types/workflows/flow_create_response.py index d4129117..6a0b08cb 100644 --- a/src/mobilerun_sdk/types/workflows/flow_create_response.py +++ b/src/mobilerun_sdk/types/workflows/flow_create_response.py @@ -7,7 +7,21 @@ from ..._models import BaseModel -__all__ = ["FlowCreateResponse", "Data", "DataRecordingPolicy"] +__all__ = ["FlowCreateResponse", "Data", "DataDelivery", "DataDeliveryRecording", "DataRecordingPolicy"] + + +class DataDeliveryRecording(BaseModel): + filename: str + + +class DataDelivery(BaseModel): + destination: Literal["one_drive", "google_drive"] + + folder: Optional[str] = None + + recording: Optional[DataDeliveryRecording] = None + + screenshots: Optional[object] = None class DataRecordingPolicy(BaseModel): @@ -31,6 +45,8 @@ class Data(BaseModel): created_by: Optional[str] = FieldInfo(alias="createdBy", default=None) + delivery: Optional[DataDelivery] = None + description: Optional[str] = None device_ids: List[str] = FieldInfo(alias="deviceIds") diff --git a/src/mobilerun_sdk/types/workflows/flow_dry_run_response.py b/src/mobilerun_sdk/types/workflows/flow_dry_run_response.py index 5592add2..233ec632 100644 --- a/src/mobilerun_sdk/types/workflows/flow_dry_run_response.py +++ b/src/mobilerun_sdk/types/workflows/flow_dry_run_response.py @@ -21,7 +21,7 @@ class DataAction(BaseModel): recording_enabled: bool = FieldInfo(alias="recordingEnabled") - service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks", "integrations_api"] children: Optional[List[object]] = None """ diff --git a/src/mobilerun_sdk/types/workflows/flow_list_response.py b/src/mobilerun_sdk/types/workflows/flow_list_response.py index 01705f9f..fec008d7 100644 --- a/src/mobilerun_sdk/types/workflows/flow_list_response.py +++ b/src/mobilerun_sdk/types/workflows/flow_list_response.py @@ -8,7 +8,21 @@ from ..._models import BaseModel from ..shared.pagination import Pagination -__all__ = ["FlowListResponse", "Item", "ItemRecordingPolicy"] +__all__ = ["FlowListResponse", "Item", "ItemDelivery", "ItemDeliveryRecording", "ItemRecordingPolicy"] + + +class ItemDeliveryRecording(BaseModel): + filename: str + + +class ItemDelivery(BaseModel): + destination: Literal["one_drive", "google_drive"] + + folder: Optional[str] = None + + recording: Optional[ItemDeliveryRecording] = None + + screenshots: Optional[object] = None class ItemRecordingPolicy(BaseModel): @@ -32,6 +46,8 @@ class Item(BaseModel): created_by: Optional[str] = FieldInfo(alias="createdBy", default=None) + delivery: Optional[ItemDelivery] = None + description: Optional[str] = None device_ids: List[str] = FieldInfo(alias="deviceIds") diff --git a/src/mobilerun_sdk/types/workflows/flow_retrieve_response.py b/src/mobilerun_sdk/types/workflows/flow_retrieve_response.py index b4cd5806..67752c72 100644 --- a/src/mobilerun_sdk/types/workflows/flow_retrieve_response.py +++ b/src/mobilerun_sdk/types/workflows/flow_retrieve_response.py @@ -7,7 +7,21 @@ from ..._models import BaseModel -__all__ = ["FlowRetrieveResponse", "Data", "DataRecordingPolicy"] +__all__ = ["FlowRetrieveResponse", "Data", "DataDelivery", "DataDeliveryRecording", "DataRecordingPolicy"] + + +class DataDeliveryRecording(BaseModel): + filename: str + + +class DataDelivery(BaseModel): + destination: Literal["one_drive", "google_drive"] + + folder: Optional[str] = None + + recording: Optional[DataDeliveryRecording] = None + + screenshots: Optional[object] = None class DataRecordingPolicy(BaseModel): @@ -31,6 +45,8 @@ class Data(BaseModel): created_by: Optional[str] = FieldInfo(alias="createdBy", default=None) + delivery: Optional[DataDelivery] = None + description: Optional[str] = None device_ids: List[str] = FieldInfo(alias="deviceIds") diff --git a/src/mobilerun_sdk/types/workflows/flow_unblock_response.py b/src/mobilerun_sdk/types/workflows/flow_unblock_response.py index d71392de..23ef02ab 100644 --- a/src/mobilerun_sdk/types/workflows/flow_unblock_response.py +++ b/src/mobilerun_sdk/types/workflows/flow_unblock_response.py @@ -7,7 +7,21 @@ from ..._models import BaseModel -__all__ = ["FlowUnblockResponse", "Data", "DataRecordingPolicy"] +__all__ = ["FlowUnblockResponse", "Data", "DataDelivery", "DataDeliveryRecording", "DataRecordingPolicy"] + + +class DataDeliveryRecording(BaseModel): + filename: str + + +class DataDelivery(BaseModel): + destination: Literal["one_drive", "google_drive"] + + folder: Optional[str] = None + + recording: Optional[DataDeliveryRecording] = None + + screenshots: Optional[object] = None class DataRecordingPolicy(BaseModel): @@ -31,6 +45,8 @@ class Data(BaseModel): created_by: Optional[str] = FieldInfo(alias="createdBy", default=None) + delivery: Optional[DataDelivery] = None + description: Optional[str] = None device_ids: List[str] = FieldInfo(alias="deviceIds") diff --git a/src/mobilerun_sdk/types/workflows/flow_update_params.py b/src/mobilerun_sdk/types/workflows/flow_update_params.py index 9f32e4bb..7d925975 100644 --- a/src/mobilerun_sdk/types/workflows/flow_update_params.py +++ b/src/mobilerun_sdk/types/workflows/flow_update_params.py @@ -8,7 +8,7 @@ from ..._types import SequenceNotStr from ..._utils import PropertyInfo -__all__ = ["FlowUpdateParams", "RecordingPolicy"] +__all__ = ["FlowUpdateParams", "Delivery", "DeliveryRecording", "RecordingPolicy"] class FlowUpdateParams(TypedDict, total=False): @@ -16,6 +16,8 @@ class FlowUpdateParams(TypedDict, total=False): cooldown_seconds: Annotated[Optional[int], PropertyInfo(alias="cooldownSeconds")] + delivery: Optional[Delivery] + description: str device_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="deviceIds")] @@ -50,5 +52,19 @@ class FlowUpdateParams(TypedDict, total=False): trigger_id: Annotated[str, PropertyInfo(alias="triggerId")] +class DeliveryRecording(TypedDict, total=False): + filename: Required[str] + + +class Delivery(TypedDict, total=False): + destination: Required[Literal["one_drive", "google_drive"]] + + folder: str + + recording: DeliveryRecording + + screenshots: object + + class RecordingPolicy(TypedDict, total=False): mode: Required[Literal["off", "flow", "selected_steps"]] diff --git a/src/mobilerun_sdk/types/workflows/flow_update_response.py b/src/mobilerun_sdk/types/workflows/flow_update_response.py index 511e934a..b9703c1f 100644 --- a/src/mobilerun_sdk/types/workflows/flow_update_response.py +++ b/src/mobilerun_sdk/types/workflows/flow_update_response.py @@ -7,7 +7,21 @@ from ..._models import BaseModel -__all__ = ["FlowUpdateResponse", "Data", "DataRecordingPolicy"] +__all__ = ["FlowUpdateResponse", "Data", "DataDelivery", "DataDeliveryRecording", "DataRecordingPolicy"] + + +class DataDeliveryRecording(BaseModel): + filename: str + + +class DataDelivery(BaseModel): + destination: Literal["one_drive", "google_drive"] + + folder: Optional[str] = None + + recording: Optional[DataDeliveryRecording] = None + + screenshots: Optional[object] = None class DataRecordingPolicy(BaseModel): @@ -31,6 +45,8 @@ class Data(BaseModel): created_by: Optional[str] = FieldInfo(alias="createdBy", default=None) + delivery: Optional[DataDelivery] = None + description: Optional[str] = None device_ids: List[str] = FieldInfo(alias="deviceIds") diff --git a/src/mobilerun_sdk/types/workflows/trigger_fire_params.py b/src/mobilerun_sdk/types/workflows/trigger_fire_params.py index 1a1f266d..03847b71 100644 --- a/src/mobilerun_sdk/types/workflows/trigger_fire_params.py +++ b/src/mobilerun_sdk/types/workflows/trigger_fire_params.py @@ -3,9 +3,7 @@ from __future__ import annotations from typing import Dict -from typing_extensions import Required, Annotated, TypedDict - -from ..._utils import PropertyInfo +from typing_extensions import Required, TypedDict __all__ = ["TriggerFireParams"] @@ -17,11 +15,3 @@ class TriggerFireParams(TypedDict, total=False): Validated against the trigger's customPayloadSchema when one is configured; otherwise only "must be a JSON object" is enforced. """ - - invocation_id: Annotated[str, PropertyInfo(alias="invocationId")] - """Optional client-supplied idempotency key. - - When provided, a flow that already has an execution for this (flow, - invocationId) is skipped and `deduplicated` is true. When omitted a fresh - server-side id is generated (no dedup). - """ diff --git a/tests/api_resources/assistant/test_conversations.py b/tests/api_resources/assistant/test_conversations.py index 4652e4ad..eec108db 100644 --- a/tests/api_resources/assistant/test_conversations.py +++ b/tests/api_resources/assistant/test_conversations.py @@ -42,7 +42,6 @@ def test_method_create_with_all_params(self, client: Mobilerun) -> None: title="x", agent="x", description="description", - idempotency_key="Idempotency-Key", ) assert_matches_type(ConversationCreateResponse, conversation, path=["response"]) @@ -459,7 +458,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncMobilerun) title="x", agent="x", description="description", - idempotency_key="Idempotency-Key", ) assert_matches_type(ConversationCreateResponse, conversation, path=["response"]) diff --git a/tests/api_resources/connect/test_proxies.py b/tests/api_resources/connect/test_proxies.py index f2e62efb..dd993068 100644 --- a/tests/api_resources/connect/test_proxies.py +++ b/tests/api_resources/connect/test_proxies.py @@ -119,7 +119,7 @@ def test_method_buy_with_all_params(self, client: Mobilerun) -> None: proxy = client.connect.proxies.buy( country="country", type="dedicated_residential", - idempotency_key="Idempotency-Key", + name="name", ) assert_matches_type(ProxyBuyResponse, proxy, path=["response"]) @@ -411,7 +411,7 @@ async def test_method_buy_with_all_params(self, async_client: AsyncMobilerun) -> proxy = await async_client.connect.proxies.buy( country="country", type="dedicated_residential", - idempotency_key="Idempotency-Key", + name="name", ) assert_matches_type(ProxyBuyResponse, proxy, path=["response"]) diff --git a/tests/api_resources/devices/test_traffic_sessions.py b/tests/api_resources/devices/test_traffic_sessions.py index 458eddf1..01a2256a 100644 --- a/tests/api_resources/devices/test_traffic_sessions.py +++ b/tests/api_resources/devices/test_traffic_sessions.py @@ -27,7 +27,6 @@ class TestTrafficSessions: def test_method_create(self, client: Mobilerun) -> None: traffic_session = client.devices.traffic_sessions.create( device_id="deviceId", - idempotency_key="x", ) assert_matches_type(TrafficSessionCreateResponse, traffic_session, path=["response"]) @@ -36,7 +35,6 @@ def test_method_create(self, client: Mobilerun) -> None: def test_method_create_with_all_params(self, client: Mobilerun) -> None: traffic_session = client.devices.traffic_sessions.create( device_id="deviceId", - idempotency_key="x", expires_in_seconds=60, max_body_bytes=0, ) @@ -47,7 +45,6 @@ def test_method_create_with_all_params(self, client: Mobilerun) -> None: def test_raw_response_create(self, client: Mobilerun) -> None: response = client.devices.traffic_sessions.with_raw_response.create( device_id="deviceId", - idempotency_key="x", ) assert response.is_closed is True @@ -60,7 +57,6 @@ def test_raw_response_create(self, client: Mobilerun) -> None: def test_streaming_response_create(self, client: Mobilerun) -> None: with client.devices.traffic_sessions.with_streaming_response.create( device_id="deviceId", - idempotency_key="x", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -76,7 +72,6 @@ def test_path_params_create(self, client: Mobilerun) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `device_id` but received ''"): client.devices.traffic_sessions.with_raw_response.create( device_id="", - idempotency_key="x", ) @pytest.mark.skip(reason="Mock server tests are disabled") @@ -246,7 +241,6 @@ class TestAsyncTrafficSessions: async def test_method_create(self, async_client: AsyncMobilerun) -> None: traffic_session = await async_client.devices.traffic_sessions.create( device_id="deviceId", - idempotency_key="x", ) assert_matches_type(TrafficSessionCreateResponse, traffic_session, path=["response"]) @@ -255,7 +249,6 @@ async def test_method_create(self, async_client: AsyncMobilerun) -> None: async def test_method_create_with_all_params(self, async_client: AsyncMobilerun) -> None: traffic_session = await async_client.devices.traffic_sessions.create( device_id="deviceId", - idempotency_key="x", expires_in_seconds=60, max_body_bytes=0, ) @@ -266,7 +259,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncMobilerun) async def test_raw_response_create(self, async_client: AsyncMobilerun) -> None: response = await async_client.devices.traffic_sessions.with_raw_response.create( device_id="deviceId", - idempotency_key="x", ) assert response.is_closed is True @@ -279,7 +271,6 @@ async def test_raw_response_create(self, async_client: AsyncMobilerun) -> None: async def test_streaming_response_create(self, async_client: AsyncMobilerun) -> None: async with async_client.devices.traffic_sessions.with_streaming_response.create( device_id="deviceId", - idempotency_key="x", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -295,7 +286,6 @@ async def test_path_params_create(self, async_client: AsyncMobilerun) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `device_id` but received ''"): await async_client.devices.traffic_sessions.with_raw_response.create( device_id="", - idempotency_key="x", ) @pytest.mark.skip(reason="Mock server tests are disabled") diff --git a/tests/api_resources/test_devices.py b/tests/api_resources/test_devices.py index 19b6067c..86a3ce31 100644 --- a/tests/api_resources/test_devices.py +++ b/tests/api_resources/test_devices.py @@ -21,6 +21,8 @@ ) from mobilerun_sdk._utils import parse_datetime +# pyright: reportDeprecated=false + base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -207,13 +209,16 @@ def test_streaming_response_list(self, client: Mobilerun) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_count(self, client: Mobilerun) -> None: - device = client.devices.count() + with pytest.warns(DeprecationWarning): + device = client.devices.count() + assert_matches_type(DeviceCountResponse, device, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_raw_response_count(self, client: Mobilerun) -> None: - response = client.devices.with_raw_response.count() + with pytest.warns(DeprecationWarning): + response = client.devices.with_raw_response.count() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -223,12 +228,13 @@ def test_raw_response_count(self, client: Mobilerun) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_streaming_response_count(self, client: Mobilerun) -> None: - with client.devices.with_streaming_response.count() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" + with pytest.warns(DeprecationWarning): + with client.devices.with_streaming_response.count() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" - device = response.parse() - assert_matches_type(DeviceCountResponse, device, path=["response"]) + device = response.parse() + assert_matches_type(DeviceCountResponse, device, path=["response"]) assert cast(Any, response.is_closed) is True @@ -819,13 +825,16 @@ async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> No @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_count(self, async_client: AsyncMobilerun) -> None: - device = await async_client.devices.count() + with pytest.warns(DeprecationWarning): + device = await async_client.devices.count() + assert_matches_type(DeviceCountResponse, device, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_raw_response_count(self, async_client: AsyncMobilerun) -> None: - response = await async_client.devices.with_raw_response.count() + with pytest.warns(DeprecationWarning): + response = await async_client.devices.with_raw_response.count() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -835,12 +844,13 @@ async def test_raw_response_count(self, async_client: AsyncMobilerun) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_streaming_response_count(self, async_client: AsyncMobilerun) -> None: - async with async_client.devices.with_streaming_response.count() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" + with pytest.warns(DeprecationWarning): + async with async_client.devices.with_streaming_response.count() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" - device = await response.parse() - assert_matches_type(DeviceCountResponse, device, path=["response"]) + device = await response.parse() + assert_matches_type(DeviceCountResponse, device, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_files.py b/tests/api_resources/test_files.py index 47decef9..28417b3f 100644 --- a/tests/api_resources/test_files.py +++ b/tests/api_resources/test_files.py @@ -298,7 +298,6 @@ def test_method_upload_url_with_all_params(self, client: Mobilerun) -> None: mime_type="x", size_bytes=1, zone="user", - idempotency_key="x", ) assert_matches_type(FileUploadURLResponse, file, path=["response"]) @@ -612,7 +611,6 @@ async def test_method_upload_url_with_all_params(self, async_client: AsyncMobile mime_type="x", size_bytes=1, zone="user", - idempotency_key="x", ) assert_matches_type(FileUploadURLResponse, file, path=["response"]) diff --git a/tests/api_resources/test_mailboxes.py b/tests/api_resources/test_mailboxes.py index 45d04734..eae52bf1 100644 --- a/tests/api_resources/test_mailboxes.py +++ b/tests/api_resources/test_mailboxes.py @@ -31,16 +31,13 @@ class TestMailboxes: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_create(self, client: Mobilerun) -> None: - mailbox = client.mailboxes.create( - client_request_id="x", - ) + mailbox = client.mailboxes.create() assert_matches_type(MailboxCreateResponse, mailbox, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_create_with_all_params(self, client: Mobilerun) -> None: mailbox = client.mailboxes.create( - client_request_id="x", billing_preference="included", domain_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", label="label", @@ -51,9 +48,7 @@ def test_method_create_with_all_params(self, client: Mobilerun) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_raw_response_create(self, client: Mobilerun) -> None: - response = client.mailboxes.with_raw_response.create( - client_request_id="x", - ) + response = client.mailboxes.with_raw_response.create() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -63,9 +58,7 @@ def test_raw_response_create(self, client: Mobilerun) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_streaming_response_create(self, client: Mobilerun) -> None: - with client.mailboxes.with_streaming_response.create( - client_request_id="x", - ) as response: + with client.mailboxes.with_streaming_response.create() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -425,16 +418,13 @@ class TestAsyncMailboxes: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_create(self, async_client: AsyncMobilerun) -> None: - mailbox = await async_client.mailboxes.create( - client_request_id="x", - ) + mailbox = await async_client.mailboxes.create() assert_matches_type(MailboxCreateResponse, mailbox, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_create_with_all_params(self, async_client: AsyncMobilerun) -> None: mailbox = await async_client.mailboxes.create( - client_request_id="x", billing_preference="included", domain_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", label="label", @@ -445,9 +435,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncMobilerun) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_raw_response_create(self, async_client: AsyncMobilerun) -> None: - response = await async_client.mailboxes.with_raw_response.create( - client_request_id="x", - ) + response = await async_client.mailboxes.with_raw_response.create() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -457,9 +445,7 @@ async def test_raw_response_create(self, async_client: AsyncMobilerun) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_streaming_response_create(self, async_client: AsyncMobilerun) -> None: - async with async_client.mailboxes.with_streaming_response.create( - client_request_id="x", - ) as response: + async with async_client.mailboxes.with_streaming_response.create() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" diff --git a/tests/api_resources/test_numbers.py b/tests/api_resources/test_numbers.py index 957aab3c..94ecf75d 100644 --- a/tests/api_resources/test_numbers.py +++ b/tests/api_resources/test_numbers.py @@ -40,7 +40,6 @@ def test_method_create_with_all_params(self, client: Mobilerun) -> None: country="de", label="Support line", purpose="telegram", - idempotency_key="x", ) assert_matches_type(NumberCreateResponse, number, path=["response"]) @@ -348,7 +347,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncMobilerun) country="de", label="Support line", purpose="telegram", - idempotency_key="x", ) assert_matches_type(NumberCreateResponse, number, path=["response"]) diff --git a/tests/api_resources/test_tasks.py b/tests/api_resources/test_tasks.py index 8ff81d06..cb29c095 100644 --- a/tests/api_resources/test_tasks.py +++ b/tests/api_resources/test_tasks.py @@ -275,7 +275,6 @@ def test_method_run_with_all_params(self, client: Mobilerun) -> None: temperature=0, vision=True, vpn_country="US", - idempotency_key="x", ) assert_matches_type(TaskRunResponse, task, path=["response"]) @@ -720,7 +719,6 @@ async def test_method_run_with_all_params(self, async_client: AsyncMobilerun) -> temperature=0, vision=True, vpn_country="US", - idempotency_key="x", ) assert_matches_type(TaskRunResponse, task, path=["response"]) diff --git a/tests/api_resources/workflows/test_flows.py b/tests/api_resources/workflows/test_flows.py index eb527497..2e90302d 100644 --- a/tests/api_resources/workflows/test_flows.py +++ b/tests/api_resources/workflows/test_flows.py @@ -71,6 +71,12 @@ def test_method_create_with_all_params(self, client: Mobilerun) -> None: trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", cooldown_scope="flow", cooldown_seconds=0, + delivery={ + "destination": "one_drive", + "folder": "x", + "recording": {"filename": "x"}, + "screenshots": {}, + }, description="description", device_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], enabled=True, @@ -182,6 +188,12 @@ def test_method_update_with_all_params(self, client: Mobilerun) -> None: flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", cooldown_scope="flow", cooldown_seconds=0, + delivery={ + "destination": "one_drive", + "folder": "x", + "recording": {"filename": "x"}, + "screenshots": {}, + }, description="description", device_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], enabled=True, @@ -584,6 +596,12 @@ async def test_method_create_with_all_params(self, async_client: AsyncMobilerun) trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", cooldown_scope="flow", cooldown_seconds=0, + delivery={ + "destination": "one_drive", + "folder": "x", + "recording": {"filename": "x"}, + "screenshots": {}, + }, description="description", device_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], enabled=True, @@ -695,6 +713,12 @@ async def test_method_update_with_all_params(self, async_client: AsyncMobilerun) flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", cooldown_scope="flow", cooldown_seconds=0, + delivery={ + "destination": "one_drive", + "folder": "x", + "recording": {"filename": "x"}, + "screenshots": {}, + }, description="description", device_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], enabled=True, diff --git a/tests/api_resources/workflows/test_triggers.py b/tests/api_resources/workflows/test_triggers.py index 7149612e..c29dff8d 100644 --- a/tests/api_resources/workflows/test_triggers.py +++ b/tests/api_resources/workflows/test_triggers.py @@ -293,16 +293,6 @@ def test_method_fire(self, client: Mobilerun) -> None: ) assert_matches_type(TriggerFireResponse, trigger, path=["response"]) - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_fire_with_all_params(self, client: Mobilerun) -> None: - trigger = client.workflows.triggers.fire( - trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - payload={"foo": "bar"}, - invocation_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(TriggerFireResponse, trigger, path=["response"]) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_raw_response_fire(self, client: Mobilerun) -> None: @@ -615,16 +605,6 @@ async def test_method_fire(self, async_client: AsyncMobilerun) -> None: ) assert_matches_type(TriggerFireResponse, trigger, path=["response"]) - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_fire_with_all_params(self, async_client: AsyncMobilerun) -> None: - trigger = await async_client.workflows.triggers.fire( - trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - payload={"foo": "bar"}, - invocation_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(TriggerFireResponse, trigger, path=["response"]) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_raw_response_fire(self, async_client: AsyncMobilerun) -> None: diff --git a/tests/test_client.py b/tests/test_client.py index 9af846f0..95b93e25 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -709,6 +709,37 @@ class Model(BaseModel): assert isinstance(response, Model) assert response.foo == 2 + @pytest.mark.respx(base_url=base_url) + def test_idempotency_header_options(self, respx_mock: MockRouter, client: Mobilerun) -> None: + respx_mock.post("/foo").mock(return_value=httpx.Response(200, json={})) + + response = client.post("/foo", cast_to=httpx.Response) + + header = response.request.headers.get("Idempotency-Key") + assert header is not None + assert header.startswith("stainless-python-retry") + + # explicit header + response = client.post( + "/foo", + cast_to=httpx.Response, + options=make_request_options(extra_headers={"Idempotency-Key": "custom-key"}), + ) + assert response.request.headers.get("Idempotency-Key") == "custom-key" + + response = client.post( + "/foo", + cast_to=httpx.Response, + options=make_request_options(extra_headers={"idempotency-key": "custom-key"}), + ) + assert response.request.headers.get("Idempotency-Key") == "custom-key" + + # custom argument + response = client.post( + "/foo", cast_to=httpx.Response, options=make_request_options(idempotency_key="custom-key") + ) + assert response.request.headers.get("Idempotency-Key") == "custom-key" + def test_base_url_setter(self) -> None: client = Mobilerun(base_url="https://example.com/from_init", api_key=api_key, _strict_response_validation=True) assert client.base_url == "https://example.com/from_init/" @@ -1637,6 +1668,37 @@ class Model(BaseModel): assert isinstance(response, Model) assert response.foo == 2 + @pytest.mark.respx(base_url=base_url) + async def test_idempotency_header_options(self, respx_mock: MockRouter, async_client: AsyncMobilerun) -> None: + respx_mock.post("/foo").mock(return_value=httpx.Response(200, json={})) + + response = await async_client.post("/foo", cast_to=httpx.Response) + + header = response.request.headers.get("Idempotency-Key") + assert header is not None + assert header.startswith("stainless-python-retry") + + # explicit header + response = await async_client.post( + "/foo", + cast_to=httpx.Response, + options=make_request_options(extra_headers={"Idempotency-Key": "custom-key"}), + ) + assert response.request.headers.get("Idempotency-Key") == "custom-key" + + response = await async_client.post( + "/foo", + cast_to=httpx.Response, + options=make_request_options(extra_headers={"idempotency-key": "custom-key"}), + ) + assert response.request.headers.get("Idempotency-Key") == "custom-key" + + # custom argument + response = await async_client.post( + "/foo", cast_to=httpx.Response, options=make_request_options(idempotency_key="custom-key") + ) + assert response.request.headers.get("Idempotency-Key") == "custom-key" + async def test_base_url_setter(self) -> None: client = AsyncMobilerun( base_url="https://example.com/from_init", api_key=api_key, _strict_response_validation=True