From 2add42ec33a0accad90ab5afe8d27ce22629b871 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 26 May 2026 13:14:25 +0000 Subject: [PATCH 01/21] feat(api): api update --- .stats.yml | 4 ++-- src/mobilerun_sdk/resources/tasks/tasks.py | 16 ++++++++++++---- src/mobilerun_sdk/types/task.py | 2 ++ .../types/task_get_trajectory_response.py | 4 ++-- src/mobilerun_sdk/types/task_list_response.py | 2 ++ src/mobilerun_sdk/types/task_run_params.py | 4 +++- .../types/task_run_streamed_params.py | 4 +++- tests/api_resources/test_tasks.py | 4 ++++ 8 files changed, 30 insertions(+), 10 deletions(-) diff --git a/.stats.yml b/.stats.yml index 20e38d9..7efea32 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 104 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-9c5542353ace880640fb7e8946c5c8d008480abb8d1952595ba2ee9323aed724.yml -openapi_spec_hash: afa528f0921063291f66c56c6093f2ab +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-3b1ce47e9ff201fbf4382175970d440f505d04660ab9de1d93258f21a111188d.yml +openapi_spec_hash: 5a16b9c8eaf044d46459b382457c90b6 config_hash: 27cfddf59d8227e89667fa012952335c diff --git a/src/mobilerun_sdk/resources/tasks/tasks.py b/src/mobilerun_sdk/resources/tasks/tasks.py index 47d4c1a..b765073 100644 --- a/src/mobilerun_sdk/resources/tasks/tasks.py +++ b/src/mobilerun_sdk/resources/tasks/tasks.py @@ -270,6 +270,7 @@ def run( *, device_id: str, task: str, + accessibility: bool | Omit = omit, agent_id: int | Omit = omit, apps: SequenceNotStr[str] | Omit = omit, continue_on_failure: bool | Omit = omit, @@ -305,7 +306,7 @@ def run( display_id: The display ID of the device to run the task on. llm_model: The LLM model identifier to use for the task (e.g. - 'google/gemini-3.1-flash-lite-preview') + 'google/gemini-3.1-flash-lite') memory_namespace: Memory namespace for cross-task personalization @@ -325,6 +326,7 @@ def run( { "device_id": device_id, "task": task, + "accessibility": accessibility, "agent_id": agent_id, "apps": apps, "continue_on_failure": continue_on_failure, @@ -356,6 +358,7 @@ def run_streamed( *, device_id: str, task: str, + accessibility: bool | Omit = omit, agent_id: int | Omit = omit, apps: SequenceNotStr[str] | Omit = omit, continue_on_failure: bool | Omit = omit, @@ -390,7 +393,7 @@ def run_streamed( display_id: The display ID of the device to run the task on. llm_model: The LLM model identifier to use for the task (e.g. - 'google/gemini-3.1-flash-lite-preview') + 'google/gemini-3.1-flash-lite') memory_namespace: Memory namespace for cross-task personalization @@ -410,6 +413,7 @@ def run_streamed( { "device_id": device_id, "task": task, + "accessibility": accessibility, "agent_id": agent_id, "apps": apps, "continue_on_failure": continue_on_failure, @@ -733,6 +737,7 @@ async def run( *, device_id: str, task: str, + accessibility: bool | Omit = omit, agent_id: int | Omit = omit, apps: SequenceNotStr[str] | Omit = omit, continue_on_failure: bool | Omit = omit, @@ -768,7 +773,7 @@ async def run( display_id: The display ID of the device to run the task on. llm_model: The LLM model identifier to use for the task (e.g. - 'google/gemini-3.1-flash-lite-preview') + 'google/gemini-3.1-flash-lite') memory_namespace: Memory namespace for cross-task personalization @@ -788,6 +793,7 @@ async def run( { "device_id": device_id, "task": task, + "accessibility": accessibility, "agent_id": agent_id, "apps": apps, "continue_on_failure": continue_on_failure, @@ -819,6 +825,7 @@ async def run_streamed( *, device_id: str, task: str, + accessibility: bool | Omit = omit, agent_id: int | Omit = omit, apps: SequenceNotStr[str] | Omit = omit, continue_on_failure: bool | Omit = omit, @@ -853,7 +860,7 @@ async def run_streamed( display_id: The display ID of the device to run the task on. llm_model: The LLM model identifier to use for the task (e.g. - 'google/gemini-3.1-flash-lite-preview') + 'google/gemini-3.1-flash-lite') memory_namespace: Memory namespace for cross-task personalization @@ -873,6 +880,7 @@ async def run_streamed( { "device_id": device_id, "task": task, + "accessibility": accessibility, "agent_id": agent_id, "apps": apps, "continue_on_failure": continue_on_failure, diff --git a/src/mobilerun_sdk/types/task.py b/src/mobilerun_sdk/types/task.py index 4a0f115..cc4dab6 100644 --- a/src/mobilerun_sdk/types/task.py +++ b/src/mobilerun_sdk/types/task.py @@ -25,6 +25,8 @@ class Task(BaseModel): id: Optional[str] = None + accessibility: Optional[bool] = None + agent_id: Optional[int] = FieldInfo(alias="agentId", default=None) apps: Optional[List[str]] = None diff --git a/src/mobilerun_sdk/types/task_get_trajectory_response.py b/src/mobilerun_sdk/types/task_get_trajectory_response.py index 241c5b1..0405cf9 100644 --- a/src/mobilerun_sdk/types/task_get_trajectory_response.py +++ b/src/mobilerun_sdk/types/task_get_trajectory_response.py @@ -212,7 +212,7 @@ class TrajectoryTrajectoryManagerInputEvent(BaseModel): class TrajectoryTrajectoryManagerPlanEventData(BaseModel): - """Coordination event from ManagerAgent to DroidAgent. + """Coordination event from ManagerAgent to MobileAgent. Used for workflow step routing only (NOT streamed to frontend). For internal events with memory_update metadata, see ManagerPlanDetailsEvent. @@ -231,7 +231,7 @@ class TrajectoryTrajectoryManagerPlanEventData(BaseModel): class TrajectoryTrajectoryManagerPlanEvent(BaseModel): data: TrajectoryTrajectoryManagerPlanEventData - """Coordination event from ManagerAgent to DroidAgent. + """Coordination event from ManagerAgent to MobileAgent. Used for workflow step routing only (NOT streamed to frontend). For internal events with memory_update metadata, see ManagerPlanDetailsEvent. diff --git a/src/mobilerun_sdk/types/task_list_response.py b/src/mobilerun_sdk/types/task_list_response.py index 16c8d1d..12a8a4c 100644 --- a/src/mobilerun_sdk/types/task_list_response.py +++ b/src/mobilerun_sdk/types/task_list_response.py @@ -34,6 +34,8 @@ class Item(BaseModel): user_id: str = FieldInfo(alias="userId") + accessibility: Optional[bool] = None + agent_id: Optional[int] = FieldInfo(alias="agentId", default=None) apps: Optional[List[str]] = None diff --git a/src/mobilerun_sdk/types/task_run_params.py b/src/mobilerun_sdk/types/task_run_params.py index 3a91df8..8fc6144 100644 --- a/src/mobilerun_sdk/types/task_run_params.py +++ b/src/mobilerun_sdk/types/task_run_params.py @@ -18,6 +18,8 @@ class TaskRunParams(TypedDict, total=False): task: Required[str] + accessibility: bool + agent_id: Annotated[int, PropertyInfo(alias="agentId")] apps: SequenceNotStr[str] @@ -36,7 +38,7 @@ class TaskRunParams(TypedDict, total=False): llm_model: Annotated[str, PropertyInfo(alias="llmModel")] """The LLM model identifier to use for the task (e.g. - 'google/gemini-3.1-flash-lite-preview') + 'google/gemini-3.1-flash-lite') """ max_steps: Annotated[int, PropertyInfo(alias="maxSteps")] diff --git a/src/mobilerun_sdk/types/task_run_streamed_params.py b/src/mobilerun_sdk/types/task_run_streamed_params.py index 8c03add..1c0cfd6 100644 --- a/src/mobilerun_sdk/types/task_run_streamed_params.py +++ b/src/mobilerun_sdk/types/task_run_streamed_params.py @@ -18,6 +18,8 @@ class TaskRunStreamedParams(TypedDict, total=False): task: Required[str] + accessibility: bool + agent_id: Annotated[int, PropertyInfo(alias="agentId")] apps: SequenceNotStr[str] @@ -36,7 +38,7 @@ class TaskRunStreamedParams(TypedDict, total=False): llm_model: Annotated[str, PropertyInfo(alias="llmModel")] """The LLM model identifier to use for the task (e.g. - 'google/gemini-3.1-flash-lite-preview') + 'google/gemini-3.1-flash-lite') """ max_steps: Annotated[int, PropertyInfo(alias="maxSteps")] diff --git a/tests/api_resources/test_tasks.py b/tests/api_resources/test_tasks.py index 05fcfdd..5dafda7 100644 --- a/tests/api_resources/test_tasks.py +++ b/tests/api_resources/test_tasks.py @@ -249,6 +249,7 @@ def test_method_run_with_all_params(self, client: Mobilerun) -> None: task = client.tasks.run( device_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", task="x", + accessibility=True, agent_id=0, apps=["string"], continue_on_failure=True, @@ -317,6 +318,7 @@ def test_method_run_streamed_with_all_params(self, client: Mobilerun) -> None: task = client.tasks.run_streamed( device_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", task="x", + accessibility=True, agent_id=0, apps=["string"], continue_on_failure=True, @@ -688,6 +690,7 @@ async def test_method_run_with_all_params(self, async_client: AsyncMobilerun) -> task = await async_client.tasks.run( device_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", task="x", + accessibility=True, agent_id=0, apps=["string"], continue_on_failure=True, @@ -756,6 +759,7 @@ async def test_method_run_streamed_with_all_params(self, async_client: AsyncMobi task = await async_client.tasks.run_streamed( device_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", task="x", + accessibility=True, agent_id=0, apps=["string"], continue_on_failure=True, From 88c9ae09fe4979789e30e859bf9f7d57f39887c2 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 10:16:56 +0000 Subject: [PATCH 02/21] feat(api): manual updates --- .stats.yml | 6 +- api.md | 8 +- src/mobilerun_sdk/resources/apps.py | 81 +++++ src/mobilerun_sdk/resources/devices/apps.py | 158 +++++----- src/mobilerun_sdk/resources/hooks.py | 95 +++++- src/mobilerun_sdk/resources/proxies.py | 83 ++++- src/mobilerun_sdk/types/__init__.py | 5 + .../types/app_list_versions_response.py | 296 ++++++++++++++++++ src/mobilerun_sdk/types/hook_test_params.py | 13 + src/mobilerun_sdk/types/hook_test_response.py | 25 ++ .../types/proxy_lookup_params.py | 24 ++ .../types/proxy_lookup_response.py | 57 ++++ tests/api_resources/devices/test_apps.py | 162 +++++----- tests/api_resources/test_apps.py | 85 +++++ tests/api_resources/test_hooks.py | 103 ++++++ tests/api_resources/test_proxies.py | 113 +++++++ 16 files changed, 1148 insertions(+), 166 deletions(-) create mode 100644 src/mobilerun_sdk/types/app_list_versions_response.py create mode 100644 src/mobilerun_sdk/types/hook_test_params.py create mode 100644 src/mobilerun_sdk/types/hook_test_response.py create mode 100644 src/mobilerun_sdk/types/proxy_lookup_params.py create mode 100644 src/mobilerun_sdk/types/proxy_lookup_response.py diff --git a/.stats.yml b/.stats.yml index 7efea32..efc2936 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 104 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-3b1ce47e9ff201fbf4382175970d440f505d04660ab9de1d93258f21a111188d.yml +configured_endpoints: 107 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-93d2d2bea4782e8dfdcad4fa394b5c73b46593bfc11413aeb4c3415e0f09edc3.yml openapi_spec_hash: 5a16b9c8eaf044d46459b382457c90b6 -config_hash: 27cfddf59d8227e89667fa012952335c +config_hash: 86398ea1292189c25296aefb64d3137d diff --git a/api.md b/api.md index ccda2c7..4b2c442 100644 --- a/api.md +++ b/api.md @@ -37,6 +37,7 @@ from mobilerun_sdk.types import ( AppDeleteResponse, AppConfirmUploadResponse, AppCreateSignedUploadURLResponse, + AppListVersionsResponse, AppMarkFailedResponse, ) ``` @@ -48,6 +49,7 @@ Methods: - client.apps.delete(id) -> AppDeleteResponse - client.apps.confirm_upload(id) -> AppConfirmUploadResponse - client.apps.create_signed_upload_url(\*\*params) -> AppCreateSignedUploadURLResponse +- client.apps.list_versions(id) -> AppListVersionsResponse - client.apps.mark_failed(id) -> AppMarkFailedResponse # Carriers @@ -188,11 +190,11 @@ from mobilerun_sdk.types.devices import AppListResponse Methods: -- client.devices.apps.update(package_name, \*, device_id) -> None - client.devices.apps.list(device_id, \*\*params) -> Optional[AppListResponse] - client.devices.apps.delete(package_name, \*, device_id) -> None - client.devices.apps.install(device_id, \*\*params) -> None - client.devices.apps.start(package_name, \*, device_id, \*\*params) -> None +- client.devices.apps.stop(package_name, \*, device_id) -> None ## Esim @@ -356,6 +358,7 @@ from mobilerun_sdk.types import ( HookGetSampleDataResponse, HookPerformResponse, HookSubscribeResponse, + HookTestResponse, HookUnsubscribeResponse, ) ``` @@ -368,6 +371,7 @@ Methods: - client.hooks.get_sample_data() -> HookGetSampleDataResponse - client.hooks.perform(\*\*params) -> HookPerformResponse - client.hooks.subscribe(\*\*params) -> HookSubscribeResponse +- client.hooks.test(hook_id, \*\*params) -> HookTestResponse - client.hooks.unsubscribe(hook_id) -> HookUnsubscribeResponse # Models @@ -410,6 +414,7 @@ from mobilerun_sdk.types import ( ProxyUpdateResponse, ProxyListResponse, ProxyDeleteResponse, + ProxyLookupResponse, ) ``` @@ -420,6 +425,7 @@ Methods: - client.proxies.update(proxy_id, \*\*params) -> ProxyUpdateResponse - client.proxies.list(\*\*params) -> ProxyListResponse - client.proxies.delete(proxy_id) -> ProxyDeleteResponse +- client.proxies.lookup(\*\*params) -> ProxyLookupResponse # Tasks diff --git a/src/mobilerun_sdk/resources/apps.py b/src/mobilerun_sdk/resources/apps.py index 2587290..3e2bb8f 100644 --- a/src/mobilerun_sdk/resources/apps.py +++ b/src/mobilerun_sdk/resources/apps.py @@ -23,6 +23,7 @@ from ..types.app_delete_response import AppDeleteResponse from ..types.app_retrieve_response import AppRetrieveResponse from ..types.app_mark_failed_response import AppMarkFailedResponse +from ..types.app_list_versions_response import AppListVersionsResponse from ..types.app_confirm_upload_response import AppConfirmUploadResponse from ..types.app_create_signed_upload_url_response import AppCreateSignedUploadURLResponse @@ -266,6 +267,40 @@ def create_signed_upload_url( cast_to=AppCreateSignedUploadURLResponse, ) + def list_versions( + self, + id: str, + *, + # 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, + ) -> AppListVersionsResponse: + """ + Retrieves all versions of an app visible to the user (own uploads + system + versions) + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._get( + path_template("/apps/{id}/versions", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AppListVersionsResponse, + ) + def mark_failed( self, id: str, @@ -537,6 +572,40 @@ async def create_signed_upload_url( cast_to=AppCreateSignedUploadURLResponse, ) + async def list_versions( + self, + id: str, + *, + # 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, + ) -> AppListVersionsResponse: + """ + Retrieves all versions of an app visible to the user (own uploads + system + versions) + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._get( + path_template("/apps/{id}/versions", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AppListVersionsResponse, + ) + async def mark_failed( self, id: str, @@ -590,6 +659,9 @@ def __init__(self, apps: AppsResource) -> None: self.create_signed_upload_url = to_raw_response_wrapper( apps.create_signed_upload_url, ) + self.list_versions = to_raw_response_wrapper( + apps.list_versions, + ) self.mark_failed = to_raw_response_wrapper( apps.mark_failed, ) @@ -614,6 +686,9 @@ def __init__(self, apps: AsyncAppsResource) -> None: self.create_signed_upload_url = async_to_raw_response_wrapper( apps.create_signed_upload_url, ) + self.list_versions = async_to_raw_response_wrapper( + apps.list_versions, + ) self.mark_failed = async_to_raw_response_wrapper( apps.mark_failed, ) @@ -638,6 +713,9 @@ def __init__(self, apps: AppsResource) -> None: self.create_signed_upload_url = to_streamed_response_wrapper( apps.create_signed_upload_url, ) + self.list_versions = to_streamed_response_wrapper( + apps.list_versions, + ) self.mark_failed = to_streamed_response_wrapper( apps.mark_failed, ) @@ -662,6 +740,9 @@ def __init__(self, apps: AsyncAppsResource) -> None: self.create_signed_upload_url = async_to_streamed_response_wrapper( apps.create_signed_upload_url, ) + self.list_versions = async_to_streamed_response_wrapper( + apps.list_versions, + ) self.mark_failed = async_to_streamed_response_wrapper( apps.mark_failed, ) diff --git a/src/mobilerun_sdk/resources/devices/apps.py b/src/mobilerun_sdk/resources/devices/apps.py index 4541bb5..dbd6985 100644 --- a/src/mobilerun_sdk/resources/devices/apps.py +++ b/src/mobilerun_sdk/resources/devices/apps.py @@ -44,50 +44,6 @@ def with_streaming_response(self) -> AppsResourceWithStreamingResponse: """ return AppsResourceWithStreamingResponse(self) - def update( - self, - package_name: str, - *, - device_id: str, - x_device_display_id: int | 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, - ) -> None: - """ - Stop app - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not device_id: - raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") - if not package_name: - raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - extra_headers = { - **strip_not_given( - {"X-Device-Display-ID": str(x_device_display_id) if is_given(x_device_display_id) else not_given} - ), - **(extra_headers or {}), - } - return self._patch( - 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 - ), - cast_to=NoneType, - ) - def list( self, device_id: str, @@ -337,28 +293,7 @@ def start( cast_to=NoneType, ) - -class AsyncAppsResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncAppsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return AsyncAppsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncAppsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return AsyncAppsResourceWithStreamingResponse(self) - - async def update( + def stop( self, package_name: str, *, @@ -394,7 +329,7 @@ async def update( ), **(extra_headers or {}), } - return await self._patch( + return self._patch( 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 @@ -402,6 +337,27 @@ async def update( cast_to=NoneType, ) + +class AsyncAppsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncAppsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncAppsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAppsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncAppsResourceWithStreamingResponse(self) + async def list( self, device_id: str, @@ -651,14 +607,55 @@ async def start( cast_to=NoneType, ) + async def stop( + self, + package_name: str, + *, + device_id: str, + x_device_display_id: int | 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, + ) -> None: + """ + Stop app + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not device_id: + raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") + if not package_name: + raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + extra_headers = { + **strip_not_given( + {"X-Device-Display-ID": str(x_device_display_id) if is_given(x_device_display_id) else not_given} + ), + **(extra_headers or {}), + } + return await self._patch( + 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 + ), + cast_to=NoneType, + ) + class AppsResourceWithRawResponse: def __init__(self, apps: AppsResource) -> None: self._apps = apps - self.update = to_raw_response_wrapper( - apps.update, - ) self.list = to_raw_response_wrapper( apps.list, ) @@ -671,15 +668,15 @@ def __init__(self, apps: AppsResource) -> None: self.start = to_raw_response_wrapper( apps.start, ) + self.stop = to_raw_response_wrapper( + apps.stop, + ) class AsyncAppsResourceWithRawResponse: def __init__(self, apps: AsyncAppsResource) -> None: self._apps = apps - self.update = async_to_raw_response_wrapper( - apps.update, - ) self.list = async_to_raw_response_wrapper( apps.list, ) @@ -692,15 +689,15 @@ def __init__(self, apps: AsyncAppsResource) -> None: self.start = async_to_raw_response_wrapper( apps.start, ) + self.stop = async_to_raw_response_wrapper( + apps.stop, + ) class AppsResourceWithStreamingResponse: def __init__(self, apps: AppsResource) -> None: self._apps = apps - self.update = to_streamed_response_wrapper( - apps.update, - ) self.list = to_streamed_response_wrapper( apps.list, ) @@ -713,15 +710,15 @@ def __init__(self, apps: AppsResource) -> None: self.start = to_streamed_response_wrapper( apps.start, ) + self.stop = to_streamed_response_wrapper( + apps.stop, + ) class AsyncAppsResourceWithStreamingResponse: def __init__(self, apps: AsyncAppsResource) -> None: self._apps = apps - self.update = async_to_streamed_response_wrapper( - apps.update, - ) self.list = async_to_streamed_response_wrapper( apps.list, ) @@ -734,3 +731,6 @@ def __init__(self, apps: AsyncAppsResource) -> None: self.start = async_to_streamed_response_wrapper( apps.start, ) + self.stop = async_to_streamed_response_wrapper( + apps.stop, + ) diff --git a/src/mobilerun_sdk/resources/hooks.py b/src/mobilerun_sdk/resources/hooks.py index 185b05e..6f3c43b 100644 --- a/src/mobilerun_sdk/resources/hooks.py +++ b/src/mobilerun_sdk/resources/hooks.py @@ -7,7 +7,7 @@ import httpx -from ..types import hook_list_params, hook_update_params, hook_perform_params, hook_subscribe_params +from ..types import hook_list_params, hook_test_params, hook_update_params, hook_perform_params, hook_subscribe_params from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given from .._utils import path_template, maybe_transform, async_maybe_transform from .._compat import cached_property @@ -20,6 +20,7 @@ ) from .._base_client import make_request_options from ..types.hook_list_response import HookListResponse +from ..types.hook_test_response import HookTestResponse from ..types.hook_update_response import HookUpdateResponse from ..types.hook_perform_response import HookPerformResponse from ..types.hook_retrieve_response import HookRetrieveResponse @@ -277,6 +278,46 @@ def subscribe( cast_to=HookSubscribeResponse, ) + def test( + self, + hook_id: str, + *, + event: Optional[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, + ) -> HookTestResponse: + """ + Send a test event to a webhook endpoint. + + Delivers a sample payload to the hook's URL with a single attempt (no retries) + for fast feedback. + + Args: + event: Event type to simulate (default: completed) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not hook_id: + raise ValueError(f"Expected a non-empty value for `hook_id` but received {hook_id!r}") + return self._post( + path_template("/hooks/{hook_id}/test", hook_id=hook_id), + body=maybe_transform({"event": event}, hook_test_params.HookTestParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=HookTestResponse, + ) + def unsubscribe( self, hook_id: str, @@ -560,6 +601,46 @@ async def subscribe( cast_to=HookSubscribeResponse, ) + async def test( + self, + hook_id: str, + *, + event: Optional[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, + ) -> HookTestResponse: + """ + Send a test event to a webhook endpoint. + + Delivers a sample payload to the hook's URL with a single attempt (no retries) + for fast feedback. + + Args: + event: Event type to simulate (default: completed) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not hook_id: + raise ValueError(f"Expected a non-empty value for `hook_id` but received {hook_id!r}") + return await self._post( + path_template("/hooks/{hook_id}/test", hook_id=hook_id), + body=await async_maybe_transform({"event": event}, hook_test_params.HookTestParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=HookTestResponse, + ) + async def unsubscribe( self, hook_id: str, @@ -618,6 +699,9 @@ def __init__(self, hooks: HooksResource) -> None: self.subscribe = to_raw_response_wrapper( hooks.subscribe, ) + self.test = to_raw_response_wrapper( + hooks.test, + ) self.unsubscribe = to_raw_response_wrapper( hooks.unsubscribe, ) @@ -645,6 +729,9 @@ def __init__(self, hooks: AsyncHooksResource) -> None: self.subscribe = async_to_raw_response_wrapper( hooks.subscribe, ) + self.test = async_to_raw_response_wrapper( + hooks.test, + ) self.unsubscribe = async_to_raw_response_wrapper( hooks.unsubscribe, ) @@ -672,6 +759,9 @@ def __init__(self, hooks: HooksResource) -> None: self.subscribe = to_streamed_response_wrapper( hooks.subscribe, ) + self.test = to_streamed_response_wrapper( + hooks.test, + ) self.unsubscribe = to_streamed_response_wrapper( hooks.unsubscribe, ) @@ -699,6 +789,9 @@ def __init__(self, hooks: AsyncHooksResource) -> None: self.subscribe = async_to_streamed_response_wrapper( hooks.subscribe, ) + self.test = async_to_streamed_response_wrapper( + hooks.test, + ) self.unsubscribe = async_to_streamed_response_wrapper( hooks.unsubscribe, ) diff --git a/src/mobilerun_sdk/resources/proxies.py b/src/mobilerun_sdk/resources/proxies.py index cd4235f..4abd363 100644 --- a/src/mobilerun_sdk/resources/proxies.py +++ b/src/mobilerun_sdk/resources/proxies.py @@ -6,7 +6,7 @@ import httpx -from ..types import proxy_list_params, proxy_create_params, proxy_update_params +from ..types import proxy_list_params, proxy_create_params, proxy_lookup_params, proxy_update_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given from .._utils import path_template, required_args, maybe_transform, async_maybe_transform from .._compat import cached_property @@ -21,6 +21,7 @@ from ..types.proxy_list_response import ProxyListResponse from ..types.proxy_create_response import ProxyCreateResponse from ..types.proxy_delete_response import ProxyDeleteResponse +from ..types.proxy_lookup_response import ProxyLookupResponse from ..types.proxy_update_response import ProxyUpdateResponse from ..types.proxy_retrieve_response import ProxyRetrieveResponse @@ -349,6 +350,40 @@ def delete( cast_to=ProxyDeleteResponse, ) + def lookup( + self, + *, + socks5: proxy_lookup_params.Socks5, + # 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, + ) -> ProxyLookupResponse: + """ + Lookup proxy location + + Args: + socks5: SOCKS5 proxy configuration. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=ProxyLookupResponse, + ) + class AsyncProxiesResource(AsyncAPIResource): """Network Proxies""" @@ -672,6 +707,40 @@ async def delete( cast_to=ProxyDeleteResponse, ) + async def lookup( + self, + *, + socks5: proxy_lookup_params.Socks5, + # 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, + ) -> ProxyLookupResponse: + """ + Lookup proxy location + + Args: + socks5: SOCKS5 proxy configuration. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=ProxyLookupResponse, + ) + class ProxiesResourceWithRawResponse: def __init__(self, proxies: ProxiesResource) -> None: @@ -692,6 +761,9 @@ def __init__(self, proxies: ProxiesResource) -> None: self.delete = to_raw_response_wrapper( proxies.delete, ) + self.lookup = to_raw_response_wrapper( + proxies.lookup, + ) class AsyncProxiesResourceWithRawResponse: @@ -713,6 +785,9 @@ def __init__(self, proxies: AsyncProxiesResource) -> None: self.delete = async_to_raw_response_wrapper( proxies.delete, ) + self.lookup = async_to_raw_response_wrapper( + proxies.lookup, + ) class ProxiesResourceWithStreamingResponse: @@ -734,6 +809,9 @@ def __init__(self, proxies: ProxiesResource) -> None: self.delete = to_streamed_response_wrapper( proxies.delete, ) + self.lookup = to_streamed_response_wrapper( + proxies.lookup, + ) class AsyncProxiesResourceWithStreamingResponse: @@ -755,3 +833,6 @@ def __init__(self, proxies: AsyncProxiesResource) -> None: self.delete = async_to_streamed_response_wrapper( proxies.delete, ) + self.lookup = async_to_streamed_response_wrapper( + proxies.lookup, + ) diff --git a/src/mobilerun_sdk/types/__init__.py b/src/mobilerun_sdk/types/__init__.py index ba767ee..abff37b 100644 --- a/src/mobilerun_sdk/types/__init__.py +++ b/src/mobilerun_sdk/types/__init__.py @@ -22,12 +22,14 @@ from .app_list_params import AppListParams as AppListParams from .task_run_params import TaskRunParams as TaskRunParams from .hook_list_params import HookListParams as HookListParams +from .hook_test_params import HookTestParams as HookTestParams from .task_list_params import TaskListParams as TaskListParams from .app_list_response import AppListResponse as AppListResponse from .proxy_list_params import ProxyListParams as ProxyListParams from .task_run_response import TaskRunResponse as TaskRunResponse from .device_list_params import DeviceListParams as DeviceListParams from .hook_list_response import HookListResponse as HookListResponse +from .hook_test_response import HookTestResponse as HookTestResponse from .hook_update_params import HookUpdateParams as HookUpdateParams from .task_list_response import TaskListResponse as TaskListResponse from .task_stop_response import TaskStopResponse as TaskStopResponse @@ -40,6 +42,7 @@ from .profile_list_params import ProfileListParams as ProfileListParams from .proxy_create_params import ProxyCreateParams as ProxyCreateParams from .proxy_list_response import ProxyListResponse as ProxyListResponse +from .proxy_lookup_params import ProxyLookupParams as ProxyLookupParams from .proxy_update_params import ProxyUpdateParams as ProxyUpdateParams from .device_create_params import DeviceCreateParams as DeviceCreateParams from .device_list_response import DeviceListResponse as DeviceListResponse @@ -57,6 +60,7 @@ from .profile_update_params import ProfileUpdateParams as ProfileUpdateParams from .proxy_create_response import ProxyCreateResponse as ProxyCreateResponse from .proxy_delete_response import ProxyDeleteResponse as ProxyDeleteResponse +from .proxy_lookup_response import ProxyLookupResponse as ProxyLookupResponse from .proxy_update_response import ProxyUpdateResponse as ProxyUpdateResponse from .credential_list_params import CredentialListParams as CredentialListParams from .device_set_name_params import DeviceSetNameParams as DeviceSetNameParams @@ -78,6 +82,7 @@ from .carrier_retrieve_response import CarrierRetrieveResponse as CarrierRetrieveResponse from .hook_unsubscribe_response import HookUnsubscribeResponse as HookUnsubscribeResponse from .package_credentials_param import PackageCredentialsParam as PackageCredentialsParam +from .app_list_versions_response import AppListVersionsResponse as AppListVersionsResponse from .task_send_message_response import TaskSendMessageResponse as TaskSendMessageResponse from .app_confirm_upload_response import AppConfirmUploadResponse as AppConfirmUploadResponse from .device_fingerprint_response import DeviceFingerprintResponse as DeviceFingerprintResponse diff --git a/src/mobilerun_sdk/types/app_list_versions_response.py b/src/mobilerun_sdk/types/app_list_versions_response.py new file mode 100644 index 0000000..130eab8 --- /dev/null +++ b/src/mobilerun_sdk/types/app_list_versions_response.py @@ -0,0 +1,296 @@ +# 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__ = ["AppListVersionsResponse", "Data"] + + +class Data(BaseModel): + id: str + + app_id: str = FieldInfo(alias="appId") + + country: Literal[ + "AF", + "AL", + "DZ", + "AS", + "AD", + "AO", + "AI", + "AQ", + "AG", + "AR", + "AM", + "AW", + "AP", + "AU", + "AT", + "AZ", + "BS", + "BH", + "BD", + "BB", + "BY", + "BE", + "BZ", + "BJ", + "BM", + "BT", + "BO", + "BQ", + "BA", + "BW", + "BV", + "BR", + "IO", + "BN", + "BG", + "BF", + "BI", + "KH", + "CM", + "CA", + "CV", + "KY", + "CF", + "TD", + "CL", + "CN", + "CX", + "CC", + "CO", + "KM", + "CG", + "CD", + "CK", + "CR", + "HR", + "CU", + "CW", + "CY", + "CZ", + "CI", + "DK", + "DJ", + "DM", + "DO", + "EC", + "EG", + "SV", + "GQ", + "ER", + "EE", + "ET", + "FK", + "FO", + "FJ", + "FI", + "FR", + "GF", + "PF", + "TF", + "GA", + "GM", + "GE", + "DE", + "GH", + "GI", + "GR", + "GL", + "GD", + "GP", + "GU", + "GT", + "GG", + "GN", + "GW", + "GY", + "HT", + "HM", + "VA", + "HN", + "HK", + "HU", + "IS", + "IN", + "ID", + "IR", + "IQ", + "IE", + "IM", + "IL", + "IT", + "JM", + "JP", + "JE", + "JO", + "KZ", + "KE", + "KI", + "KR", + "KW", + "KG", + "LA", + "LV", + "LB", + "LS", + "LR", + "LY", + "LI", + "LT", + "LU", + "MO", + "MG", + "MW", + "MY", + "MV", + "ML", + "MT", + "MH", + "MQ", + "MR", + "MU", + "YT", + "MX", + "FM", + "MD", + "MC", + "MN", + "ME", + "MS", + "MA", + "MZ", + "MM", + "NA", + "NR", + "NP", + "NL", + "AN", + "NC", + "NZ", + "NI", + "NE", + "NG", + "NU", + "NF", + "KP", + "MK", + "MP", + "NO", + "OM", + "PK", + "PW", + "PS", + "PA", + "PG", + "PY", + "PE", + "PH", + "PN", + "PL", + "PT", + "PR", + "QA", + "RE", + "RO", + "RU", + "RW", + "BL", + "SH", + "KN", + "LC", + "MF", + "PM", + "VC", + "WS", + "SM", + "ST", + "SA", + "SN", + "RS", + "CS", + "SC", + "SL", + "SG", + "SX", + "SK", + "SI", + "SB", + "SO", + "ZA", + "GS", + "SS", + "ES", + "LK", + "SD", + "SR", + "SJ", + "SZ", + "SE", + "CH", + "SY", + "TW", + "TJ", + "TZ", + "TH", + "TL", + "TG", + "TK", + "TO", + "TT", + "TN", + "TR", + "TM", + "TC", + "TV", + "UG", + "UA", + "AE", + "GB", + "US", + "UM", + "UY", + "UZ", + "VU", + "VE", + "VN", + "VG", + "VI", + "WF", + "EH", + "YE", + "ZM", + "ZW", + "AX", + ] + + created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None) + + queued_at: Optional[datetime] = FieldInfo(alias="queuedAt", default=None) + + size_bytes: Optional[int] = FieldInfo(alias="sizeBytes", default=None) + + source: Literal["user", "system", "portal"] + + status: Literal["queued", "available", "failed"] + + target_sdk: Optional[int] = FieldInfo(alias="targetSdk", default=None) + + updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None) + + user_id: Optional[str] = FieldInfo(alias="userId", default=None) + + version_code: int = FieldInfo(alias="versionCode") + + version_name: str = FieldInfo(alias="versionName") + + +class AppListVersionsResponse(BaseModel): + data: List[Data] diff --git a/src/mobilerun_sdk/types/hook_test_params.py b/src/mobilerun_sdk/types/hook_test_params.py new file mode 100644 index 0000000..af5edff --- /dev/null +++ b/src/mobilerun_sdk/types/hook_test_params.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import TypedDict + +__all__ = ["HookTestParams"] + + +class HookTestParams(TypedDict, total=False): + event: Optional[str] + """Event type to simulate (default: completed)""" diff --git a/src/mobilerun_sdk/types/hook_test_response.py b/src/mobilerun_sdk/types/hook_test_response.py new file mode 100644 index 0000000..8d22bab --- /dev/null +++ b/src/mobilerun_sdk/types/hook_test_response.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["HookTestResponse"] + + +class HookTestResponse(BaseModel): + """Response after attempting test delivery.""" + + id: str + """The hook ID""" + + success: bool + """Whether delivery succeeded (2xx)""" + + error: Optional[str] = None + """Error message if delivery failed""" + + status_code: Optional[int] = FieldInfo(alias="statusCode", default=None) + """HTTP status from target""" diff --git a/src/mobilerun_sdk/types/proxy_lookup_params.py b/src/mobilerun_sdk/types/proxy_lookup_params.py new file mode 100644 index 0000000..43b7464 --- /dev/null +++ b/src/mobilerun_sdk/types/proxy_lookup_params.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["ProxyLookupParams", "Socks5"] + + +class ProxyLookupParams(TypedDict, total=False): + socks5: Required[Socks5] + """SOCKS5 proxy configuration.""" + + +class Socks5(TypedDict, total=False): + """SOCKS5 proxy configuration.""" + + host: Required[str] + + port: Required[int] + + password: str + + user: str diff --git a/src/mobilerun_sdk/types/proxy_lookup_response.py b/src/mobilerun_sdk/types/proxy_lookup_response.py new file mode 100644 index 0000000..6e4e88f --- /dev/null +++ b/src/mobilerun_sdk/types/proxy_lookup_response.py @@ -0,0 +1,57 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["ProxyLookupResponse", "Carrier"] + + +class Carrier(BaseModel): + """Mobile carrier information.""" + + mcc: Optional[str] = None + """Mobile Country Code.""" + + mnc: Optional[str] = None + """Mobile Network Code.""" + + name: Optional[str] = None + """Carrier name.""" + + +class ProxyLookupResponse(BaseModel): + ip: str + """IP address of the proxy.""" + + is_mobile: bool = FieldInfo(alias="isMobile") + """Whether the IP is a mobile connection.""" + + latitude: float + """Latitude of the proxy.""" + + longitude: float + """Longitude of the proxy.""" + + schema_: Optional[str] = FieldInfo(alias="$schema", default=None) + """A URL to the JSON Schema for this object.""" + + carrier: Optional[Carrier] = None + """Mobile carrier information.""" + + city: Optional[str] = None + """City of the proxy.""" + + country: Optional[str] = None + """Country of the proxy.""" + + country_code: Optional[str] = FieldInfo(alias="countryCode", default=None) + """ISO country code.""" + + region: Optional[str] = None + """Region of the proxy.""" + + timezone: Optional[str] = None + """Timezone of the proxy.""" diff --git a/tests/api_resources/devices/test_apps.py b/tests/api_resources/devices/test_apps.py index 87c426d..5f86d32 100644 --- a/tests/api_resources/devices/test_apps.py +++ b/tests/api_resources/devices/test_apps.py @@ -17,68 +17,6 @@ class TestApps: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_update(self, client: Mobilerun) -> None: - app = client.devices.apps.update( - package_name="packageName", - device_id="deviceId", - ) - assert app is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_update_with_all_params(self, client: Mobilerun) -> None: - app = client.devices.apps.update( - package_name="packageName", - device_id="deviceId", - x_device_display_id=0, - ) - assert app is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_update(self, client: Mobilerun) -> None: - response = client.devices.apps.with_raw_response.update( - package_name="packageName", - device_id="deviceId", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = response.parse() - assert app is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_update(self, client: Mobilerun) -> None: - with client.devices.apps.with_streaming_response.update( - package_name="packageName", - device_id="deviceId", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - app = response.parse() - assert app is None - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_update(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `device_id` but received ''"): - client.devices.apps.with_raw_response.update( - package_name="packageName", - device_id="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - client.devices.apps.with_raw_response.update( - package_name="", - device_id="deviceId", - ) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_list(self, client: Mobilerun) -> None: @@ -371,16 +309,10 @@ def test_path_params_start(self, client: Mobilerun) -> None: device_id="deviceId", ) - -class TestAsyncApps: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_update(self, async_client: AsyncMobilerun) -> None: - app = await async_client.devices.apps.update( + def test_method_stop(self, client: Mobilerun) -> None: + app = client.devices.apps.stop( package_name="packageName", device_id="deviceId", ) @@ -388,8 +320,8 @@ async def test_method_update(self, async_client: AsyncMobilerun) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_update_with_all_params(self, async_client: AsyncMobilerun) -> None: - app = await async_client.devices.apps.update( + def test_method_stop_with_all_params(self, client: Mobilerun) -> None: + app = client.devices.apps.stop( package_name="packageName", device_id="deviceId", x_device_display_id=0, @@ -398,47 +330,53 @@ async def test_method_update_with_all_params(self, async_client: AsyncMobilerun) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_update(self, async_client: AsyncMobilerun) -> None: - response = await async_client.devices.apps.with_raw_response.update( + def test_raw_response_stop(self, client: Mobilerun) -> None: + response = client.devices.apps.with_raw_response.stop( package_name="packageName", device_id="deviceId", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = await response.parse() + app = response.parse() assert app is None @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_update(self, async_client: AsyncMobilerun) -> None: - async with async_client.devices.apps.with_streaming_response.update( + def test_streaming_response_stop(self, client: Mobilerun) -> None: + with client.devices.apps.with_streaming_response.stop( package_name="packageName", device_id="deviceId", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = await response.parse() + app = response.parse() assert app is None assert cast(Any, response.is_closed) is True @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_path_params_update(self, async_client: AsyncMobilerun) -> None: + def test_path_params_stop(self, client: Mobilerun) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `device_id` but received ''"): - await async_client.devices.apps.with_raw_response.update( + client.devices.apps.with_raw_response.stop( package_name="packageName", device_id="", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - await async_client.devices.apps.with_raw_response.update( + client.devices.apps.with_raw_response.stop( package_name="", device_id="deviceId", ) + +class TestAsyncApps: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_list(self, async_client: AsyncMobilerun) -> None: @@ -730,3 +668,65 @@ async def test_path_params_start(self, async_client: AsyncMobilerun) -> None: package_name="", device_id="deviceId", ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_stop(self, async_client: AsyncMobilerun) -> None: + app = await async_client.devices.apps.stop( + package_name="packageName", + device_id="deviceId", + ) + assert app is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_stop_with_all_params(self, async_client: AsyncMobilerun) -> None: + app = await async_client.devices.apps.stop( + package_name="packageName", + device_id="deviceId", + x_device_display_id=0, + ) + assert app is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_stop(self, async_client: AsyncMobilerun) -> None: + response = await async_client.devices.apps.with_raw_response.stop( + package_name="packageName", + device_id="deviceId", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = await response.parse() + assert app is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_stop(self, async_client: AsyncMobilerun) -> None: + async with async_client.devices.apps.with_streaming_response.stop( + package_name="packageName", + device_id="deviceId", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = await response.parse() + assert app is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_stop(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.apps.with_raw_response.stop( + package_name="packageName", + device_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): + await async_client.devices.apps.with_raw_response.stop( + package_name="", + device_id="deviceId", + ) diff --git a/tests/api_resources/test_apps.py b/tests/api_resources/test_apps.py index 887a5ee..7fd88df 100644 --- a/tests/api_resources/test_apps.py +++ b/tests/api_resources/test_apps.py @@ -14,6 +14,7 @@ AppDeleteResponse, AppRetrieveResponse, AppMarkFailedResponse, + AppListVersionsResponse, AppConfirmUploadResponse, AppCreateSignedUploadURLResponse, ) @@ -280,6 +281,48 @@ def test_streaming_response_create_signed_upload_url(self, client: Mobilerun) -> assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_versions(self, client: Mobilerun) -> None: + app = client.apps.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(AppListVersionsResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list_versions(self, client: Mobilerun) -> None: + response = client.apps.with_raw_response.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = response.parse() + assert_matches_type(AppListVersionsResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list_versions(self, client: Mobilerun) -> None: + with client.apps.with_streaming_response.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = response.parse() + assert_matches_type(AppListVersionsResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_list_versions(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.apps.with_raw_response.list_versions( + "", + ) + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_mark_failed(self, client: Mobilerun) -> None: @@ -584,6 +627,48 @@ async def test_streaming_response_create_signed_upload_url(self, async_client: A assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_versions(self, async_client: AsyncMobilerun) -> None: + app = await async_client.apps.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(AppListVersionsResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list_versions(self, async_client: AsyncMobilerun) -> None: + response = await async_client.apps.with_raw_response.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = await response.parse() + assert_matches_type(AppListVersionsResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list_versions(self, async_client: AsyncMobilerun) -> None: + async with async_client.apps.with_streaming_response.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = await response.parse() + assert_matches_type(AppListVersionsResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_list_versions(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.apps.with_raw_response.list_versions( + "", + ) + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_mark_failed(self, async_client: AsyncMobilerun) -> None: diff --git a/tests/api_resources/test_hooks.py b/tests/api_resources/test_hooks.py index 5d9a9d9..21548ab 100644 --- a/tests/api_resources/test_hooks.py +++ b/tests/api_resources/test_hooks.py @@ -11,6 +11,7 @@ from mobilerun_sdk import Mobilerun, AsyncMobilerun from mobilerun_sdk.types import ( HookListResponse, + HookTestResponse, HookUpdateResponse, HookPerformResponse, HookRetrieveResponse, @@ -264,6 +265,57 @@ def test_streaming_response_subscribe(self, client: Mobilerun) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_test(self, client: Mobilerun) -> None: + hook = client.hooks.test( + hook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(HookTestResponse, hook, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_test_with_all_params(self, client: Mobilerun) -> None: + hook = client.hooks.test( + hook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + event="event", + ) + assert_matches_type(HookTestResponse, hook, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_test(self, client: Mobilerun) -> None: + response = client.hooks.with_raw_response.test( + hook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + hook = response.parse() + assert_matches_type(HookTestResponse, hook, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_test(self, client: Mobilerun) -> None: + with client.hooks.with_streaming_response.test( + hook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + hook = response.parse() + assert_matches_type(HookTestResponse, hook, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_test(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `hook_id` but received ''"): + client.hooks.with_raw_response.test( + hook_id="", + ) + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_unsubscribe(self, client: Mobilerun) -> None: @@ -551,6 +603,57 @@ async def test_streaming_response_subscribe(self, async_client: AsyncMobilerun) assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_test(self, async_client: AsyncMobilerun) -> None: + hook = await async_client.hooks.test( + hook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(HookTestResponse, hook, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_test_with_all_params(self, async_client: AsyncMobilerun) -> None: + hook = await async_client.hooks.test( + hook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + event="event", + ) + assert_matches_type(HookTestResponse, hook, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_test(self, async_client: AsyncMobilerun) -> None: + response = await async_client.hooks.with_raw_response.test( + hook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + hook = await response.parse() + assert_matches_type(HookTestResponse, hook, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_test(self, async_client: AsyncMobilerun) -> None: + async with async_client.hooks.with_streaming_response.test( + hook_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + hook = await response.parse() + assert_matches_type(HookTestResponse, hook, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_test(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `hook_id` but received ''"): + await async_client.hooks.with_raw_response.test( + hook_id="", + ) + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_unsubscribe(self, async_client: AsyncMobilerun) -> None: diff --git a/tests/api_resources/test_proxies.py b/tests/api_resources/test_proxies.py index 6b09e36..b96cc4d 100644 --- a/tests/api_resources/test_proxies.py +++ b/tests/api_resources/test_proxies.py @@ -13,6 +13,7 @@ ProxyListResponse, ProxyCreateResponse, ProxyDeleteResponse, + ProxyLookupResponse, ProxyUpdateResponse, ProxyRetrieveResponse, ) @@ -352,6 +353,62 @@ def test_path_params_delete(self, client: Mobilerun) -> None: "", ) + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_lookup(self, client: Mobilerun) -> None: + proxy = client.proxies.lookup( + socks5={ + "host": "host", + "port": 1, + }, + ) + assert_matches_type(ProxyLookupResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_lookup_with_all_params(self, client: Mobilerun) -> None: + proxy = client.proxies.lookup( + socks5={ + "host": "host", + "port": 1, + "password": "password", + "user": "user", + }, + ) + assert_matches_type(ProxyLookupResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_lookup(self, client: Mobilerun) -> None: + response = client.proxies.with_raw_response.lookup( + socks5={ + "host": "host", + "port": 1, + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = response.parse() + assert_matches_type(ProxyLookupResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_lookup(self, client: Mobilerun) -> None: + with client.proxies.with_streaming_response.lookup( + socks5={ + "host": "host", + "port": 1, + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = response.parse() + assert_matches_type(ProxyLookupResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + class TestAsyncProxies: parametrize = pytest.mark.parametrize( @@ -686,3 +743,59 @@ async def test_path_params_delete(self, async_client: AsyncMobilerun) -> None: await async_client.proxies.with_raw_response.delete( "", ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_lookup(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.proxies.lookup( + socks5={ + "host": "host", + "port": 1, + }, + ) + assert_matches_type(ProxyLookupResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_lookup_with_all_params(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.proxies.lookup( + socks5={ + "host": "host", + "port": 1, + "password": "password", + "user": "user", + }, + ) + assert_matches_type(ProxyLookupResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_lookup(self, async_client: AsyncMobilerun) -> None: + response = await async_client.proxies.with_raw_response.lookup( + socks5={ + "host": "host", + "port": 1, + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = await response.parse() + assert_matches_type(ProxyLookupResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_lookup(self, async_client: AsyncMobilerun) -> None: + async with async_client.proxies.with_streaming_response.lookup( + socks5={ + "host": "host", + "port": 1, + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = await response.parse() + assert_matches_type(ProxyLookupResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True From 3a0956aedece406203dc55228a3ec4549c078d56 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 30 May 2026 11:14:23 +0000 Subject: [PATCH 03/21] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index efc2936..6616e99 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 107 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-93d2d2bea4782e8dfdcad4fa394b5c73b46593bfc11413aeb4c3415e0f09edc3.yml -openapi_spec_hash: 5a16b9c8eaf044d46459b382457c90b6 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-506128e71e04bea5ce31fd879d4c0ac5a313fc39cf9f39acd1cbb3cee95f74ab.yml +openapi_spec_hash: b45c764022d18add79f0516691749fa8 config_hash: 86398ea1292189c25296aefb64d3137d From b58be1c00be168f8719a56d2ce5c1806ac30ef92 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 30 May 2026 12:58:43 +0000 Subject: [PATCH 04/21] feat(api): api update --- .stats.yml | 6 +- api.md | 104 +-- src/mobilerun_sdk/_client.py | 112 +-- src/mobilerun_sdk/resources/__init__.py | 28 - src/mobilerun_sdk/resources/apps.py | 748 ------------------ src/mobilerun_sdk/resources/carriers.py | 4 - .../resources/credentials/__init__.py | 33 - .../resources/credentials/credentials.py | 225 ------ .../credentials/packages/__init__.py | 33 - .../packages/credentials/__init__.py | 33 - .../packages/credentials/credentials.py | 413 ---------- .../packages/credentials/fields.py | 421 ---------- .../credentials/packages/packages.py | 284 ------- .../resources/devices/devices.py | 18 +- src/mobilerun_sdk/resources/devices/tasks.py | 4 - src/mobilerun_sdk/resources/hooks.py | 4 + src/mobilerun_sdk/resources/models.py | 4 - src/mobilerun_sdk/resources/proxies.py | 677 +--------------- src/mobilerun_sdk/types/__init__.py | 21 +- .../types/app_confirm_upload_response.py | 13 - .../app_create_signed_upload_url_params.py | 43 - .../app_create_signed_upload_url_response.py | 26 - .../types/app_delete_response.py | 13 - src/mobilerun_sdk/types/app_list_params.py | 25 - src/mobilerun_sdk/types/app_list_response.py | 333 -------- .../types/app_list_versions_response.py | 296 ------- .../types/app_mark_failed_response.py | 13 - .../types/app_retrieve_response.py | 35 - .../types/credential_list_params.py | 15 - .../types/credential_list_response.py | 15 - .../types/credentials/__init__.py | 4 - .../credentials/package_create_params.py | 13 - .../credentials/package_create_response.py | 21 - .../credentials/package_list_response.py | 12 - .../types/credentials/packages/__init__.py | 6 - .../types/credentials/packages/credential.py | 30 - .../packages/credential_create_params.py | 27 - .../packages/credential_create_response.py | 16 - .../packages/credential_delete_response.py | 16 - .../packages/credential_retrieve_response.py | 10 - .../packages/credentials/__init__.py | 6 - .../credentials/field_create_params.py | 22 - .../credentials/field_create_response.py | 16 - .../credentials/field_delete_response.py | 16 - .../credentials/field_update_params.py | 17 - .../credentials/field_update_response.py | 16 - .../types/device_create_params.py | 14 +- .../types/devices/state_ui_response.py | 104 ++- src/mobilerun_sdk/types/proxy_config.py | 38 +- src/mobilerun_sdk/types/proxy_config_param.py | 18 + .../types/proxy_create_params.py | 33 - .../types/proxy_create_response.py | 16 - .../types/proxy_delete_response.py | 16 - src/mobilerun_sdk/types/proxy_list_params.py | 11 - .../types/proxy_list_response.py | 12 - .../types/proxy_retrieve_response.py | 10 - .../types/proxy_update_params.py | 33 - .../types/proxy_update_response.py | 16 - src/mobilerun_sdk/types/shared/__init__.py | 1 - src/mobilerun_sdk/types/shared/device_spec.py | 14 +- src/mobilerun_sdk/types/shared/pagination.py | 21 - .../types/shared_params/device_spec.py | 14 +- tests/api_resources/credentials/__init__.py | 1 - .../credentials/packages/__init__.py | 1 - .../packages/credentials/__init__.py | 1 - .../packages/credentials/test_fields.py | 390 --------- .../credentials/packages/test_credentials.py | 376 --------- .../credentials/test_packages.py | 176 ----- tests/api_resources/test_apps.py | 712 ----------------- tests/api_resources/test_credentials.py | 98 --- tests/api_resources/test_proxies.py | 667 +--------------- 71 files changed, 162 insertions(+), 6878 deletions(-) delete mode 100644 src/mobilerun_sdk/resources/apps.py delete mode 100644 src/mobilerun_sdk/resources/credentials/__init__.py delete mode 100644 src/mobilerun_sdk/resources/credentials/credentials.py delete mode 100644 src/mobilerun_sdk/resources/credentials/packages/__init__.py delete mode 100644 src/mobilerun_sdk/resources/credentials/packages/credentials/__init__.py delete mode 100644 src/mobilerun_sdk/resources/credentials/packages/credentials/credentials.py delete mode 100644 src/mobilerun_sdk/resources/credentials/packages/credentials/fields.py delete mode 100644 src/mobilerun_sdk/resources/credentials/packages/packages.py delete mode 100644 src/mobilerun_sdk/types/app_confirm_upload_response.py delete mode 100644 src/mobilerun_sdk/types/app_create_signed_upload_url_params.py delete mode 100644 src/mobilerun_sdk/types/app_create_signed_upload_url_response.py delete mode 100644 src/mobilerun_sdk/types/app_delete_response.py delete mode 100644 src/mobilerun_sdk/types/app_list_params.py delete mode 100644 src/mobilerun_sdk/types/app_list_response.py delete mode 100644 src/mobilerun_sdk/types/app_list_versions_response.py delete mode 100644 src/mobilerun_sdk/types/app_mark_failed_response.py delete mode 100644 src/mobilerun_sdk/types/app_retrieve_response.py delete mode 100644 src/mobilerun_sdk/types/credential_list_params.py delete mode 100644 src/mobilerun_sdk/types/credential_list_response.py delete mode 100644 src/mobilerun_sdk/types/credentials/package_create_params.py delete mode 100644 src/mobilerun_sdk/types/credentials/package_create_response.py delete mode 100644 src/mobilerun_sdk/types/credentials/package_list_response.py delete mode 100644 src/mobilerun_sdk/types/credentials/packages/credential.py delete mode 100644 src/mobilerun_sdk/types/credentials/packages/credential_create_params.py delete mode 100644 src/mobilerun_sdk/types/credentials/packages/credential_create_response.py delete mode 100644 src/mobilerun_sdk/types/credentials/packages/credential_delete_response.py delete mode 100644 src/mobilerun_sdk/types/credentials/packages/credential_retrieve_response.py delete mode 100644 src/mobilerun_sdk/types/credentials/packages/credentials/field_create_params.py delete mode 100644 src/mobilerun_sdk/types/credentials/packages/credentials/field_create_response.py delete mode 100644 src/mobilerun_sdk/types/credentials/packages/credentials/field_delete_response.py delete mode 100644 src/mobilerun_sdk/types/credentials/packages/credentials/field_update_params.py delete mode 100644 src/mobilerun_sdk/types/credentials/packages/credentials/field_update_response.py create mode 100644 src/mobilerun_sdk/types/proxy_config_param.py delete mode 100644 src/mobilerun_sdk/types/proxy_create_params.py delete mode 100644 src/mobilerun_sdk/types/proxy_create_response.py delete mode 100644 src/mobilerun_sdk/types/proxy_delete_response.py delete mode 100644 src/mobilerun_sdk/types/proxy_list_params.py delete mode 100644 src/mobilerun_sdk/types/proxy_list_response.py delete mode 100644 src/mobilerun_sdk/types/proxy_retrieve_response.py delete mode 100644 src/mobilerun_sdk/types/proxy_update_params.py delete mode 100644 src/mobilerun_sdk/types/proxy_update_response.py delete mode 100644 src/mobilerun_sdk/types/shared/pagination.py delete mode 100644 tests/api_resources/credentials/__init__.py delete mode 100644 tests/api_resources/credentials/packages/__init__.py delete mode 100644 tests/api_resources/credentials/packages/credentials/__init__.py delete mode 100644 tests/api_resources/credentials/packages/credentials/test_fields.py delete mode 100644 tests/api_resources/credentials/packages/test_credentials.py delete mode 100644 tests/api_resources/credentials/test_packages.py delete mode 100644 tests/api_resources/test_apps.py delete mode 100644 tests/api_resources/test_credentials.py diff --git a/.stats.yml b/.stats.yml index 6616e99..6e46968 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 107 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-506128e71e04bea5ce31fd879d4c0ac5a313fc39cf9f39acd1cbb3cee95f74ab.yml -openapi_spec_hash: b45c764022d18add79f0516691749fa8 +configured_endpoints: 86 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-423b2f04c14fefe08d8c773dc2a025e7775f5ef947a2ba1d8eebbf008106c9fc.yml +openapi_spec_hash: 7581f9f0e4fc01bad5ca519628671bab config_hash: 86398ea1292189c25296aefb64d3137d diff --git a/api.md b/api.md index 4b2c442..1dd0ca2 100644 --- a/api.md +++ b/api.md @@ -7,7 +7,6 @@ from mobilerun_sdk.types import ( DeviceSpec, Location, Meta, - Pagination, PaginationMeta, PermissionSet, Socks5, @@ -26,32 +25,6 @@ Methods: - client.agents.list() -> AgentListResponse -# Apps - -Types: - -```python -from mobilerun_sdk.types import ( - AppRetrieveResponse, - AppListResponse, - AppDeleteResponse, - AppConfirmUploadResponse, - AppCreateSignedUploadURLResponse, - AppListVersionsResponse, - AppMarkFailedResponse, -) -``` - -Methods: - -- client.apps.retrieve(id) -> AppRetrieveResponse -- client.apps.list(\*\*params) -> AppListResponse -- client.apps.delete(id) -> AppDeleteResponse -- client.apps.confirm_upload(id) -> AppConfirmUploadResponse -- client.apps.create_signed_upload_url(\*\*params) -> AppCreateSignedUploadURLResponse -- client.apps.list_versions(id) -> AppListVersionsResponse -- client.apps.mark_failed(id) -> AppMarkFailedResponse - # Carriers Types: @@ -76,68 +49,6 @@ Methods: - client.carriers.delete(carrier_id) -> CarrierDeleteResponse - client.carriers.lookup(\*\*params) -> CarrierLookupResponse -# Credentials - -Types: - -```python -from mobilerun_sdk.types import CredentialListResponse -``` - -Methods: - -- client.credentials.list(\*\*params) -> CredentialListResponse - -## Packages - -Types: - -```python -from mobilerun_sdk.types.credentials import PackageCreateResponse, PackageListResponse -``` - -Methods: - -- client.credentials.packages.create(\*\*params) -> PackageCreateResponse -- client.credentials.packages.list(package_name) -> PackageListResponse - -### Credentials - -Types: - -```python -from mobilerun_sdk.types.credentials.packages import ( - Credential, - CredentialCreateResponse, - CredentialRetrieveResponse, - CredentialDeleteResponse, -) -``` - -Methods: - -- client.credentials.packages.credentials.create(package_name, \*\*params) -> CredentialCreateResponse -- client.credentials.packages.credentials.retrieve(credential_name, \*, package_name) -> CredentialRetrieveResponse -- client.credentials.packages.credentials.delete(credential_name, \*, package_name) -> CredentialDeleteResponse - -#### Fields - -Types: - -```python -from mobilerun_sdk.types.credentials.packages.credentials import ( - FieldCreateResponse, - FieldUpdateResponse, - FieldDeleteResponse, -) -``` - -Methods: - -- client.credentials.packages.credentials.fields.create(credential_name, \*, package_name, \*\*params) -> FieldCreateResponse -- client.credentials.packages.credentials.fields.update(field_type, \*, package_name, credential_name, \*\*params) -> FieldUpdateResponse -- client.credentials.packages.credentials.fields.delete(field_type, \*, package_name, credential_name) -> FieldDeleteResponse - # Devices Types: @@ -407,24 +318,11 @@ Methods: Types: ```python -from mobilerun_sdk.types import ( - ProxyConfig, - ProxyCreateResponse, - ProxyRetrieveResponse, - ProxyUpdateResponse, - ProxyListResponse, - ProxyDeleteResponse, - ProxyLookupResponse, -) +from mobilerun_sdk.types import ProxyConfig, ProxyLookupResponse ``` Methods: -- client.proxies.create(\*\*params) -> ProxyCreateResponse -- client.proxies.retrieve(proxy_id) -> ProxyRetrieveResponse -- client.proxies.update(proxy_id, \*\*params) -> ProxyUpdateResponse -- client.proxies.list(\*\*params) -> ProxyListResponse -- client.proxies.delete(proxy_id) -> ProxyDeleteResponse - client.proxies.lookup(\*\*params) -> ProxyLookupResponse # Tasks diff --git a/src/mobilerun_sdk/_client.py b/src/mobilerun_sdk/_client.py index 28b10f0..3816717 100644 --- a/src/mobilerun_sdk/_client.py +++ b/src/mobilerun_sdk/_client.py @@ -36,8 +36,7 @@ ) if TYPE_CHECKING: - from .resources import apps, hooks, tasks, agents, models, devices, proxies, carriers, profiles, credentials - from .resources.apps import AppsResource, AsyncAppsResource + from .resources import hooks, tasks, agents, models, devices, proxies, carriers, profiles from .resources.hooks import HooksResource, AsyncHooksResource from .resources.agents import AgentsResource, AsyncAgentsResource from .resources.models import ModelsResource, AsyncModelsResource @@ -46,7 +45,6 @@ from .resources.profiles import ProfilesResource, AsyncProfilesResource from .resources.tasks.tasks import TasksResource, AsyncTasksResource from .resources.devices.devices import DevicesResource, AsyncDevicesResource - from .resources.credentials.credentials import CredentialsResource, AsyncCredentialsResource __all__ = [ "Timeout", @@ -127,27 +125,12 @@ def agents(self) -> AgentsResource: return AgentsResource(self) - @cached_property - def apps(self) -> AppsResource: - """App Management""" - from .resources.apps import AppsResource - - return AppsResource(self) - @cached_property def carriers(self) -> CarriersResource: - """Mobile Carriers""" from .resources.carriers import CarriersResource return CarriersResource(self) - @cached_property - def credentials(self) -> CredentialsResource: - """Vault & Secrets""" - from .resources.credentials import CredentialsResource - - return CredentialsResource(self) - @cached_property def devices(self) -> DevicesResource: from .resources.devices import DevicesResource @@ -156,13 +139,13 @@ def devices(self) -> DevicesResource: @cached_property def hooks(self) -> HooksResource: + """Webhooks API""" from .resources.hooks import HooksResource return HooksResource(self) @cached_property def models(self) -> ModelsResource: - """LLM Models""" from .resources.models import ModelsResource return ModelsResource(self) @@ -175,7 +158,6 @@ def profiles(self) -> ProfilesResource: @cached_property def proxies(self) -> ProxiesResource: - """Network Proxies""" from .resources.proxies import ProxiesResource return ProxiesResource(self) @@ -378,27 +360,12 @@ def agents(self) -> AsyncAgentsResource: return AsyncAgentsResource(self) - @cached_property - def apps(self) -> AsyncAppsResource: - """App Management""" - from .resources.apps import AsyncAppsResource - - return AsyncAppsResource(self) - @cached_property def carriers(self) -> AsyncCarriersResource: - """Mobile Carriers""" from .resources.carriers import AsyncCarriersResource return AsyncCarriersResource(self) - @cached_property - def credentials(self) -> AsyncCredentialsResource: - """Vault & Secrets""" - from .resources.credentials import AsyncCredentialsResource - - return AsyncCredentialsResource(self) - @cached_property def devices(self) -> AsyncDevicesResource: from .resources.devices import AsyncDevicesResource @@ -407,13 +374,13 @@ def devices(self) -> AsyncDevicesResource: @cached_property def hooks(self) -> AsyncHooksResource: + """Webhooks API""" from .resources.hooks import AsyncHooksResource return AsyncHooksResource(self) @cached_property def models(self) -> AsyncModelsResource: - """LLM Models""" from .resources.models import AsyncModelsResource return AsyncModelsResource(self) @@ -426,7 +393,6 @@ def profiles(self) -> AsyncProfilesResource: @cached_property def proxies(self) -> AsyncProxiesResource: - """Network Proxies""" from .resources.proxies import AsyncProxiesResource return AsyncProxiesResource(self) @@ -575,27 +541,12 @@ def agents(self) -> agents.AgentsResourceWithRawResponse: return AgentsResourceWithRawResponse(self._client.agents) - @cached_property - def apps(self) -> apps.AppsResourceWithRawResponse: - """App Management""" - from .resources.apps import AppsResourceWithRawResponse - - return AppsResourceWithRawResponse(self._client.apps) - @cached_property def carriers(self) -> carriers.CarriersResourceWithRawResponse: - """Mobile Carriers""" from .resources.carriers import CarriersResourceWithRawResponse return CarriersResourceWithRawResponse(self._client.carriers) - @cached_property - def credentials(self) -> credentials.CredentialsResourceWithRawResponse: - """Vault & Secrets""" - from .resources.credentials import CredentialsResourceWithRawResponse - - return CredentialsResourceWithRawResponse(self._client.credentials) - @cached_property def devices(self) -> devices.DevicesResourceWithRawResponse: from .resources.devices import DevicesResourceWithRawResponse @@ -604,13 +555,13 @@ def devices(self) -> devices.DevicesResourceWithRawResponse: @cached_property def hooks(self) -> hooks.HooksResourceWithRawResponse: + """Webhooks API""" from .resources.hooks import HooksResourceWithRawResponse return HooksResourceWithRawResponse(self._client.hooks) @cached_property def models(self) -> models.ModelsResourceWithRawResponse: - """LLM Models""" from .resources.models import ModelsResourceWithRawResponse return ModelsResourceWithRawResponse(self._client.models) @@ -623,7 +574,6 @@ def profiles(self) -> profiles.ProfilesResourceWithRawResponse: @cached_property def proxies(self) -> proxies.ProxiesResourceWithRawResponse: - """Network Proxies""" from .resources.proxies import ProxiesResourceWithRawResponse return ProxiesResourceWithRawResponse(self._client.proxies) @@ -649,27 +599,12 @@ def agents(self) -> agents.AsyncAgentsResourceWithRawResponse: return AsyncAgentsResourceWithRawResponse(self._client.agents) - @cached_property - def apps(self) -> apps.AsyncAppsResourceWithRawResponse: - """App Management""" - from .resources.apps import AsyncAppsResourceWithRawResponse - - return AsyncAppsResourceWithRawResponse(self._client.apps) - @cached_property def carriers(self) -> carriers.AsyncCarriersResourceWithRawResponse: - """Mobile Carriers""" from .resources.carriers import AsyncCarriersResourceWithRawResponse return AsyncCarriersResourceWithRawResponse(self._client.carriers) - @cached_property - def credentials(self) -> credentials.AsyncCredentialsResourceWithRawResponse: - """Vault & Secrets""" - from .resources.credentials import AsyncCredentialsResourceWithRawResponse - - return AsyncCredentialsResourceWithRawResponse(self._client.credentials) - @cached_property def devices(self) -> devices.AsyncDevicesResourceWithRawResponse: from .resources.devices import AsyncDevicesResourceWithRawResponse @@ -678,13 +613,13 @@ def devices(self) -> devices.AsyncDevicesResourceWithRawResponse: @cached_property def hooks(self) -> hooks.AsyncHooksResourceWithRawResponse: + """Webhooks API""" from .resources.hooks import AsyncHooksResourceWithRawResponse return AsyncHooksResourceWithRawResponse(self._client.hooks) @cached_property def models(self) -> models.AsyncModelsResourceWithRawResponse: - """LLM Models""" from .resources.models import AsyncModelsResourceWithRawResponse return AsyncModelsResourceWithRawResponse(self._client.models) @@ -697,7 +632,6 @@ def profiles(self) -> profiles.AsyncProfilesResourceWithRawResponse: @cached_property def proxies(self) -> proxies.AsyncProxiesResourceWithRawResponse: - """Network Proxies""" from .resources.proxies import AsyncProxiesResourceWithRawResponse return AsyncProxiesResourceWithRawResponse(self._client.proxies) @@ -723,27 +657,12 @@ def agents(self) -> agents.AgentsResourceWithStreamingResponse: return AgentsResourceWithStreamingResponse(self._client.agents) - @cached_property - def apps(self) -> apps.AppsResourceWithStreamingResponse: - """App Management""" - from .resources.apps import AppsResourceWithStreamingResponse - - return AppsResourceWithStreamingResponse(self._client.apps) - @cached_property def carriers(self) -> carriers.CarriersResourceWithStreamingResponse: - """Mobile Carriers""" from .resources.carriers import CarriersResourceWithStreamingResponse return CarriersResourceWithStreamingResponse(self._client.carriers) - @cached_property - def credentials(self) -> credentials.CredentialsResourceWithStreamingResponse: - """Vault & Secrets""" - from .resources.credentials import CredentialsResourceWithStreamingResponse - - return CredentialsResourceWithStreamingResponse(self._client.credentials) - @cached_property def devices(self) -> devices.DevicesResourceWithStreamingResponse: from .resources.devices import DevicesResourceWithStreamingResponse @@ -752,13 +671,13 @@ def devices(self) -> devices.DevicesResourceWithStreamingResponse: @cached_property def hooks(self) -> hooks.HooksResourceWithStreamingResponse: + """Webhooks API""" from .resources.hooks import HooksResourceWithStreamingResponse return HooksResourceWithStreamingResponse(self._client.hooks) @cached_property def models(self) -> models.ModelsResourceWithStreamingResponse: - """LLM Models""" from .resources.models import ModelsResourceWithStreamingResponse return ModelsResourceWithStreamingResponse(self._client.models) @@ -771,7 +690,6 @@ def profiles(self) -> profiles.ProfilesResourceWithStreamingResponse: @cached_property def proxies(self) -> proxies.ProxiesResourceWithStreamingResponse: - """Network Proxies""" from .resources.proxies import ProxiesResourceWithStreamingResponse return ProxiesResourceWithStreamingResponse(self._client.proxies) @@ -797,27 +715,12 @@ def agents(self) -> agents.AsyncAgentsResourceWithStreamingResponse: return AsyncAgentsResourceWithStreamingResponse(self._client.agents) - @cached_property - def apps(self) -> apps.AsyncAppsResourceWithStreamingResponse: - """App Management""" - from .resources.apps import AsyncAppsResourceWithStreamingResponse - - return AsyncAppsResourceWithStreamingResponse(self._client.apps) - @cached_property def carriers(self) -> carriers.AsyncCarriersResourceWithStreamingResponse: - """Mobile Carriers""" from .resources.carriers import AsyncCarriersResourceWithStreamingResponse return AsyncCarriersResourceWithStreamingResponse(self._client.carriers) - @cached_property - def credentials(self) -> credentials.AsyncCredentialsResourceWithStreamingResponse: - """Vault & Secrets""" - from .resources.credentials import AsyncCredentialsResourceWithStreamingResponse - - return AsyncCredentialsResourceWithStreamingResponse(self._client.credentials) - @cached_property def devices(self) -> devices.AsyncDevicesResourceWithStreamingResponse: from .resources.devices import AsyncDevicesResourceWithStreamingResponse @@ -826,13 +729,13 @@ def devices(self) -> devices.AsyncDevicesResourceWithStreamingResponse: @cached_property def hooks(self) -> hooks.AsyncHooksResourceWithStreamingResponse: + """Webhooks API""" from .resources.hooks import AsyncHooksResourceWithStreamingResponse return AsyncHooksResourceWithStreamingResponse(self._client.hooks) @cached_property def models(self) -> models.AsyncModelsResourceWithStreamingResponse: - """LLM Models""" from .resources.models import AsyncModelsResourceWithStreamingResponse return AsyncModelsResourceWithStreamingResponse(self._client.models) @@ -845,7 +748,6 @@ def profiles(self) -> profiles.AsyncProfilesResourceWithStreamingResponse: @cached_property def proxies(self) -> proxies.AsyncProxiesResourceWithStreamingResponse: - """Network Proxies""" from .resources.proxies import AsyncProxiesResourceWithStreamingResponse return AsyncProxiesResourceWithStreamingResponse(self._client.proxies) diff --git a/src/mobilerun_sdk/resources/__init__.py b/src/mobilerun_sdk/resources/__init__.py index 21f473c..9ebd59d 100644 --- a/src/mobilerun_sdk/resources/__init__.py +++ b/src/mobilerun_sdk/resources/__init__.py @@ -1,13 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from .apps import ( - AppsResource, - AsyncAppsResource, - AppsResourceWithRawResponse, - AsyncAppsResourceWithRawResponse, - AppsResourceWithStreamingResponse, - AsyncAppsResourceWithStreamingResponse, -) from .hooks import ( HooksResource, AsyncHooksResource, @@ -72,14 +64,6 @@ ProfilesResourceWithStreamingResponse, AsyncProfilesResourceWithStreamingResponse, ) -from .credentials import ( - CredentialsResource, - AsyncCredentialsResource, - CredentialsResourceWithRawResponse, - AsyncCredentialsResourceWithRawResponse, - CredentialsResourceWithStreamingResponse, - AsyncCredentialsResourceWithStreamingResponse, -) __all__ = [ "AgentsResource", @@ -88,24 +72,12 @@ "AsyncAgentsResourceWithRawResponse", "AgentsResourceWithStreamingResponse", "AsyncAgentsResourceWithStreamingResponse", - "AppsResource", - "AsyncAppsResource", - "AppsResourceWithRawResponse", - "AsyncAppsResourceWithRawResponse", - "AppsResourceWithStreamingResponse", - "AsyncAppsResourceWithStreamingResponse", "CarriersResource", "AsyncCarriersResource", "CarriersResourceWithRawResponse", "AsyncCarriersResourceWithRawResponse", "CarriersResourceWithStreamingResponse", "AsyncCarriersResourceWithStreamingResponse", - "CredentialsResource", - "AsyncCredentialsResource", - "CredentialsResourceWithRawResponse", - "AsyncCredentialsResourceWithRawResponse", - "CredentialsResourceWithStreamingResponse", - "AsyncCredentialsResourceWithStreamingResponse", "DevicesResource", "AsyncDevicesResource", "DevicesResourceWithRawResponse", diff --git a/src/mobilerun_sdk/resources/apps.py b/src/mobilerun_sdk/resources/apps.py deleted file mode 100644 index 3e2bb8f..0000000 --- a/src/mobilerun_sdk/resources/apps.py +++ /dev/null @@ -1,748 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Iterable -from typing_extensions import Literal - -import httpx - -from ..types import app_list_params, app_create_signed_upload_url_params -from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import path_template, maybe_transform, async_maybe_transform -from .._compat import cached_property -from .._resource import SyncAPIResource, AsyncAPIResource -from .._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from .._base_client import make_request_options -from ..types.app_list_response import AppListResponse -from ..types.app_delete_response import AppDeleteResponse -from ..types.app_retrieve_response import AppRetrieveResponse -from ..types.app_mark_failed_response import AppMarkFailedResponse -from ..types.app_list_versions_response import AppListVersionsResponse -from ..types.app_confirm_upload_response import AppConfirmUploadResponse -from ..types.app_create_signed_upload_url_response import AppCreateSignedUploadURLResponse - -__all__ = ["AppsResource", "AsyncAppsResource"] - - -class AppsResource(SyncAPIResource): - """App Management""" - - @cached_property - def with_raw_response(self) -> AppsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return AppsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AppsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return AppsResourceWithStreamingResponse(self) - - def retrieve( - self, - id: str, - *, - # 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, - ) -> AppRetrieveResponse: - """ - Retrieves an app by its ID - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not id: - raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - return self._get( - path_template("/apps/{id}", id=id), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=AppRetrieveResponse, - ) - - def list( - self, - *, - order: Literal["asc", "desc"] | Omit = omit, - page: int | Omit = omit, - page_size: int | Omit = omit, - platform: Literal["all", "android", "ios"] | Omit = omit, - query: str | Omit = omit, - sort_by: Literal["createdAt", "name"] | Omit = omit, - status: Literal["all", "queued", "available", "failed"] | 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, - ) -> AppListResponse: - """ - Retrieves a paginated list of apps with filtering and search capabilities - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get( - "/apps", - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "order": order, - "page": page, - "page_size": page_size, - "platform": platform, - "query": query, - "sort_by": sort_by, - "status": status, - }, - app_list_params.AppListParams, - ), - ), - cast_to=AppListResponse, - ) - - def delete( - self, - id: str, - *, - # 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, - ) -> AppDeleteResponse: - """Deletes an uploaded app by ID. - - Removes files from R2 storage and the database - entry. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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 - ), - cast_to=AppDeleteResponse, - ) - - def confirm_upload( - self, - id: str, - *, - # 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, - ) -> AppConfirmUploadResponse: - """ - Verifies the APK file exists in R2 and sets the app status to available. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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 - ), - cast_to=AppConfirmUploadResponse, - ) - - def create_signed_upload_url( - self, - *, - bundle_id: str, - display_name: str, - files: Iterable[app_create_signed_upload_url_params.File], - size_bytes: float, - version_code: float, - version_name: str, - country: str | Omit = omit, - description: str | Omit = omit, - developer_name: str | Omit = omit, - icon_url: str | Omit = omit, - platform: Literal["android", "ios"] | Omit = omit, - target_sdk: float | 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, - ) -> AppCreateSignedUploadURLResponse: - """ - Creates or updates an app and returns pre-signed Cloudflare R2 upload URLs for - each file - - Args: - country: Country code for Search Results - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._post( - "/apps/create-signed-upload-url", - body=maybe_transform( - { - "bundle_id": bundle_id, - "display_name": display_name, - "files": files, - "size_bytes": size_bytes, - "version_code": version_code, - "version_name": version_name, - "country": country, - "description": description, - "developer_name": developer_name, - "icon_url": icon_url, - "platform": platform, - "target_sdk": target_sdk, - }, - 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 - ), - cast_to=AppCreateSignedUploadURLResponse, - ) - - def list_versions( - self, - id: str, - *, - # 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, - ) -> AppListVersionsResponse: - """ - Retrieves all versions of an app visible to the user (own uploads + system - versions) - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not id: - raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - return self._get( - path_template("/apps/{id}/versions", id=id), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=AppListVersionsResponse, - ) - - def mark_failed( - self, - id: str, - *, - # 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, - ) -> AppMarkFailedResponse: - """ - Sets the app status to failed. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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 - ), - cast_to=AppMarkFailedResponse, - ) - - -class AsyncAppsResource(AsyncAPIResource): - """App Management""" - - @cached_property - def with_raw_response(self) -> AsyncAppsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return AsyncAppsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncAppsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return AsyncAppsResourceWithStreamingResponse(self) - - async def retrieve( - self, - id: str, - *, - # 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, - ) -> AppRetrieveResponse: - """ - Retrieves an app by its ID - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not id: - raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - return await self._get( - path_template("/apps/{id}", id=id), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=AppRetrieveResponse, - ) - - async def list( - self, - *, - order: Literal["asc", "desc"] | Omit = omit, - page: int | Omit = omit, - page_size: int | Omit = omit, - platform: Literal["all", "android", "ios"] | Omit = omit, - query: str | Omit = omit, - sort_by: Literal["createdAt", "name"] | Omit = omit, - status: Literal["all", "queued", "available", "failed"] | 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, - ) -> AppListResponse: - """ - Retrieves a paginated list of apps with filtering and search capabilities - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return await self._get( - "/apps", - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=await async_maybe_transform( - { - "order": order, - "page": page, - "page_size": page_size, - "platform": platform, - "query": query, - "sort_by": sort_by, - "status": status, - }, - app_list_params.AppListParams, - ), - ), - cast_to=AppListResponse, - ) - - async def delete( - self, - id: str, - *, - # 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, - ) -> AppDeleteResponse: - """Deletes an uploaded app by ID. - - Removes files from R2 storage and the database - entry. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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 - ), - cast_to=AppDeleteResponse, - ) - - async def confirm_upload( - self, - id: str, - *, - # 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, - ) -> AppConfirmUploadResponse: - """ - Verifies the APK file exists in R2 and sets the app status to available. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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 - ), - cast_to=AppConfirmUploadResponse, - ) - - async def create_signed_upload_url( - self, - *, - bundle_id: str, - display_name: str, - files: Iterable[app_create_signed_upload_url_params.File], - size_bytes: float, - version_code: float, - version_name: str, - country: str | Omit = omit, - description: str | Omit = omit, - developer_name: str | Omit = omit, - icon_url: str | Omit = omit, - platform: Literal["android", "ios"] | Omit = omit, - target_sdk: float | 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, - ) -> AppCreateSignedUploadURLResponse: - """ - Creates or updates an app and returns pre-signed Cloudflare R2 upload URLs for - each file - - Args: - country: Country code for Search Results - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return await self._post( - "/apps/create-signed-upload-url", - body=await async_maybe_transform( - { - "bundle_id": bundle_id, - "display_name": display_name, - "files": files, - "size_bytes": size_bytes, - "version_code": version_code, - "version_name": version_name, - "country": country, - "description": description, - "developer_name": developer_name, - "icon_url": icon_url, - "platform": platform, - "target_sdk": target_sdk, - }, - 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 - ), - cast_to=AppCreateSignedUploadURLResponse, - ) - - async def list_versions( - self, - id: str, - *, - # 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, - ) -> AppListVersionsResponse: - """ - Retrieves all versions of an app visible to the user (own uploads + system - versions) - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not id: - raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - return await self._get( - path_template("/apps/{id}/versions", id=id), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=AppListVersionsResponse, - ) - - async def mark_failed( - self, - id: str, - *, - # 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, - ) -> AppMarkFailedResponse: - """ - Sets the app status to failed. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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 - ), - cast_to=AppMarkFailedResponse, - ) - - -class AppsResourceWithRawResponse: - def __init__(self, apps: AppsResource) -> None: - self._apps = apps - - self.retrieve = to_raw_response_wrapper( - apps.retrieve, - ) - self.list = to_raw_response_wrapper( - apps.list, - ) - self.delete = to_raw_response_wrapper( - apps.delete, - ) - self.confirm_upload = to_raw_response_wrapper( - apps.confirm_upload, - ) - self.create_signed_upload_url = to_raw_response_wrapper( - apps.create_signed_upload_url, - ) - self.list_versions = to_raw_response_wrapper( - apps.list_versions, - ) - self.mark_failed = to_raw_response_wrapper( - apps.mark_failed, - ) - - -class AsyncAppsResourceWithRawResponse: - def __init__(self, apps: AsyncAppsResource) -> None: - self._apps = apps - - self.retrieve = async_to_raw_response_wrapper( - apps.retrieve, - ) - self.list = async_to_raw_response_wrapper( - apps.list, - ) - self.delete = async_to_raw_response_wrapper( - apps.delete, - ) - self.confirm_upload = async_to_raw_response_wrapper( - apps.confirm_upload, - ) - self.create_signed_upload_url = async_to_raw_response_wrapper( - apps.create_signed_upload_url, - ) - self.list_versions = async_to_raw_response_wrapper( - apps.list_versions, - ) - self.mark_failed = async_to_raw_response_wrapper( - apps.mark_failed, - ) - - -class AppsResourceWithStreamingResponse: - def __init__(self, apps: AppsResource) -> None: - self._apps = apps - - self.retrieve = to_streamed_response_wrapper( - apps.retrieve, - ) - self.list = to_streamed_response_wrapper( - apps.list, - ) - self.delete = to_streamed_response_wrapper( - apps.delete, - ) - self.confirm_upload = to_streamed_response_wrapper( - apps.confirm_upload, - ) - self.create_signed_upload_url = to_streamed_response_wrapper( - apps.create_signed_upload_url, - ) - self.list_versions = to_streamed_response_wrapper( - apps.list_versions, - ) - self.mark_failed = to_streamed_response_wrapper( - apps.mark_failed, - ) - - -class AsyncAppsResourceWithStreamingResponse: - def __init__(self, apps: AsyncAppsResource) -> None: - self._apps = apps - - self.retrieve = async_to_streamed_response_wrapper( - apps.retrieve, - ) - self.list = async_to_streamed_response_wrapper( - apps.list, - ) - self.delete = async_to_streamed_response_wrapper( - apps.delete, - ) - self.confirm_upload = async_to_streamed_response_wrapper( - apps.confirm_upload, - ) - self.create_signed_upload_url = async_to_streamed_response_wrapper( - apps.create_signed_upload_url, - ) - self.list_versions = async_to_streamed_response_wrapper( - apps.list_versions, - ) - self.mark_failed = async_to_streamed_response_wrapper( - apps.mark_failed, - ) diff --git a/src/mobilerun_sdk/resources/carriers.py b/src/mobilerun_sdk/resources/carriers.py index d627159..a674b8f 100644 --- a/src/mobilerun_sdk/resources/carriers.py +++ b/src/mobilerun_sdk/resources/carriers.py @@ -29,8 +29,6 @@ class CarriersResource(SyncAPIResource): - """Mobile Carriers""" - @cached_property def with_raw_response(self) -> CarriersResourceWithRawResponse: """ @@ -419,8 +417,6 @@ def lookup( class AsyncCarriersResource(AsyncAPIResource): - """Mobile Carriers""" - @cached_property def with_raw_response(self) -> AsyncCarriersResourceWithRawResponse: """ diff --git a/src/mobilerun_sdk/resources/credentials/__init__.py b/src/mobilerun_sdk/resources/credentials/__init__.py deleted file mode 100644 index 2ab7903..0000000 --- a/src/mobilerun_sdk/resources/credentials/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from .packages import ( - PackagesResource, - AsyncPackagesResource, - PackagesResourceWithRawResponse, - AsyncPackagesResourceWithRawResponse, - PackagesResourceWithStreamingResponse, - AsyncPackagesResourceWithStreamingResponse, -) -from .credentials import ( - CredentialsResource, - AsyncCredentialsResource, - CredentialsResourceWithRawResponse, - AsyncCredentialsResourceWithRawResponse, - CredentialsResourceWithStreamingResponse, - AsyncCredentialsResourceWithStreamingResponse, -) - -__all__ = [ - "PackagesResource", - "AsyncPackagesResource", - "PackagesResourceWithRawResponse", - "AsyncPackagesResourceWithRawResponse", - "PackagesResourceWithStreamingResponse", - "AsyncPackagesResourceWithStreamingResponse", - "CredentialsResource", - "AsyncCredentialsResource", - "CredentialsResourceWithRawResponse", - "AsyncCredentialsResourceWithRawResponse", - "CredentialsResourceWithStreamingResponse", - "AsyncCredentialsResourceWithStreamingResponse", -] diff --git a/src/mobilerun_sdk/resources/credentials/credentials.py b/src/mobilerun_sdk/resources/credentials/credentials.py deleted file mode 100644 index 9276d9f..0000000 --- a/src/mobilerun_sdk/resources/credentials/credentials.py +++ /dev/null @@ -1,225 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import httpx - -from ...types import credential_list_params -from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from ..._utils import maybe_transform, async_maybe_transform -from ..._compat import cached_property -from ..._resource import SyncAPIResource, AsyncAPIResource -from ..._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ..._base_client import make_request_options -from .packages.packages import ( - PackagesResource, - AsyncPackagesResource, - PackagesResourceWithRawResponse, - AsyncPackagesResourceWithRawResponse, - PackagesResourceWithStreamingResponse, - AsyncPackagesResourceWithStreamingResponse, -) -from ...types.credential_list_response import CredentialListResponse - -__all__ = ["CredentialsResource", "AsyncCredentialsResource"] - - -class CredentialsResource(SyncAPIResource): - """Vault & Secrets""" - - @cached_property - def packages(self) -> PackagesResource: - """Vault & Secrets""" - return PackagesResource(self._client) - - @cached_property - def with_raw_response(self) -> CredentialsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return CredentialsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> CredentialsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return CredentialsResourceWithStreamingResponse(self) - - def list( - self, - *, - page: int | Omit = omit, - page_size: int | 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, - ) -> CredentialListResponse: - """ - List all credentials for the authenticated user - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get( - "/credentials", - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "page": page, - "page_size": page_size, - }, - credential_list_params.CredentialListParams, - ), - ), - cast_to=CredentialListResponse, - ) - - -class AsyncCredentialsResource(AsyncAPIResource): - """Vault & Secrets""" - - @cached_property - def packages(self) -> AsyncPackagesResource: - """Vault & Secrets""" - return AsyncPackagesResource(self._client) - - @cached_property - def with_raw_response(self) -> AsyncCredentialsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return AsyncCredentialsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncCredentialsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return AsyncCredentialsResourceWithStreamingResponse(self) - - async def list( - self, - *, - page: int | Omit = omit, - page_size: int | 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, - ) -> CredentialListResponse: - """ - List all credentials for the authenticated user - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return await self._get( - "/credentials", - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=await async_maybe_transform( - { - "page": page, - "page_size": page_size, - }, - credential_list_params.CredentialListParams, - ), - ), - cast_to=CredentialListResponse, - ) - - -class CredentialsResourceWithRawResponse: - def __init__(self, credentials: CredentialsResource) -> None: - self._credentials = credentials - - self.list = to_raw_response_wrapper( - credentials.list, - ) - - @cached_property - def packages(self) -> PackagesResourceWithRawResponse: - """Vault & Secrets""" - return PackagesResourceWithRawResponse(self._credentials.packages) - - -class AsyncCredentialsResourceWithRawResponse: - def __init__(self, credentials: AsyncCredentialsResource) -> None: - self._credentials = credentials - - self.list = async_to_raw_response_wrapper( - credentials.list, - ) - - @cached_property - def packages(self) -> AsyncPackagesResourceWithRawResponse: - """Vault & Secrets""" - return AsyncPackagesResourceWithRawResponse(self._credentials.packages) - - -class CredentialsResourceWithStreamingResponse: - def __init__(self, credentials: CredentialsResource) -> None: - self._credentials = credentials - - self.list = to_streamed_response_wrapper( - credentials.list, - ) - - @cached_property - def packages(self) -> PackagesResourceWithStreamingResponse: - """Vault & Secrets""" - return PackagesResourceWithStreamingResponse(self._credentials.packages) - - -class AsyncCredentialsResourceWithStreamingResponse: - def __init__(self, credentials: AsyncCredentialsResource) -> None: - self._credentials = credentials - - self.list = async_to_streamed_response_wrapper( - credentials.list, - ) - - @cached_property - def packages(self) -> AsyncPackagesResourceWithStreamingResponse: - """Vault & Secrets""" - return AsyncPackagesResourceWithStreamingResponse(self._credentials.packages) diff --git a/src/mobilerun_sdk/resources/credentials/packages/__init__.py b/src/mobilerun_sdk/resources/credentials/packages/__init__.py deleted file mode 100644 index 179ec4a..0000000 --- a/src/mobilerun_sdk/resources/credentials/packages/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from .packages import ( - PackagesResource, - AsyncPackagesResource, - PackagesResourceWithRawResponse, - AsyncPackagesResourceWithRawResponse, - PackagesResourceWithStreamingResponse, - AsyncPackagesResourceWithStreamingResponse, -) -from .credentials import ( - CredentialsResource, - AsyncCredentialsResource, - CredentialsResourceWithRawResponse, - AsyncCredentialsResourceWithRawResponse, - CredentialsResourceWithStreamingResponse, - AsyncCredentialsResourceWithStreamingResponse, -) - -__all__ = [ - "CredentialsResource", - "AsyncCredentialsResource", - "CredentialsResourceWithRawResponse", - "AsyncCredentialsResourceWithRawResponse", - "CredentialsResourceWithStreamingResponse", - "AsyncCredentialsResourceWithStreamingResponse", - "PackagesResource", - "AsyncPackagesResource", - "PackagesResourceWithRawResponse", - "AsyncPackagesResourceWithRawResponse", - "PackagesResourceWithStreamingResponse", - "AsyncPackagesResourceWithStreamingResponse", -] diff --git a/src/mobilerun_sdk/resources/credentials/packages/credentials/__init__.py b/src/mobilerun_sdk/resources/credentials/packages/credentials/__init__.py deleted file mode 100644 index bfa68f3..0000000 --- a/src/mobilerun_sdk/resources/credentials/packages/credentials/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from .fields import ( - FieldsResource, - AsyncFieldsResource, - FieldsResourceWithRawResponse, - AsyncFieldsResourceWithRawResponse, - FieldsResourceWithStreamingResponse, - AsyncFieldsResourceWithStreamingResponse, -) -from .credentials import ( - CredentialsResource, - AsyncCredentialsResource, - CredentialsResourceWithRawResponse, - AsyncCredentialsResourceWithRawResponse, - CredentialsResourceWithStreamingResponse, - AsyncCredentialsResourceWithStreamingResponse, -) - -__all__ = [ - "FieldsResource", - "AsyncFieldsResource", - "FieldsResourceWithRawResponse", - "AsyncFieldsResourceWithRawResponse", - "FieldsResourceWithStreamingResponse", - "AsyncFieldsResourceWithStreamingResponse", - "CredentialsResource", - "AsyncCredentialsResource", - "CredentialsResourceWithRawResponse", - "AsyncCredentialsResourceWithRawResponse", - "CredentialsResourceWithStreamingResponse", - "AsyncCredentialsResourceWithStreamingResponse", -] diff --git a/src/mobilerun_sdk/resources/credentials/packages/credentials/credentials.py b/src/mobilerun_sdk/resources/credentials/packages/credentials/credentials.py deleted file mode 100644 index df12c15..0000000 --- a/src/mobilerun_sdk/resources/credentials/packages/credentials/credentials.py +++ /dev/null @@ -1,413 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Iterable - -import httpx - -from .fields import ( - FieldsResource, - AsyncFieldsResource, - FieldsResourceWithRawResponse, - AsyncFieldsResourceWithRawResponse, - FieldsResourceWithStreamingResponse, - AsyncFieldsResourceWithStreamingResponse, -) -from ....._types import Body, Query, Headers, NotGiven, not_given -from ....._utils import path_template, maybe_transform, async_maybe_transform -from ....._compat import cached_property -from ....._resource import SyncAPIResource, AsyncAPIResource -from ....._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ....._base_client import make_request_options -from .....types.credentials.packages import credential_create_params -from .....types.credentials.packages.credential_create_response import CredentialCreateResponse -from .....types.credentials.packages.credential_delete_response import CredentialDeleteResponse -from .....types.credentials.packages.credential_retrieve_response import CredentialRetrieveResponse - -__all__ = ["CredentialsResource", "AsyncCredentialsResource"] - - -class CredentialsResource(SyncAPIResource): - """Vault & Secrets""" - - @cached_property - def fields(self) -> FieldsResource: - """Vault & Secrets""" - return FieldsResource(self._client) - - @cached_property - def with_raw_response(self) -> CredentialsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return CredentialsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> CredentialsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return CredentialsResourceWithStreamingResponse(self) - - def create( - self, - package_name: str, - *, - credential_name: str, - fields: Iterable[credential_create_params.Field], - # 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, - ) -> CredentialCreateResponse: - """ - Create a credential with fields for a package - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not package_name: - raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") - return self._post( - path_template("/credentials/packages/{package_name}", package_name=package_name), - body=maybe_transform( - { - "credential_name": credential_name, - "fields": fields, - }, - credential_create_params.CredentialCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=CredentialCreateResponse, - ) - - def retrieve( - self, - credential_name: str, - *, - package_name: str, - # 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, - ) -> CredentialRetrieveResponse: - """ - Get a specific credential with its fields - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not package_name: - raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") - if not credential_name: - raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") - return self._get( - path_template( - "/credentials/packages/{package_name}/credentials/{credential_name}", - package_name=package_name, - credential_name=credential_name, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=CredentialRetrieveResponse, - ) - - def delete( - self, - credential_name: str, - *, - package_name: str, - # 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, - ) -> CredentialDeleteResponse: - """ - Delete a credential and all its fields - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not package_name: - raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") - if not credential_name: - raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") - return self._delete( - path_template( - "/credentials/packages/{package_name}/credentials/{credential_name}", - package_name=package_name, - credential_name=credential_name, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=CredentialDeleteResponse, - ) - - -class AsyncCredentialsResource(AsyncAPIResource): - """Vault & Secrets""" - - @cached_property - def fields(self) -> AsyncFieldsResource: - """Vault & Secrets""" - return AsyncFieldsResource(self._client) - - @cached_property - def with_raw_response(self) -> AsyncCredentialsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return AsyncCredentialsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncCredentialsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return AsyncCredentialsResourceWithStreamingResponse(self) - - async def create( - self, - package_name: str, - *, - credential_name: str, - fields: Iterable[credential_create_params.Field], - # 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, - ) -> CredentialCreateResponse: - """ - Create a credential with fields for a package - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not package_name: - raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") - return await self._post( - path_template("/credentials/packages/{package_name}", package_name=package_name), - body=await async_maybe_transform( - { - "credential_name": credential_name, - "fields": fields, - }, - credential_create_params.CredentialCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=CredentialCreateResponse, - ) - - async def retrieve( - self, - credential_name: str, - *, - package_name: str, - # 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, - ) -> CredentialRetrieveResponse: - """ - Get a specific credential with its fields - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not package_name: - raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") - if not credential_name: - raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") - return await self._get( - path_template( - "/credentials/packages/{package_name}/credentials/{credential_name}", - package_name=package_name, - credential_name=credential_name, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=CredentialRetrieveResponse, - ) - - async def delete( - self, - credential_name: str, - *, - package_name: str, - # 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, - ) -> CredentialDeleteResponse: - """ - Delete a credential and all its fields - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not package_name: - raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") - if not credential_name: - raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") - return await self._delete( - path_template( - "/credentials/packages/{package_name}/credentials/{credential_name}", - package_name=package_name, - credential_name=credential_name, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=CredentialDeleteResponse, - ) - - -class CredentialsResourceWithRawResponse: - def __init__(self, credentials: CredentialsResource) -> None: - self._credentials = credentials - - self.create = to_raw_response_wrapper( - credentials.create, - ) - self.retrieve = to_raw_response_wrapper( - credentials.retrieve, - ) - self.delete = to_raw_response_wrapper( - credentials.delete, - ) - - @cached_property - def fields(self) -> FieldsResourceWithRawResponse: - """Vault & Secrets""" - return FieldsResourceWithRawResponse(self._credentials.fields) - - -class AsyncCredentialsResourceWithRawResponse: - def __init__(self, credentials: AsyncCredentialsResource) -> None: - self._credentials = credentials - - self.create = async_to_raw_response_wrapper( - credentials.create, - ) - self.retrieve = async_to_raw_response_wrapper( - credentials.retrieve, - ) - self.delete = async_to_raw_response_wrapper( - credentials.delete, - ) - - @cached_property - def fields(self) -> AsyncFieldsResourceWithRawResponse: - """Vault & Secrets""" - return AsyncFieldsResourceWithRawResponse(self._credentials.fields) - - -class CredentialsResourceWithStreamingResponse: - def __init__(self, credentials: CredentialsResource) -> None: - self._credentials = credentials - - self.create = to_streamed_response_wrapper( - credentials.create, - ) - self.retrieve = to_streamed_response_wrapper( - credentials.retrieve, - ) - self.delete = to_streamed_response_wrapper( - credentials.delete, - ) - - @cached_property - def fields(self) -> FieldsResourceWithStreamingResponse: - """Vault & Secrets""" - return FieldsResourceWithStreamingResponse(self._credentials.fields) - - -class AsyncCredentialsResourceWithStreamingResponse: - def __init__(self, credentials: AsyncCredentialsResource) -> None: - self._credentials = credentials - - self.create = async_to_streamed_response_wrapper( - credentials.create, - ) - self.retrieve = async_to_streamed_response_wrapper( - credentials.retrieve, - ) - self.delete = async_to_streamed_response_wrapper( - credentials.delete, - ) - - @cached_property - def fields(self) -> AsyncFieldsResourceWithStreamingResponse: - """Vault & Secrets""" - return AsyncFieldsResourceWithStreamingResponse(self._credentials.fields) diff --git a/src/mobilerun_sdk/resources/credentials/packages/credentials/fields.py b/src/mobilerun_sdk/resources/credentials/packages/credentials/fields.py deleted file mode 100644 index 38ebfd9..0000000 --- a/src/mobilerun_sdk/resources/credentials/packages/credentials/fields.py +++ /dev/null @@ -1,421 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Literal - -import httpx - -from ....._types import Body, Query, Headers, NotGiven, not_given -from ....._utils import path_template, maybe_transform, async_maybe_transform -from ....._compat import cached_property -from ....._resource import SyncAPIResource, AsyncAPIResource -from ....._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ....._base_client import make_request_options -from .....types.credentials.packages.credentials import field_create_params, field_update_params -from .....types.credentials.packages.credentials.field_create_response import FieldCreateResponse -from .....types.credentials.packages.credentials.field_delete_response import FieldDeleteResponse -from .....types.credentials.packages.credentials.field_update_response import FieldUpdateResponse - -__all__ = ["FieldsResource", "AsyncFieldsResource"] - - -class FieldsResource(SyncAPIResource): - """Vault & Secrets""" - - @cached_property - def with_raw_response(self) -> FieldsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return FieldsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> FieldsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return FieldsResourceWithStreamingResponse(self) - - def create( - self, - credential_name: str, - *, - package_name: str, - field_type: Literal[ - "email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes" - ], - value: str, - # 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, - ) -> FieldCreateResponse: - """ - Add a new field to an existing credential - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not package_name: - raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") - if not credential_name: - raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") - return self._post( - path_template( - "/credentials/packages/{package_name}/credentials/{credential_name}/fields", - package_name=package_name, - credential_name=credential_name, - ), - body=maybe_transform( - { - "field_type": field_type, - "value": value, - }, - field_create_params.FieldCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=FieldCreateResponse, - ) - - def update( - self, - field_type: Literal[ - "email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes" - ], - *, - package_name: str, - credential_name: str, - value: str, - # 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, - ) -> FieldUpdateResponse: - """ - Update the value of a credential field - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not package_name: - raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") - if not credential_name: - raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") - if not field_type: - raise ValueError(f"Expected a non-empty value for `field_type` but received {field_type!r}") - return self._patch( - path_template( - "/credentials/packages/{package_name}/credentials/{credential_name}/fields/{field_type}", - package_name=package_name, - credential_name=credential_name, - field_type=field_type, - ), - 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 - ), - cast_to=FieldUpdateResponse, - ) - - def delete( - self, - field_type: Literal[ - "email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes" - ], - *, - package_name: str, - credential_name: str, - # 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, - ) -> FieldDeleteResponse: - """ - Delete a field from a credential - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not package_name: - raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") - if not credential_name: - raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") - if not field_type: - raise ValueError(f"Expected a non-empty value for `field_type` but received {field_type!r}") - return self._delete( - path_template( - "/credentials/packages/{package_name}/credentials/{credential_name}/fields/{field_type}", - package_name=package_name, - credential_name=credential_name, - field_type=field_type, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=FieldDeleteResponse, - ) - - -class AsyncFieldsResource(AsyncAPIResource): - """Vault & Secrets""" - - @cached_property - def with_raw_response(self) -> AsyncFieldsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return AsyncFieldsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncFieldsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return AsyncFieldsResourceWithStreamingResponse(self) - - async def create( - self, - credential_name: str, - *, - package_name: str, - field_type: Literal[ - "email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes" - ], - value: str, - # 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, - ) -> FieldCreateResponse: - """ - Add a new field to an existing credential - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not package_name: - raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") - if not credential_name: - raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") - return await self._post( - path_template( - "/credentials/packages/{package_name}/credentials/{credential_name}/fields", - package_name=package_name, - credential_name=credential_name, - ), - body=await async_maybe_transform( - { - "field_type": field_type, - "value": value, - }, - field_create_params.FieldCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=FieldCreateResponse, - ) - - async def update( - self, - field_type: Literal[ - "email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes" - ], - *, - package_name: str, - credential_name: str, - value: str, - # 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, - ) -> FieldUpdateResponse: - """ - Update the value of a credential field - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not package_name: - raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") - if not credential_name: - raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") - if not field_type: - raise ValueError(f"Expected a non-empty value for `field_type` but received {field_type!r}") - return await self._patch( - path_template( - "/credentials/packages/{package_name}/credentials/{credential_name}/fields/{field_type}", - package_name=package_name, - credential_name=credential_name, - field_type=field_type, - ), - 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 - ), - cast_to=FieldUpdateResponse, - ) - - async def delete( - self, - field_type: Literal[ - "email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes" - ], - *, - package_name: str, - credential_name: str, - # 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, - ) -> FieldDeleteResponse: - """ - Delete a field from a credential - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not package_name: - raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") - if not credential_name: - raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") - if not field_type: - raise ValueError(f"Expected a non-empty value for `field_type` but received {field_type!r}") - return await self._delete( - path_template( - "/credentials/packages/{package_name}/credentials/{credential_name}/fields/{field_type}", - package_name=package_name, - credential_name=credential_name, - field_type=field_type, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=FieldDeleteResponse, - ) - - -class FieldsResourceWithRawResponse: - def __init__(self, fields: FieldsResource) -> None: - self._fields = fields - - self.create = to_raw_response_wrapper( - fields.create, - ) - self.update = to_raw_response_wrapper( - fields.update, - ) - self.delete = to_raw_response_wrapper( - fields.delete, - ) - - -class AsyncFieldsResourceWithRawResponse: - def __init__(self, fields: AsyncFieldsResource) -> None: - self._fields = fields - - self.create = async_to_raw_response_wrapper( - fields.create, - ) - self.update = async_to_raw_response_wrapper( - fields.update, - ) - self.delete = async_to_raw_response_wrapper( - fields.delete, - ) - - -class FieldsResourceWithStreamingResponse: - def __init__(self, fields: FieldsResource) -> None: - self._fields = fields - - self.create = to_streamed_response_wrapper( - fields.create, - ) - self.update = to_streamed_response_wrapper( - fields.update, - ) - self.delete = to_streamed_response_wrapper( - fields.delete, - ) - - -class AsyncFieldsResourceWithStreamingResponse: - def __init__(self, fields: AsyncFieldsResource) -> None: - self._fields = fields - - self.create = async_to_streamed_response_wrapper( - fields.create, - ) - self.update = async_to_streamed_response_wrapper( - fields.update, - ) - self.delete = async_to_streamed_response_wrapper( - fields.delete, - ) diff --git a/src/mobilerun_sdk/resources/credentials/packages/packages.py b/src/mobilerun_sdk/resources/credentials/packages/packages.py deleted file mode 100644 index 135ccdd..0000000 --- a/src/mobilerun_sdk/resources/credentials/packages/packages.py +++ /dev/null @@ -1,284 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import httpx - -from ...._types import Body, Query, Headers, NotGiven, not_given -from ...._utils import path_template, maybe_transform, async_maybe_transform -from ...._compat import cached_property -from ...._resource import SyncAPIResource, AsyncAPIResource -from ...._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ...._base_client import make_request_options -from ....types.credentials import package_create_params -from .credentials.credentials import ( - CredentialsResource, - AsyncCredentialsResource, - CredentialsResourceWithRawResponse, - AsyncCredentialsResourceWithRawResponse, - CredentialsResourceWithStreamingResponse, - AsyncCredentialsResourceWithStreamingResponse, -) -from ....types.credentials.package_list_response import PackageListResponse -from ....types.credentials.package_create_response import PackageCreateResponse - -__all__ = ["PackagesResource", "AsyncPackagesResource"] - - -class PackagesResource(SyncAPIResource): - """Vault & Secrets""" - - @cached_property - def credentials(self) -> CredentialsResource: - """Vault & Secrets""" - return CredentialsResource(self._client) - - @cached_property - def with_raw_response(self) -> PackagesResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return PackagesResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> PackagesResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return PackagesResourceWithStreamingResponse(self) - - def create( - self, - *, - package_name: str, - # 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, - ) -> PackageCreateResponse: - """ - Initialize a new package/app - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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 - ), - cast_to=PackageCreateResponse, - ) - - def list( - self, - package_name: str, - *, - # 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, - ) -> PackageListResponse: - """ - List credentials for a specific package - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not package_name: - raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") - return self._get( - path_template("/credentials/packages/{package_name}", package_name=package_name), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=PackageListResponse, - ) - - -class AsyncPackagesResource(AsyncAPIResource): - """Vault & Secrets""" - - @cached_property - def credentials(self) -> AsyncCredentialsResource: - """Vault & Secrets""" - return AsyncCredentialsResource(self._client) - - @cached_property - def with_raw_response(self) -> AsyncPackagesResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return AsyncPackagesResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncPackagesResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return AsyncPackagesResourceWithStreamingResponse(self) - - async def create( - self, - *, - package_name: str, - # 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, - ) -> PackageCreateResponse: - """ - Initialize a new package/app - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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 - ), - cast_to=PackageCreateResponse, - ) - - async def list( - self, - package_name: str, - *, - # 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, - ) -> PackageListResponse: - """ - List credentials for a specific package - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not package_name: - raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") - return await self._get( - path_template("/credentials/packages/{package_name}", package_name=package_name), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=PackageListResponse, - ) - - -class PackagesResourceWithRawResponse: - def __init__(self, packages: PackagesResource) -> None: - self._packages = packages - - self.create = to_raw_response_wrapper( - packages.create, - ) - self.list = to_raw_response_wrapper( - packages.list, - ) - - @cached_property - def credentials(self) -> CredentialsResourceWithRawResponse: - """Vault & Secrets""" - return CredentialsResourceWithRawResponse(self._packages.credentials) - - -class AsyncPackagesResourceWithRawResponse: - def __init__(self, packages: AsyncPackagesResource) -> None: - self._packages = packages - - self.create = async_to_raw_response_wrapper( - packages.create, - ) - self.list = async_to_raw_response_wrapper( - packages.list, - ) - - @cached_property - def credentials(self) -> AsyncCredentialsResourceWithRawResponse: - """Vault & Secrets""" - return AsyncCredentialsResourceWithRawResponse(self._packages.credentials) - - -class PackagesResourceWithStreamingResponse: - def __init__(self, packages: PackagesResource) -> None: - self._packages = packages - - self.create = to_streamed_response_wrapper( - packages.create, - ) - self.list = to_streamed_response_wrapper( - packages.list, - ) - - @cached_property - def credentials(self) -> CredentialsResourceWithStreamingResponse: - """Vault & Secrets""" - return CredentialsResourceWithStreamingResponse(self._packages.credentials) - - -class AsyncPackagesResourceWithStreamingResponse: - def __init__(self, packages: AsyncPackagesResource) -> None: - self._packages = packages - - self.create = async_to_streamed_response_wrapper( - packages.create, - ) - self.list = async_to_streamed_response_wrapper( - packages.list, - ) - - @cached_property - def credentials(self) -> AsyncCredentialsResourceWithStreamingResponse: - """Vault & Secrets""" - return AsyncCredentialsResourceWithStreamingResponse(self._packages.credentials) diff --git a/src/mobilerun_sdk/resources/devices/devices.py b/src/mobilerun_sdk/resources/devices/devices.py index 31c41ed..b70b517 100644 --- a/src/mobilerun_sdk/resources/devices/devices.py +++ b/src/mobilerun_sdk/resources/devices/devices.py @@ -48,7 +48,12 @@ TasksResourceWithStreamingResponse, AsyncTasksResourceWithStreamingResponse, ) -from ...types import device_list_params, device_create_params, device_set_name_params, device_terminate_params +from ...types import ( + device_list_params, + device_create_params, + device_set_name_params, + device_terminate_params, +) from .actions import ( ActionsResource, AsyncActionsResource, @@ -125,6 +130,7 @@ ) from ..._base_client import make_request_options from ...types.device import Device +from ...types.proxy_config_param import ProxyConfigParam from ...types.device_list_response import DeviceListResponse from ...types.device_count_response import DeviceCountResponse from ...types.shared_params.location import Location @@ -178,7 +184,6 @@ def state(self) -> StateResource: @cached_property def tasks(self) -> TasksResource: - """Device Management""" return TasksResource(self._client) @cached_property @@ -224,7 +229,7 @@ def create( locale: str | Omit = omit, location: Location | Omit = omit, name: str | Omit = omit, - proxy: device_create_params.Proxy | Omit = omit, + proxy: ProxyConfigParam | Omit = omit, timezone: 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. @@ -673,7 +678,6 @@ def state(self) -> AsyncStateResource: @cached_property def tasks(self) -> AsyncTasksResource: - """Device Management""" return AsyncTasksResource(self._client) @cached_property @@ -719,7 +723,7 @@ async def create( locale: str | Omit = omit, location: Location | Omit = omit, name: str | Omit = omit, - proxy: device_create_params.Proxy | Omit = omit, + proxy: ProxyConfigParam | Omit = omit, timezone: 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. @@ -1202,7 +1206,6 @@ def state(self) -> StateResourceWithRawResponse: @cached_property def tasks(self) -> TasksResourceWithRawResponse: - """Device Management""" return TasksResourceWithRawResponse(self._devices.tasks) @cached_property @@ -1291,7 +1294,6 @@ def state(self) -> AsyncStateResourceWithRawResponse: @cached_property def tasks(self) -> AsyncTasksResourceWithRawResponse: - """Device Management""" return AsyncTasksResourceWithRawResponse(self._devices.tasks) @cached_property @@ -1380,7 +1382,6 @@ def state(self) -> StateResourceWithStreamingResponse: @cached_property def tasks(self) -> TasksResourceWithStreamingResponse: - """Device Management""" return TasksResourceWithStreamingResponse(self._devices.tasks) @cached_property @@ -1469,7 +1470,6 @@ def state(self) -> AsyncStateResourceWithStreamingResponse: @cached_property def tasks(self) -> AsyncTasksResourceWithStreamingResponse: - """Device Management""" return AsyncTasksResourceWithStreamingResponse(self._devices.tasks) @cached_property diff --git a/src/mobilerun_sdk/resources/devices/tasks.py b/src/mobilerun_sdk/resources/devices/tasks.py index 061d2ca..62c8d6f 100644 --- a/src/mobilerun_sdk/resources/devices/tasks.py +++ b/src/mobilerun_sdk/resources/devices/tasks.py @@ -24,8 +24,6 @@ class TasksResource(SyncAPIResource): - """Device Management""" - @cached_property def with_raw_response(self) -> TasksResourceWithRawResponse: """ @@ -96,8 +94,6 @@ def list( class AsyncTasksResource(AsyncAPIResource): - """Device Management""" - @cached_property def with_raw_response(self) -> AsyncTasksResourceWithRawResponse: """ diff --git a/src/mobilerun_sdk/resources/hooks.py b/src/mobilerun_sdk/resources/hooks.py index 6f3c43b..39a730c 100644 --- a/src/mobilerun_sdk/resources/hooks.py +++ b/src/mobilerun_sdk/resources/hooks.py @@ -32,6 +32,8 @@ class HooksResource(SyncAPIResource): + """Webhooks API""" + @cached_property def with_raw_response(self) -> HooksResourceWithRawResponse: """ @@ -355,6 +357,8 @@ def unsubscribe( class AsyncHooksResource(AsyncAPIResource): + """Webhooks API""" + @cached_property def with_raw_response(self) -> AsyncHooksResourceWithRawResponse: """ diff --git a/src/mobilerun_sdk/resources/models.py b/src/mobilerun_sdk/resources/models.py index 4bb2764..d1edbdd 100644 --- a/src/mobilerun_sdk/resources/models.py +++ b/src/mobilerun_sdk/resources/models.py @@ -20,8 +20,6 @@ class ModelsResource(SyncAPIResource): - """LLM Models""" - @cached_property def with_raw_response(self) -> ModelsResourceWithRawResponse: """ @@ -62,8 +60,6 @@ def list( class AsyncModelsResource(AsyncAPIResource): - """LLM Models""" - @cached_property def with_raw_response(self) -> AsyncModelsResourceWithRawResponse: """ diff --git a/src/mobilerun_sdk/resources/proxies.py b/src/mobilerun_sdk/resources/proxies.py index 4abd363..1e8cfed 100644 --- a/src/mobilerun_sdk/resources/proxies.py +++ b/src/mobilerun_sdk/resources/proxies.py @@ -2,13 +2,11 @@ from __future__ import annotations -from typing_extensions import Literal, overload - import httpx -from ..types import proxy_list_params, proxy_create_params, proxy_lookup_params, proxy_update_params -from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import path_template, required_args, maybe_transform, async_maybe_transform +from ..types import proxy_lookup_params +from .._types import Body, Query, Headers, NotGiven, not_given +from .._utils import maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -18,19 +16,12 @@ async_to_streamed_response_wrapper, ) from .._base_client import make_request_options -from ..types.proxy_list_response import ProxyListResponse -from ..types.proxy_create_response import ProxyCreateResponse -from ..types.proxy_delete_response import ProxyDeleteResponse from ..types.proxy_lookup_response import ProxyLookupResponse -from ..types.proxy_update_response import ProxyUpdateResponse -from ..types.proxy_retrieve_response import ProxyRetrieveResponse __all__ = ["ProxiesResource", "AsyncProxiesResource"] class ProxiesResource(SyncAPIResource): - """Network Proxies""" - @cached_property def with_raw_response(self) -> ProxiesResourceWithRawResponse: """ @@ -50,306 +41,6 @@ def with_streaming_response(self) -> ProxiesResourceWithStreamingResponse: """ return ProxiesResourceWithStreamingResponse(self) - @overload - def create( - self, - *, - host: str, - name: str, - password: str, - port: int, - protocol: Literal["socks5"], - user: str, - # 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, - ) -> ProxyCreateResponse: - """ - Create a new proxy config - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - ... - - @overload - def create( - self, - *, - config: str, - name: str, - protocol: Literal["wireguard"], - # 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, - ) -> ProxyCreateResponse: - """ - Create a new proxy config - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - ... - - @required_args(["host", "name", "password", "port", "protocol", "user"], ["config", "name", "protocol"]) - def create( - self, - *, - host: str | Omit = omit, - name: str, - password: str | Omit = omit, - port: int | Omit = omit, - protocol: Literal["socks5"] | Literal["wireguard"], - user: str | Omit = omit, - config: 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, - ) -> ProxyCreateResponse: - return self._post( - "/proxies", - body=maybe_transform( - { - "host": host, - "name": name, - "password": password, - "port": port, - "protocol": protocol, - "user": user, - "config": config, - }, - proxy_create_params.ProxyCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=ProxyCreateResponse, - ) - - def retrieve( - self, - proxy_id: str, - *, - # 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, - ) -> ProxyRetrieveResponse: - """ - Get a specific proxy config - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not proxy_id: - raise ValueError(f"Expected a non-empty value for `proxy_id` but received {proxy_id!r}") - return self._get( - 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 - ), - cast_to=ProxyRetrieveResponse, - ) - - @overload - def update( - self, - proxy_id: str, - *, - host: str, - name: str, - password: str, - port: int, - protocol: Literal["socks5"], - user: str, - # 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, - ) -> ProxyUpdateResponse: - """ - Update a proxy config - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - ... - - @overload - def update( - self, - proxy_id: str, - *, - config: str, - name: str, - protocol: Literal["wireguard"], - # 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, - ) -> ProxyUpdateResponse: - """ - Update a proxy config - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - ... - - @required_args(["host", "name", "password", "port", "protocol", "user"], ["config", "name", "protocol"]) - def update( - self, - proxy_id: str, - *, - host: str | Omit = omit, - name: str, - password: str | Omit = omit, - port: int | Omit = omit, - protocol: Literal["socks5"] | Literal["wireguard"], - user: str | Omit = omit, - config: 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, - ) -> ProxyUpdateResponse: - if not proxy_id: - raise ValueError(f"Expected a non-empty value for `proxy_id` but received {proxy_id!r}") - return self._put( - path_template("/proxies/{proxy_id}", proxy_id=proxy_id), - body=maybe_transform( - { - "host": host, - "name": name, - "password": password, - "port": port, - "protocol": protocol, - "user": user, - "config": config, - }, - proxy_update_params.ProxyUpdateParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=ProxyUpdateResponse, - ) - - def list( - self, - *, - protocol: Literal["socks5", "wireguard"] | 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, - ) -> ProxyListResponse: - """ - List all proxy configs for the authenticated user - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._get( - "/proxies", - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform({"protocol": protocol}, proxy_list_params.ProxyListParams), - ), - cast_to=ProxyListResponse, - ) - - def delete( - self, - proxy_id: str, - *, - # 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, - ) -> ProxyDeleteResponse: - """ - Delete a proxy config - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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 - ), - cast_to=ProxyDeleteResponse, - ) - def lookup( self, *, @@ -386,8 +77,6 @@ def lookup( class AsyncProxiesResource(AsyncAPIResource): - """Network Proxies""" - @cached_property def with_raw_response(self) -> AsyncProxiesResourceWithRawResponse: """ @@ -407,306 +96,6 @@ def with_streaming_response(self) -> AsyncProxiesResourceWithStreamingResponse: """ return AsyncProxiesResourceWithStreamingResponse(self) - @overload - async def create( - self, - *, - host: str, - name: str, - password: str, - port: int, - protocol: Literal["socks5"], - user: str, - # 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, - ) -> ProxyCreateResponse: - """ - Create a new proxy config - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - ... - - @overload - async def create( - self, - *, - config: str, - name: str, - protocol: Literal["wireguard"], - # 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, - ) -> ProxyCreateResponse: - """ - Create a new proxy config - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - ... - - @required_args(["host", "name", "password", "port", "protocol", "user"], ["config", "name", "protocol"]) - async def create( - self, - *, - host: str | Omit = omit, - name: str, - password: str | Omit = omit, - port: int | Omit = omit, - protocol: Literal["socks5"] | Literal["wireguard"], - user: str | Omit = omit, - config: 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, - ) -> ProxyCreateResponse: - return await self._post( - "/proxies", - body=await async_maybe_transform( - { - "host": host, - "name": name, - "password": password, - "port": port, - "protocol": protocol, - "user": user, - "config": config, - }, - proxy_create_params.ProxyCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=ProxyCreateResponse, - ) - - async def retrieve( - self, - proxy_id: str, - *, - # 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, - ) -> ProxyRetrieveResponse: - """ - Get a specific proxy config - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not proxy_id: - raise ValueError(f"Expected a non-empty value for `proxy_id` but received {proxy_id!r}") - return await self._get( - 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 - ), - cast_to=ProxyRetrieveResponse, - ) - - @overload - async def update( - self, - proxy_id: str, - *, - host: str, - name: str, - password: str, - port: int, - protocol: Literal["socks5"], - user: str, - # 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, - ) -> ProxyUpdateResponse: - """ - Update a proxy config - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - ... - - @overload - async def update( - self, - proxy_id: str, - *, - config: str, - name: str, - protocol: Literal["wireguard"], - # 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, - ) -> ProxyUpdateResponse: - """ - Update a proxy config - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - ... - - @required_args(["host", "name", "password", "port", "protocol", "user"], ["config", "name", "protocol"]) - async def update( - self, - proxy_id: str, - *, - host: str | Omit = omit, - name: str, - password: str | Omit = omit, - port: int | Omit = omit, - protocol: Literal["socks5"] | Literal["wireguard"], - user: str | Omit = omit, - config: 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, - ) -> ProxyUpdateResponse: - if not proxy_id: - raise ValueError(f"Expected a non-empty value for `proxy_id` but received {proxy_id!r}") - return await self._put( - path_template("/proxies/{proxy_id}", proxy_id=proxy_id), - body=await async_maybe_transform( - { - "host": host, - "name": name, - "password": password, - "port": port, - "protocol": protocol, - "user": user, - "config": config, - }, - proxy_update_params.ProxyUpdateParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=ProxyUpdateResponse, - ) - - async def list( - self, - *, - protocol: Literal["socks5", "wireguard"] | 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, - ) -> ProxyListResponse: - """ - List all proxy configs for the authenticated user - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return await self._get( - "/proxies", - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=await async_maybe_transform({"protocol": protocol}, proxy_list_params.ProxyListParams), - ), - cast_to=ProxyListResponse, - ) - - async def delete( - self, - proxy_id: str, - *, - # 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, - ) -> ProxyDeleteResponse: - """ - Delete a proxy config - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - 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 - ), - cast_to=ProxyDeleteResponse, - ) - async def lookup( self, *, @@ -746,21 +135,6 @@ class ProxiesResourceWithRawResponse: def __init__(self, proxies: ProxiesResource) -> None: self._proxies = proxies - self.create = to_raw_response_wrapper( - proxies.create, - ) - self.retrieve = to_raw_response_wrapper( - proxies.retrieve, - ) - self.update = to_raw_response_wrapper( - proxies.update, - ) - self.list = to_raw_response_wrapper( - proxies.list, - ) - self.delete = to_raw_response_wrapper( - proxies.delete, - ) self.lookup = to_raw_response_wrapper( proxies.lookup, ) @@ -770,21 +144,6 @@ class AsyncProxiesResourceWithRawResponse: def __init__(self, proxies: AsyncProxiesResource) -> None: self._proxies = proxies - self.create = async_to_raw_response_wrapper( - proxies.create, - ) - self.retrieve = async_to_raw_response_wrapper( - proxies.retrieve, - ) - self.update = async_to_raw_response_wrapper( - proxies.update, - ) - self.list = async_to_raw_response_wrapper( - proxies.list, - ) - self.delete = async_to_raw_response_wrapper( - proxies.delete, - ) self.lookup = async_to_raw_response_wrapper( proxies.lookup, ) @@ -794,21 +153,6 @@ class ProxiesResourceWithStreamingResponse: def __init__(self, proxies: ProxiesResource) -> None: self._proxies = proxies - self.create = to_streamed_response_wrapper( - proxies.create, - ) - self.retrieve = to_streamed_response_wrapper( - proxies.retrieve, - ) - self.update = to_streamed_response_wrapper( - proxies.update, - ) - self.list = to_streamed_response_wrapper( - proxies.list, - ) - self.delete = to_streamed_response_wrapper( - proxies.delete, - ) self.lookup = to_streamed_response_wrapper( proxies.lookup, ) @@ -818,21 +162,6 @@ class AsyncProxiesResourceWithStreamingResponse: def __init__(self, proxies: AsyncProxiesResource) -> None: self._proxies = proxies - self.create = async_to_streamed_response_wrapper( - proxies.create, - ) - self.retrieve = async_to_streamed_response_wrapper( - proxies.retrieve, - ) - self.update = async_to_streamed_response_wrapper( - proxies.update, - ) - self.list = async_to_streamed_response_wrapper( - proxies.list, - ) - self.delete = async_to_streamed_response_wrapper( - proxies.delete, - ) self.lookup = async_to_streamed_response_wrapper( proxies.lookup, ) diff --git a/src/mobilerun_sdk/types/__init__.py b/src/mobilerun_sdk/types/__init__.py index abff37b..94667ef 100644 --- a/src/mobilerun_sdk/types/__init__.py +++ b/src/mobilerun_sdk/types/__init__.py @@ -9,7 +9,6 @@ Socks5 as Socks5, Location as Location, DeviceSpec as DeviceSpec, - Pagination as Pagination, DeviceCarrier as DeviceCarrier, PermissionSet as PermissionSet, PaginationMeta as PaginationMeta, @@ -19,35 +18,28 @@ from .task_status import TaskStatus as TaskStatus from .proxy_config import ProxyConfig as ProxyConfig from .usage_result import UsageResult as UsageResult -from .app_list_params import AppListParams as AppListParams from .task_run_params import TaskRunParams as TaskRunParams from .hook_list_params import HookListParams as HookListParams from .hook_test_params import HookTestParams as HookTestParams from .task_list_params import TaskListParams as TaskListParams -from .app_list_response import AppListResponse as AppListResponse -from .proxy_list_params import ProxyListParams as ProxyListParams from .task_run_response import TaskRunResponse as TaskRunResponse from .device_list_params import DeviceListParams as DeviceListParams from .hook_list_response import HookListResponse as HookListResponse from .hook_test_response import HookTestResponse as HookTestResponse from .hook_update_params import HookUpdateParams as HookUpdateParams +from .proxy_config_param import ProxyConfigParam as ProxyConfigParam from .task_list_response import TaskListResponse as TaskListResponse from .task_stop_response import TaskStopResponse as TaskStopResponse from .agent_list_response import AgentListResponse as AgentListResponse -from .app_delete_response import AppDeleteResponse as AppDeleteResponse from .carrier_list_params import CarrierListParams as CarrierListParams from .hook_perform_params import HookPerformParams as HookPerformParams from .model_list_response import ModelListResponse as ModelListResponse from .package_credentials import PackageCredentials as PackageCredentials from .profile_list_params import ProfileListParams as ProfileListParams -from .proxy_create_params import ProxyCreateParams as ProxyCreateParams -from .proxy_list_response import ProxyListResponse as ProxyListResponse from .proxy_lookup_params import ProxyLookupParams as ProxyLookupParams -from .proxy_update_params import ProxyUpdateParams as ProxyUpdateParams from .device_create_params import DeviceCreateParams as DeviceCreateParams from .device_list_response import DeviceListResponse as DeviceListResponse from .hook_update_response import HookUpdateResponse as HookUpdateResponse -from .app_retrieve_response import AppRetrieveResponse as AppRetrieveResponse from .carrier_create_params import CarrierCreateParams as CarrierCreateParams from .carrier_list_response import CarrierListResponse as CarrierListResponse from .carrier_lookup_params import CarrierLookupParams as CarrierLookupParams @@ -58,11 +50,7 @@ from .profile_create_params import ProfileCreateParams as ProfileCreateParams from .profile_list_response import ProfileListResponse as ProfileListResponse from .profile_update_params import ProfileUpdateParams as ProfileUpdateParams -from .proxy_create_response import ProxyCreateResponse as ProxyCreateResponse -from .proxy_delete_response import ProxyDeleteResponse as ProxyDeleteResponse from .proxy_lookup_response import ProxyLookupResponse as ProxyLookupResponse -from .proxy_update_response import ProxyUpdateResponse as ProxyUpdateResponse -from .credential_list_params import CredentialListParams as CredentialListParams from .device_set_name_params import DeviceSetNameParams as DeviceSetNameParams from .hook_retrieve_response import HookRetrieveResponse as HookRetrieveResponse from .task_retrieve_response import TaskRetrieveResponse as TaskRetrieveResponse @@ -73,20 +61,13 @@ from .device_terminate_params import DeviceTerminateParams as DeviceTerminateParams from .hook_subscribe_response import HookSubscribeResponse as HookSubscribeResponse from .profile_delete_response import ProfileDeleteResponse as ProfileDeleteResponse -from .proxy_retrieve_response import ProxyRetrieveResponse as ProxyRetrieveResponse -from .app_mark_failed_response import AppMarkFailedResponse as AppMarkFailedResponse -from .credential_list_response import CredentialListResponse as CredentialListResponse from .task_get_status_response import TaskGetStatusResponse as TaskGetStatusResponse from .task_run_streamed_params import TaskRunStreamedParams as TaskRunStreamedParams from .task_send_message_params import TaskSendMessageParams as TaskSendMessageParams from .carrier_retrieve_response import CarrierRetrieveResponse as CarrierRetrieveResponse from .hook_unsubscribe_response import HookUnsubscribeResponse as HookUnsubscribeResponse from .package_credentials_param import PackageCredentialsParam as PackageCredentialsParam -from .app_list_versions_response import AppListVersionsResponse as AppListVersionsResponse from .task_send_message_response import TaskSendMessageResponse as TaskSendMessageResponse -from .app_confirm_upload_response import AppConfirmUploadResponse as AppConfirmUploadResponse from .device_fingerprint_response import DeviceFingerprintResponse as DeviceFingerprintResponse from .task_get_trajectory_response import TaskGetTrajectoryResponse as TaskGetTrajectoryResponse from .hook_get_sample_data_response import HookGetSampleDataResponse as HookGetSampleDataResponse -from .app_create_signed_upload_url_params import AppCreateSignedUploadURLParams as AppCreateSignedUploadURLParams -from .app_create_signed_upload_url_response import AppCreateSignedUploadURLResponse as AppCreateSignedUploadURLResponse diff --git a/src/mobilerun_sdk/types/app_confirm_upload_response.py b/src/mobilerun_sdk/types/app_confirm_upload_response.py deleted file mode 100644 index da579dc..0000000 --- a/src/mobilerun_sdk/types/app_confirm_upload_response.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal - -from .._models import BaseModel - -__all__ = ["AppConfirmUploadResponse"] - - -class AppConfirmUploadResponse(BaseModel): - message: str - - success: Literal[True] diff --git a/src/mobilerun_sdk/types/app_create_signed_upload_url_params.py b/src/mobilerun_sdk/types/app_create_signed_upload_url_params.py deleted file mode 100644 index a374c4b..0000000 --- a/src/mobilerun_sdk/types/app_create_signed_upload_url_params.py +++ /dev/null @@ -1,43 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Iterable -from typing_extensions import Literal, Required, Annotated, TypedDict - -from .._utils import PropertyInfo - -__all__ = ["AppCreateSignedUploadURLParams", "File"] - - -class AppCreateSignedUploadURLParams(TypedDict, total=False): - bundle_id: Required[Annotated[str, PropertyInfo(alias="bundleId")]] - - display_name: Required[Annotated[str, PropertyInfo(alias="displayName")]] - - files: Required[Iterable[File]] - - size_bytes: Required[Annotated[float, PropertyInfo(alias="sizeBytes")]] - - version_code: Required[Annotated[float, PropertyInfo(alias="versionCode")]] - - version_name: Required[Annotated[str, PropertyInfo(alias="versionName")]] - - country: str - """Country code for Search Results""" - - description: str - - developer_name: Annotated[str, PropertyInfo(alias="developerName")] - - icon_url: Annotated[str, PropertyInfo(alias="iconURL")] - - platform: Literal["android", "ios"] - - target_sdk: Annotated[float, PropertyInfo(alias="targetSdk")] - - -class File(TypedDict, total=False): - content_type: Required[Annotated[str, PropertyInfo(alias="contentType")]] - - file_name: Required[Annotated[str, PropertyInfo(alias="fileName")]] diff --git a/src/mobilerun_sdk/types/app_create_signed_upload_url_response.py b/src/mobilerun_sdk/types/app_create_signed_upload_url_response.py deleted file mode 100644 index 8d15581..0000000 --- a/src/mobilerun_sdk/types/app_create_signed_upload_url_response.py +++ /dev/null @@ -1,26 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List - -from pydantic import Field as FieldInfo - -from .._models import BaseModel - -__all__ = ["AppCreateSignedUploadURLResponse", "R2UploadURL"] - - -class R2UploadURL(BaseModel): - file_name: str = FieldInfo(alias="fileName") - - r2_upload_url: str = FieldInfo(alias="r2UploadUrl") - - -class AppCreateSignedUploadURLResponse(BaseModel): - app_id: str = FieldInfo(alias="appId") - """App ID in the database""" - - r2_upload_urls: List[R2UploadURL] = FieldInfo(alias="r2UploadUrls") - """Pre-signed Cloudflare R2 URLs for uploading app files""" - - version_id: str = FieldInfo(alias="versionId") - """App version ID in the database""" diff --git a/src/mobilerun_sdk/types/app_delete_response.py b/src/mobilerun_sdk/types/app_delete_response.py deleted file mode 100644 index 5dce5fa..0000000 --- a/src/mobilerun_sdk/types/app_delete_response.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal - -from .._models import BaseModel - -__all__ = ["AppDeleteResponse"] - - -class AppDeleteResponse(BaseModel): - message: str - - success: Literal[True] diff --git a/src/mobilerun_sdk/types/app_list_params.py b/src/mobilerun_sdk/types/app_list_params.py deleted file mode 100644 index 319c937..0000000 --- a/src/mobilerun_sdk/types/app_list_params.py +++ /dev/null @@ -1,25 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Literal, Annotated, TypedDict - -from .._utils import PropertyInfo - -__all__ = ["AppListParams"] - - -class AppListParams(TypedDict, total=False): - order: Literal["asc", "desc"] - - page: int - - page_size: Annotated[int, PropertyInfo(alias="pageSize")] - - platform: Literal["all", "android", "ios"] - - query: str - - sort_by: Annotated[Literal["createdAt", "name"], PropertyInfo(alias="sortBy")] - - status: Literal["all", "queued", "available", "failed"] diff --git a/src/mobilerun_sdk/types/app_list_response.py b/src/mobilerun_sdk/types/app_list_response.py deleted file mode 100644 index f7e2394..0000000 --- a/src/mobilerun_sdk/types/app_list_response.py +++ /dev/null @@ -1,333 +0,0 @@ -# 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 -from .shared.pagination import Pagination - -__all__ = ["AppListResponse", "Count", "Item", "ItemVersion"] - - -class Count(BaseModel): - available_count: float = FieldInfo(alias="availableCount") - - failed_count: float = FieldInfo(alias="failedCount") - - queued_count: float = FieldInfo(alias="queuedCount") - - total_count: float = FieldInfo(alias="totalCount") - - -class ItemVersion(BaseModel): - id: str - - app_id: str = FieldInfo(alias="appId") - - country: Literal[ - "AF", - "AL", - "DZ", - "AS", - "AD", - "AO", - "AI", - "AQ", - "AG", - "AR", - "AM", - "AW", - "AP", - "AU", - "AT", - "AZ", - "BS", - "BH", - "BD", - "BB", - "BY", - "BE", - "BZ", - "BJ", - "BM", - "BT", - "BO", - "BQ", - "BA", - "BW", - "BV", - "BR", - "IO", - "BN", - "BG", - "BF", - "BI", - "KH", - "CM", - "CA", - "CV", - "KY", - "CF", - "TD", - "CL", - "CN", - "CX", - "CC", - "CO", - "KM", - "CG", - "CD", - "CK", - "CR", - "HR", - "CU", - "CW", - "CY", - "CZ", - "CI", - "DK", - "DJ", - "DM", - "DO", - "EC", - "EG", - "SV", - "GQ", - "ER", - "EE", - "ET", - "FK", - "FO", - "FJ", - "FI", - "FR", - "GF", - "PF", - "TF", - "GA", - "GM", - "GE", - "DE", - "GH", - "GI", - "GR", - "GL", - "GD", - "GP", - "GU", - "GT", - "GG", - "GN", - "GW", - "GY", - "HT", - "HM", - "VA", - "HN", - "HK", - "HU", - "IS", - "IN", - "ID", - "IR", - "IQ", - "IE", - "IM", - "IL", - "IT", - "JM", - "JP", - "JE", - "JO", - "KZ", - "KE", - "KI", - "KR", - "KW", - "KG", - "LA", - "LV", - "LB", - "LS", - "LR", - "LY", - "LI", - "LT", - "LU", - "MO", - "MG", - "MW", - "MY", - "MV", - "ML", - "MT", - "MH", - "MQ", - "MR", - "MU", - "YT", - "MX", - "FM", - "MD", - "MC", - "MN", - "ME", - "MS", - "MA", - "MZ", - "MM", - "NA", - "NR", - "NP", - "NL", - "AN", - "NC", - "NZ", - "NI", - "NE", - "NG", - "NU", - "NF", - "KP", - "MK", - "MP", - "NO", - "OM", - "PK", - "PW", - "PS", - "PA", - "PG", - "PY", - "PE", - "PH", - "PN", - "PL", - "PT", - "PR", - "QA", - "RE", - "RO", - "RU", - "RW", - "BL", - "SH", - "KN", - "LC", - "MF", - "PM", - "VC", - "WS", - "SM", - "ST", - "SA", - "SN", - "RS", - "CS", - "SC", - "SL", - "SG", - "SX", - "SK", - "SI", - "SB", - "SO", - "ZA", - "GS", - "SS", - "ES", - "LK", - "SD", - "SR", - "SJ", - "SZ", - "SE", - "CH", - "SY", - "TW", - "TJ", - "TZ", - "TH", - "TL", - "TG", - "TK", - "TO", - "TT", - "TN", - "TR", - "TM", - "TC", - "TV", - "UG", - "UA", - "AE", - "GB", - "US", - "UM", - "UY", - "UZ", - "VU", - "VE", - "VN", - "VG", - "VI", - "WF", - "EH", - "YE", - "ZM", - "ZW", - "AX", - ] - - created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None) - - queued_at: Optional[datetime] = FieldInfo(alias="queuedAt", default=None) - - size_bytes: Optional[int] = FieldInfo(alias="sizeBytes", default=None) - - source: Literal["user", "system", "portal"] - - status: Literal["queued", "available", "failed"] - - target_sdk: Optional[int] = FieldInfo(alias="targetSdk", default=None) - - updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None) - - user_id: Optional[str] = FieldInfo(alias="userId", default=None) - - version_code: int = FieldInfo(alias="versionCode") - - version_name: str = FieldInfo(alias="versionName") - - -class Item(BaseModel): - id: str - - bundle_id: str = FieldInfo(alias="bundleId") - - created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None) - - description: Optional[str] = None - - developer_name: Optional[str] = FieldInfo(alias="developerName", default=None) - - display_name: str = FieldInfo(alias="displayName") - - icon_url: str = FieldInfo(alias="iconURL") - - platform: Literal["android", "ios"] - - updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None) - - version: ItemVersion - - -class AppListResponse(BaseModel): - count: Count - - items: List[Item] - - pagination: Pagination diff --git a/src/mobilerun_sdk/types/app_list_versions_response.py b/src/mobilerun_sdk/types/app_list_versions_response.py deleted file mode 100644 index 130eab8..0000000 --- a/src/mobilerun_sdk/types/app_list_versions_response.py +++ /dev/null @@ -1,296 +0,0 @@ -# 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__ = ["AppListVersionsResponse", "Data"] - - -class Data(BaseModel): - id: str - - app_id: str = FieldInfo(alias="appId") - - country: Literal[ - "AF", - "AL", - "DZ", - "AS", - "AD", - "AO", - "AI", - "AQ", - "AG", - "AR", - "AM", - "AW", - "AP", - "AU", - "AT", - "AZ", - "BS", - "BH", - "BD", - "BB", - "BY", - "BE", - "BZ", - "BJ", - "BM", - "BT", - "BO", - "BQ", - "BA", - "BW", - "BV", - "BR", - "IO", - "BN", - "BG", - "BF", - "BI", - "KH", - "CM", - "CA", - "CV", - "KY", - "CF", - "TD", - "CL", - "CN", - "CX", - "CC", - "CO", - "KM", - "CG", - "CD", - "CK", - "CR", - "HR", - "CU", - "CW", - "CY", - "CZ", - "CI", - "DK", - "DJ", - "DM", - "DO", - "EC", - "EG", - "SV", - "GQ", - "ER", - "EE", - "ET", - "FK", - "FO", - "FJ", - "FI", - "FR", - "GF", - "PF", - "TF", - "GA", - "GM", - "GE", - "DE", - "GH", - "GI", - "GR", - "GL", - "GD", - "GP", - "GU", - "GT", - "GG", - "GN", - "GW", - "GY", - "HT", - "HM", - "VA", - "HN", - "HK", - "HU", - "IS", - "IN", - "ID", - "IR", - "IQ", - "IE", - "IM", - "IL", - "IT", - "JM", - "JP", - "JE", - "JO", - "KZ", - "KE", - "KI", - "KR", - "KW", - "KG", - "LA", - "LV", - "LB", - "LS", - "LR", - "LY", - "LI", - "LT", - "LU", - "MO", - "MG", - "MW", - "MY", - "MV", - "ML", - "MT", - "MH", - "MQ", - "MR", - "MU", - "YT", - "MX", - "FM", - "MD", - "MC", - "MN", - "ME", - "MS", - "MA", - "MZ", - "MM", - "NA", - "NR", - "NP", - "NL", - "AN", - "NC", - "NZ", - "NI", - "NE", - "NG", - "NU", - "NF", - "KP", - "MK", - "MP", - "NO", - "OM", - "PK", - "PW", - "PS", - "PA", - "PG", - "PY", - "PE", - "PH", - "PN", - "PL", - "PT", - "PR", - "QA", - "RE", - "RO", - "RU", - "RW", - "BL", - "SH", - "KN", - "LC", - "MF", - "PM", - "VC", - "WS", - "SM", - "ST", - "SA", - "SN", - "RS", - "CS", - "SC", - "SL", - "SG", - "SX", - "SK", - "SI", - "SB", - "SO", - "ZA", - "GS", - "SS", - "ES", - "LK", - "SD", - "SR", - "SJ", - "SZ", - "SE", - "CH", - "SY", - "TW", - "TJ", - "TZ", - "TH", - "TL", - "TG", - "TK", - "TO", - "TT", - "TN", - "TR", - "TM", - "TC", - "TV", - "UG", - "UA", - "AE", - "GB", - "US", - "UM", - "UY", - "UZ", - "VU", - "VE", - "VN", - "VG", - "VI", - "WF", - "EH", - "YE", - "ZM", - "ZW", - "AX", - ] - - created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None) - - queued_at: Optional[datetime] = FieldInfo(alias="queuedAt", default=None) - - size_bytes: Optional[int] = FieldInfo(alias="sizeBytes", default=None) - - source: Literal["user", "system", "portal"] - - status: Literal["queued", "available", "failed"] - - target_sdk: Optional[int] = FieldInfo(alias="targetSdk", default=None) - - updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None) - - user_id: Optional[str] = FieldInfo(alias="userId", default=None) - - version_code: int = FieldInfo(alias="versionCode") - - version_name: str = FieldInfo(alias="versionName") - - -class AppListVersionsResponse(BaseModel): - data: List[Data] diff --git a/src/mobilerun_sdk/types/app_mark_failed_response.py b/src/mobilerun_sdk/types/app_mark_failed_response.py deleted file mode 100644 index 4df598b..0000000 --- a/src/mobilerun_sdk/types/app_mark_failed_response.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal - -from .._models import BaseModel - -__all__ = ["AppMarkFailedResponse"] - - -class AppMarkFailedResponse(BaseModel): - message: str - - success: Literal[True] diff --git a/src/mobilerun_sdk/types/app_retrieve_response.py b/src/mobilerun_sdk/types/app_retrieve_response.py deleted file mode 100644 index 57fd551..0000000 --- a/src/mobilerun_sdk/types/app_retrieve_response.py +++ /dev/null @@ -1,35 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Optional -from datetime import datetime -from typing_extensions import Literal - -from pydantic import Field as FieldInfo - -from .._models import BaseModel - -__all__ = ["AppRetrieveResponse", "Data"] - - -class Data(BaseModel): - id: str - - bundle_id: str = FieldInfo(alias="bundleId") - - created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None) - - description: Optional[str] = None - - developer_name: Optional[str] = FieldInfo(alias="developerName", default=None) - - display_name: str = FieldInfo(alias="displayName") - - icon_url: str = FieldInfo(alias="iconURL") - - platform: Literal["android", "ios"] - - updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None) - - -class AppRetrieveResponse(BaseModel): - data: Data diff --git a/src/mobilerun_sdk/types/credential_list_params.py b/src/mobilerun_sdk/types/credential_list_params.py deleted file mode 100644 index 1f94a2e..0000000 --- a/src/mobilerun_sdk/types/credential_list_params.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Annotated, TypedDict - -from .._utils import PropertyInfo - -__all__ = ["CredentialListParams"] - - -class CredentialListParams(TypedDict, total=False): - page: int - - page_size: Annotated[int, PropertyInfo(alias="pageSize")] diff --git a/src/mobilerun_sdk/types/credential_list_response.py b/src/mobilerun_sdk/types/credential_list_response.py deleted file mode 100644 index 0721b2b..0000000 --- a/src/mobilerun_sdk/types/credential_list_response.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List - -from .._models import BaseModel -from .shared.pagination import Pagination -from .credentials.packages.credential import Credential - -__all__ = ["CredentialListResponse"] - - -class CredentialListResponse(BaseModel): - items: List[Credential] - - pagination: Pagination diff --git a/src/mobilerun_sdk/types/credentials/__init__.py b/src/mobilerun_sdk/types/credentials/__init__.py index d2b799c..f8ee8b1 100644 --- a/src/mobilerun_sdk/types/credentials/__init__.py +++ b/src/mobilerun_sdk/types/credentials/__init__.py @@ -1,7 +1,3 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations - -from .package_create_params import PackageCreateParams as PackageCreateParams -from .package_list_response import PackageListResponse as PackageListResponse -from .package_create_response import PackageCreateResponse as PackageCreateResponse diff --git a/src/mobilerun_sdk/types/credentials/package_create_params.py b/src/mobilerun_sdk/types/credentials/package_create_params.py deleted file mode 100644 index 50dad4a..0000000 --- a/src/mobilerun_sdk/types/credentials/package_create_params.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, Annotated, TypedDict - -from ..._utils import PropertyInfo - -__all__ = ["PackageCreateParams"] - - -class PackageCreateParams(TypedDict, total=False): - package_name: Required[Annotated[str, PropertyInfo(alias="packageName")]] diff --git a/src/mobilerun_sdk/types/credentials/package_create_response.py b/src/mobilerun_sdk/types/credentials/package_create_response.py deleted file mode 100644 index 8ff9fa8..0000000 --- a/src/mobilerun_sdk/types/credentials/package_create_response.py +++ /dev/null @@ -1,21 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal - -from pydantic import Field as FieldInfo - -from ..._models import BaseModel - -__all__ = ["PackageCreateResponse", "Data"] - - -class Data(BaseModel): - package_name: str = FieldInfo(alias="packageName") - - -class PackageCreateResponse(BaseModel): - data: Data - - message: str - - success: Literal[True] diff --git a/src/mobilerun_sdk/types/credentials/package_list_response.py b/src/mobilerun_sdk/types/credentials/package_list_response.py deleted file mode 100644 index c9567e1..0000000 --- a/src/mobilerun_sdk/types/credentials/package_list_response.py +++ /dev/null @@ -1,12 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List - -from ..._models import BaseModel -from .packages.credential import Credential - -__all__ = ["PackageListResponse"] - - -class PackageListResponse(BaseModel): - data: List[Credential] diff --git a/src/mobilerun_sdk/types/credentials/packages/__init__.py b/src/mobilerun_sdk/types/credentials/packages/__init__.py index a3bddb0..f8ee8b1 100644 --- a/src/mobilerun_sdk/types/credentials/packages/__init__.py +++ b/src/mobilerun_sdk/types/credentials/packages/__init__.py @@ -1,9 +1,3 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations - -from .credential import Credential as Credential -from .credential_create_params import CredentialCreateParams as CredentialCreateParams -from .credential_create_response import CredentialCreateResponse as CredentialCreateResponse -from .credential_delete_response import CredentialDeleteResponse as CredentialDeleteResponse -from .credential_retrieve_response import CredentialRetrieveResponse as CredentialRetrieveResponse diff --git a/src/mobilerun_sdk/types/credentials/packages/credential.py b/src/mobilerun_sdk/types/credentials/packages/credential.py deleted file mode 100644 index 686342d..0000000 --- a/src/mobilerun_sdk/types/credentials/packages/credential.py +++ /dev/null @@ -1,30 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List -from typing_extensions import Literal - -from pydantic import Field as FieldInfo - -from ...._models import BaseModel - -__all__ = ["Credential", "Field"] - - -class Field(BaseModel): - field_type: Literal[ - "email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes" - ] = FieldInfo(alias="fieldType") - - value: str - - -class Credential(BaseModel): - credential_name: str = FieldInfo(alias="credentialName") - - fields: List[Field] - - package_name: str = FieldInfo(alias="packageName") - - secret_path: str = FieldInfo(alias="secretPath") - - user_id: str = FieldInfo(alias="userId") diff --git a/src/mobilerun_sdk/types/credentials/packages/credential_create_params.py b/src/mobilerun_sdk/types/credentials/packages/credential_create_params.py deleted file mode 100644 index 7925fa5..0000000 --- a/src/mobilerun_sdk/types/credentials/packages/credential_create_params.py +++ /dev/null @@ -1,27 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Iterable -from typing_extensions import Literal, Required, Annotated, TypedDict - -from ...._utils import PropertyInfo - -__all__ = ["CredentialCreateParams", "Field"] - - -class CredentialCreateParams(TypedDict, total=False): - credential_name: Required[Annotated[str, PropertyInfo(alias="credentialName")]] - - fields: Required[Iterable[Field]] - - -class Field(TypedDict, total=False): - field_type: Required[ - Annotated[ - Literal["email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes"], - PropertyInfo(alias="fieldType"), - ] - ] - - value: Required[str] diff --git a/src/mobilerun_sdk/types/credentials/packages/credential_create_response.py b/src/mobilerun_sdk/types/credentials/packages/credential_create_response.py deleted file mode 100644 index 56749ca..0000000 --- a/src/mobilerun_sdk/types/credentials/packages/credential_create_response.py +++ /dev/null @@ -1,16 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal - -from ...._models import BaseModel -from .credential import Credential - -__all__ = ["CredentialCreateResponse"] - - -class CredentialCreateResponse(BaseModel): - data: Credential - - message: str - - success: Literal[True] diff --git a/src/mobilerun_sdk/types/credentials/packages/credential_delete_response.py b/src/mobilerun_sdk/types/credentials/packages/credential_delete_response.py deleted file mode 100644 index 9fc9bf4..0000000 --- a/src/mobilerun_sdk/types/credentials/packages/credential_delete_response.py +++ /dev/null @@ -1,16 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal - -from ...._models import BaseModel -from .credential import Credential - -__all__ = ["CredentialDeleteResponse"] - - -class CredentialDeleteResponse(BaseModel): - data: Credential - - message: str - - success: Literal[True] diff --git a/src/mobilerun_sdk/types/credentials/packages/credential_retrieve_response.py b/src/mobilerun_sdk/types/credentials/packages/credential_retrieve_response.py deleted file mode 100644 index ea546cc..0000000 --- a/src/mobilerun_sdk/types/credentials/packages/credential_retrieve_response.py +++ /dev/null @@ -1,10 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from ...._models import BaseModel -from .credential import Credential - -__all__ = ["CredentialRetrieveResponse"] - - -class CredentialRetrieveResponse(BaseModel): - data: Credential diff --git a/src/mobilerun_sdk/types/credentials/packages/credentials/__init__.py b/src/mobilerun_sdk/types/credentials/packages/credentials/__init__.py index f3e7873..f8ee8b1 100644 --- a/src/mobilerun_sdk/types/credentials/packages/credentials/__init__.py +++ b/src/mobilerun_sdk/types/credentials/packages/credentials/__init__.py @@ -1,9 +1,3 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations - -from .field_create_params import FieldCreateParams as FieldCreateParams -from .field_update_params import FieldUpdateParams as FieldUpdateParams -from .field_create_response import FieldCreateResponse as FieldCreateResponse -from .field_delete_response import FieldDeleteResponse as FieldDeleteResponse -from .field_update_response import FieldUpdateResponse as FieldUpdateResponse diff --git a/src/mobilerun_sdk/types/credentials/packages/credentials/field_create_params.py b/src/mobilerun_sdk/types/credentials/packages/credentials/field_create_params.py deleted file mode 100644 index debabf7..0000000 --- a/src/mobilerun_sdk/types/credentials/packages/credentials/field_create_params.py +++ /dev/null @@ -1,22 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Literal, Required, Annotated, TypedDict - -from ....._utils import PropertyInfo - -__all__ = ["FieldCreateParams"] - - -class FieldCreateParams(TypedDict, total=False): - package_name: Required[Annotated[str, PropertyInfo(alias="packageName")]] - - field_type: Required[ - Annotated[ - Literal["email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes"], - PropertyInfo(alias="fieldType"), - ] - ] - - value: Required[str] diff --git a/src/mobilerun_sdk/types/credentials/packages/credentials/field_create_response.py b/src/mobilerun_sdk/types/credentials/packages/credentials/field_create_response.py deleted file mode 100644 index 2d7f2d0..0000000 --- a/src/mobilerun_sdk/types/credentials/packages/credentials/field_create_response.py +++ /dev/null @@ -1,16 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal - -from ....._models import BaseModel -from ..credential import Credential - -__all__ = ["FieldCreateResponse"] - - -class FieldCreateResponse(BaseModel): - data: Credential - - message: str - - success: Literal[True] diff --git a/src/mobilerun_sdk/types/credentials/packages/credentials/field_delete_response.py b/src/mobilerun_sdk/types/credentials/packages/credentials/field_delete_response.py deleted file mode 100644 index 67e99f8..0000000 --- a/src/mobilerun_sdk/types/credentials/packages/credentials/field_delete_response.py +++ /dev/null @@ -1,16 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal - -from ....._models import BaseModel -from ..credential import Credential - -__all__ = ["FieldDeleteResponse"] - - -class FieldDeleteResponse(BaseModel): - data: Credential - - message: str - - success: Literal[True] diff --git a/src/mobilerun_sdk/types/credentials/packages/credentials/field_update_params.py b/src/mobilerun_sdk/types/credentials/packages/credentials/field_update_params.py deleted file mode 100644 index ed62fb1..0000000 --- a/src/mobilerun_sdk/types/credentials/packages/credentials/field_update_params.py +++ /dev/null @@ -1,17 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, Annotated, TypedDict - -from ....._utils import PropertyInfo - -__all__ = ["FieldUpdateParams"] - - -class FieldUpdateParams(TypedDict, total=False): - package_name: Required[Annotated[str, PropertyInfo(alias="packageName")]] - - credential_name: Required[Annotated[str, PropertyInfo(alias="credentialName")]] - - value: Required[str] diff --git a/src/mobilerun_sdk/types/credentials/packages/credentials/field_update_response.py b/src/mobilerun_sdk/types/credentials/packages/credentials/field_update_response.py deleted file mode 100644 index 8676ce3..0000000 --- a/src/mobilerun_sdk/types/credentials/packages/credentials/field_update_response.py +++ /dev/null @@ -1,16 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal - -from ....._models import BaseModel -from ..credential import Credential - -__all__ = ["FieldUpdateResponse"] - - -class FieldUpdateResponse(BaseModel): - data: Credential - - message: str - - success: Literal[True] diff --git a/src/mobilerun_sdk/types/device_create_params.py b/src/mobilerun_sdk/types/device_create_params.py index a631b9c..6d5b9b0 100644 --- a/src/mobilerun_sdk/types/device_create_params.py +++ b/src/mobilerun_sdk/types/device_create_params.py @@ -7,12 +7,12 @@ from .._types import SequenceNotStr from .._utils import PropertyInfo -from .shared_params.socks5 import Socks5 +from .proxy_config_param import ProxyConfigParam from .shared_params.location import Location from .shared_params.device_carrier import DeviceCarrier from .shared_params.device_identifiers import DeviceIdentifiers -__all__ = ["DeviceCreateParams", "Proxy"] +__all__ = ["DeviceCreateParams"] class DeviceCreateParams(TypedDict, total=False): @@ -48,14 +48,6 @@ class DeviceCreateParams(TypedDict, total=False): name: str - proxy: Proxy + proxy: ProxyConfigParam timezone: str - - -class Proxy(TypedDict, total=False): - name: str - - smart_ip: Annotated[bool, PropertyInfo(alias="smartIp")] - - socks5: Socks5 diff --git a/src/mobilerun_sdk/types/devices/state_ui_response.py b/src/mobilerun_sdk/types/devices/state_ui_response.py index bdddd0c..80cbe44 100644 --- a/src/mobilerun_sdk/types/devices/state_ui_response.py +++ b/src/mobilerun_sdk/types/devices/state_ui_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Optional from pydantic import Field as FieldInfo @@ -9,14 +9,64 @@ __all__ = [ "StateUiResponse", + "A11yTree", + "A11yTreeBoundsInScreen", "DeviceContext", "DeviceContextDisplayMetrics", "DeviceContextFilteringParams", + "ImeTree", + "ImeTreeBoundsInScreen", "PhoneState", "PhoneStateFocusedElement", ] +class A11yTreeBoundsInScreen(BaseModel): + bottom: int + + left: int + + right: int + + top: int + + +class A11yTree(BaseModel): + bounds_in_screen: A11yTreeBoundsInScreen = FieldInfo(alias="boundsInScreen") + + children: Optional[List[object]] = None + + class_name: str = FieldInfo(alias="className") + + content_description: str = FieldInfo(alias="contentDescription") + + is_checkable: bool = FieldInfo(alias="isCheckable") + + is_checked: bool = FieldInfo(alias="isChecked") + + is_clickable: bool = FieldInfo(alias="isClickable") + + is_enabled: bool = FieldInfo(alias="isEnabled") + + is_focusable: bool = FieldInfo(alias="isFocusable") + + is_focused: bool = FieldInfo(alias="isFocused") + + is_long_clickable: bool = FieldInfo(alias="isLongClickable") + + is_password: bool = FieldInfo(alias="isPassword") + + is_scrollable: bool = FieldInfo(alias="isScrollable") + + is_selected: bool = FieldInfo(alias="isSelected") + + package_name: str = FieldInfo(alias="packageName") + + resource_id: str = FieldInfo(alias="resourceId") + + text: str + + class DeviceContextDisplayMetrics(BaseModel): density: float @@ -42,7 +92,51 @@ class DeviceContext(BaseModel): screen_bounds: Rect - screen_size: Rect = FieldInfo(alias="screenSize") + +class ImeTreeBoundsInScreen(BaseModel): + bottom: int + + left: int + + right: int + + top: int + + +class ImeTree(BaseModel): + bounds_in_screen: ImeTreeBoundsInScreen = FieldInfo(alias="boundsInScreen") + + children: Optional[List[object]] = None + + class_name: str = FieldInfo(alias="className") + + content_description: str = FieldInfo(alias="contentDescription") + + is_checkable: bool = FieldInfo(alias="isCheckable") + + is_checked: bool = FieldInfo(alias="isChecked") + + is_clickable: bool = FieldInfo(alias="isClickable") + + is_enabled: bool = FieldInfo(alias="isEnabled") + + is_focusable: bool = FieldInfo(alias="isFocusable") + + is_focused: bool = FieldInfo(alias="isFocused") + + is_long_clickable: bool = FieldInfo(alias="isLongClickable") + + is_password: bool = FieldInfo(alias="isPassword") + + is_scrollable: bool = FieldInfo(alias="isScrollable") + + is_selected: bool = FieldInfo(alias="isSelected") + + package_name: str = FieldInfo(alias="packageName") + + resource_id: str = FieldInfo(alias="resourceId") + + text: str class PhoneStateFocusedElement(BaseModel): @@ -68,13 +162,13 @@ class PhoneState(BaseModel): class StateUiResponse(BaseModel): - a11y_tree: object + a11y_tree: A11yTree device_context: DeviceContext + ime_tree: ImeTree + phone_state: PhoneState schema_: Optional[str] = FieldInfo(alias="$schema", default=None) """A URL to the JSON Schema for this object.""" - - ime_tree: Optional[object] = None diff --git a/src/mobilerun_sdk/types/proxy_config.py b/src/mobilerun_sdk/types/proxy_config.py index 52d651c..5a5715b 100644 --- a/src/mobilerun_sdk/types/proxy_config.py +++ b/src/mobilerun_sdk/types/proxy_config.py @@ -1,42 +1,18 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Union -from typing_extensions import Literal, Annotated, TypeAlias +from typing import Optional from pydantic import Field as FieldInfo -from .._utils import PropertyInfo from .._models import BaseModel +from .shared.socks5 import Socks5 -__all__ = ["ProxyConfig", "Socks5ProxyConfig", "WireguardProxyConfig"] +__all__ = ["ProxyConfig"] -class Socks5ProxyConfig(BaseModel): - host: str +class ProxyConfig(BaseModel): + name: Optional[str] = None - name: str + smart_ip: Optional[bool] = FieldInfo(alias="smartIp", default=None) - password: str - - port: int - - protocol: Literal["socks5"] - - proxy_id: str = FieldInfo(alias="proxyId") - - user: str - - -class WireguardProxyConfig(BaseModel): - config: str - - name: str - - protocol: Literal["wireguard"] - - proxy_id: str = FieldInfo(alias="proxyId") - - -ProxyConfig: TypeAlias = Annotated[ - Union[Socks5ProxyConfig, WireguardProxyConfig], PropertyInfo(discriminator="protocol") -] + socks5: Optional[Socks5] = None diff --git a/src/mobilerun_sdk/types/proxy_config_param.py b/src/mobilerun_sdk/types/proxy_config_param.py new file mode 100644 index 0000000..c169125 --- /dev/null +++ b/src/mobilerun_sdk/types/proxy_config_param.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Annotated, TypedDict + +from .._utils import PropertyInfo +from .shared_params.socks5 import Socks5 + +__all__ = ["ProxyConfigParam"] + + +class ProxyConfigParam(TypedDict, total=False): + name: str + + smart_ip: Annotated[bool, PropertyInfo(alias="smartIp")] + + socks5: Socks5 diff --git a/src/mobilerun_sdk/types/proxy_create_params.py b/src/mobilerun_sdk/types/proxy_create_params.py deleted file mode 100644 index 1d9fdf4..0000000 --- a/src/mobilerun_sdk/types/proxy_create_params.py +++ /dev/null @@ -1,33 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Union -from typing_extensions import Literal, Required, TypeAlias, TypedDict - -__all__ = ["ProxyCreateParams", "CreateSocks5Proxy", "CreateWireguardProxy"] - - -class CreateSocks5Proxy(TypedDict, total=False): - host: Required[str] - - name: Required[str] - - password: Required[str] - - port: Required[int] - - protocol: Required[Literal["socks5"]] - - user: Required[str] - - -class CreateWireguardProxy(TypedDict, total=False): - config: Required[str] - - name: Required[str] - - protocol: Required[Literal["wireguard"]] - - -ProxyCreateParams: TypeAlias = Union[CreateSocks5Proxy, CreateWireguardProxy] diff --git a/src/mobilerun_sdk/types/proxy_create_response.py b/src/mobilerun_sdk/types/proxy_create_response.py deleted file mode 100644 index 72a8d2c..0000000 --- a/src/mobilerun_sdk/types/proxy_create_response.py +++ /dev/null @@ -1,16 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal - -from .._models import BaseModel -from .proxy_config import ProxyConfig - -__all__ = ["ProxyCreateResponse"] - - -class ProxyCreateResponse(BaseModel): - data: ProxyConfig - - message: str - - success: Literal[True] diff --git a/src/mobilerun_sdk/types/proxy_delete_response.py b/src/mobilerun_sdk/types/proxy_delete_response.py deleted file mode 100644 index 872567b..0000000 --- a/src/mobilerun_sdk/types/proxy_delete_response.py +++ /dev/null @@ -1,16 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal - -from .._models import BaseModel -from .proxy_config import ProxyConfig - -__all__ = ["ProxyDeleteResponse"] - - -class ProxyDeleteResponse(BaseModel): - data: ProxyConfig - - message: str - - success: Literal[True] diff --git a/src/mobilerun_sdk/types/proxy_list_params.py b/src/mobilerun_sdk/types/proxy_list_params.py deleted file mode 100644 index 6b3d14f..0000000 --- a/src/mobilerun_sdk/types/proxy_list_params.py +++ /dev/null @@ -1,11 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Literal, TypedDict - -__all__ = ["ProxyListParams"] - - -class ProxyListParams(TypedDict, total=False): - protocol: Literal["socks5", "wireguard"] diff --git a/src/mobilerun_sdk/types/proxy_list_response.py b/src/mobilerun_sdk/types/proxy_list_response.py deleted file mode 100644 index ff49af0..0000000 --- a/src/mobilerun_sdk/types/proxy_list_response.py +++ /dev/null @@ -1,12 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List - -from .._models import BaseModel -from .proxy_config import ProxyConfig - -__all__ = ["ProxyListResponse"] - - -class ProxyListResponse(BaseModel): - data: List[ProxyConfig] diff --git a/src/mobilerun_sdk/types/proxy_retrieve_response.py b/src/mobilerun_sdk/types/proxy_retrieve_response.py deleted file mode 100644 index 6c6a1c5..0000000 --- a/src/mobilerun_sdk/types/proxy_retrieve_response.py +++ /dev/null @@ -1,10 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from .._models import BaseModel -from .proxy_config import ProxyConfig - -__all__ = ["ProxyRetrieveResponse"] - - -class ProxyRetrieveResponse(BaseModel): - data: ProxyConfig diff --git a/src/mobilerun_sdk/types/proxy_update_params.py b/src/mobilerun_sdk/types/proxy_update_params.py deleted file mode 100644 index ab81ede..0000000 --- a/src/mobilerun_sdk/types/proxy_update_params.py +++ /dev/null @@ -1,33 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Union -from typing_extensions import Literal, Required, TypeAlias, TypedDict - -__all__ = ["ProxyUpdateParams", "UpdateSocks5Proxy", "UpdateWireguardProxy"] - - -class UpdateSocks5Proxy(TypedDict, total=False): - host: Required[str] - - name: Required[str] - - password: Required[str] - - port: Required[int] - - protocol: Required[Literal["socks5"]] - - user: Required[str] - - -class UpdateWireguardProxy(TypedDict, total=False): - config: Required[str] - - name: Required[str] - - protocol: Required[Literal["wireguard"]] - - -ProxyUpdateParams: TypeAlias = Union[UpdateSocks5Proxy, UpdateWireguardProxy] diff --git a/src/mobilerun_sdk/types/proxy_update_response.py b/src/mobilerun_sdk/types/proxy_update_response.py deleted file mode 100644 index f1578b4..0000000 --- a/src/mobilerun_sdk/types/proxy_update_response.py +++ /dev/null @@ -1,16 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal - -from .._models import BaseModel -from .proxy_config import ProxyConfig - -__all__ = ["ProxyUpdateResponse"] - - -class ProxyUpdateResponse(BaseModel): - data: ProxyConfig - - message: str - - success: Literal[True] diff --git a/src/mobilerun_sdk/types/shared/__init__.py b/src/mobilerun_sdk/types/shared/__init__.py index 7d0f116..92ac387 100644 --- a/src/mobilerun_sdk/types/shared/__init__.py +++ b/src/mobilerun_sdk/types/shared/__init__.py @@ -3,7 +3,6 @@ from .meta import Meta as Meta from .socks5 import Socks5 as Socks5 from .location import Location as Location -from .pagination import Pagination as Pagination from .device_spec import DeviceSpec as DeviceSpec from .device_carrier import DeviceCarrier as DeviceCarrier from .permission_set import PermissionSet as PermissionSet diff --git a/src/mobilerun_sdk/types/shared/device_spec.py b/src/mobilerun_sdk/types/shared/device_spec.py index 64614c9..0cbc319 100644 --- a/src/mobilerun_sdk/types/shared/device_spec.py +++ b/src/mobilerun_sdk/types/shared/device_spec.py @@ -4,21 +4,13 @@ from pydantic import Field as FieldInfo -from .socks5 import Socks5 from .location import Location from ..._models import BaseModel +from ..proxy_config import ProxyConfig from .device_carrier import DeviceCarrier from .device_identifiers import DeviceIdentifiers -__all__ = ["DeviceSpec", "Proxy"] - - -class Proxy(BaseModel): - name: Optional[str] = None - - smart_ip: Optional[bool] = FieldInfo(alias="smartIp", default=None) - - socks5: Optional[Socks5] = None +__all__ = ["DeviceSpec"] class DeviceSpec(BaseModel): @@ -43,6 +35,6 @@ class DeviceSpec(BaseModel): name: Optional[str] = None - proxy: Optional[Proxy] = None + proxy: Optional[ProxyConfig] = None timezone: Optional[str] = None diff --git a/src/mobilerun_sdk/types/shared/pagination.py b/src/mobilerun_sdk/types/shared/pagination.py deleted file mode 100644 index d5a8b19..0000000 --- a/src/mobilerun_sdk/types/shared/pagination.py +++ /dev/null @@ -1,21 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from pydantic import Field as FieldInfo - -from ..._models import BaseModel - -__all__ = ["Pagination"] - - -class Pagination(BaseModel): - has_next: bool = FieldInfo(alias="hasNext") - - has_prev: bool = FieldInfo(alias="hasPrev") - - page: int - - pages: int - - page_size: int = FieldInfo(alias="pageSize") - - total: int diff --git a/src/mobilerun_sdk/types/shared_params/device_spec.py b/src/mobilerun_sdk/types/shared_params/device_spec.py index 7d1a43e..90a7c89 100644 --- a/src/mobilerun_sdk/types/shared_params/device_spec.py +++ b/src/mobilerun_sdk/types/shared_params/device_spec.py @@ -5,22 +5,14 @@ from typing import Optional from typing_extensions import Annotated, TypedDict -from .socks5 import Socks5 from ..._types import SequenceNotStr from ..._utils import PropertyInfo from .location import Location from .device_carrier import DeviceCarrier from .device_identifiers import DeviceIdentifiers +from ..proxy_config_param import ProxyConfigParam -__all__ = ["DeviceSpec", "Proxy"] - - -class Proxy(TypedDict, total=False): - name: str - - smart_ip: Annotated[bool, PropertyInfo(alias="smartIp")] - - socks5: Socks5 +__all__ = ["DeviceSpec"] class DeviceSpec(TypedDict, total=False): @@ -42,6 +34,6 @@ class DeviceSpec(TypedDict, total=False): name: str - proxy: Proxy + proxy: ProxyConfigParam timezone: str diff --git a/tests/api_resources/credentials/__init__.py b/tests/api_resources/credentials/__init__.py deleted file mode 100644 index fd8019a..0000000 --- a/tests/api_resources/credentials/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/credentials/packages/__init__.py b/tests/api_resources/credentials/packages/__init__.py deleted file mode 100644 index fd8019a..0000000 --- a/tests/api_resources/credentials/packages/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/credentials/packages/credentials/__init__.py b/tests/api_resources/credentials/packages/credentials/__init__.py deleted file mode 100644 index fd8019a..0000000 --- a/tests/api_resources/credentials/packages/credentials/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/credentials/packages/credentials/test_fields.py b/tests/api_resources/credentials/packages/credentials/test_fields.py deleted file mode 100644 index b16a174..0000000 --- a/tests/api_resources/credentials/packages/credentials/test_fields.py +++ /dev/null @@ -1,390 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from tests.utils import assert_matches_type -from mobilerun_sdk import Mobilerun, AsyncMobilerun -from mobilerun_sdk.types.credentials.packages.credentials import ( - FieldCreateResponse, - FieldDeleteResponse, - FieldUpdateResponse, -) - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestFields: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create(self, client: Mobilerun) -> None: - field = client.credentials.packages.credentials.fields.create( - credential_name="credentialName", - package_name="packageName", - field_type="email", - value="x", - ) - assert_matches_type(FieldCreateResponse, field, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_create(self, client: Mobilerun) -> None: - response = client.credentials.packages.credentials.fields.with_raw_response.create( - credential_name="credentialName", - package_name="packageName", - field_type="email", - value="x", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - field = response.parse() - assert_matches_type(FieldCreateResponse, field, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_create(self, client: Mobilerun) -> None: - with client.credentials.packages.credentials.fields.with_streaming_response.create( - credential_name="credentialName", - package_name="packageName", - field_type="email", - value="x", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - field = response.parse() - assert_matches_type(FieldCreateResponse, field, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_create(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - client.credentials.packages.credentials.fields.with_raw_response.create( - credential_name="credentialName", - package_name="", - field_type="email", - value="x", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): - client.credentials.packages.credentials.fields.with_raw_response.create( - credential_name="", - package_name="packageName", - field_type="email", - value="x", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_update(self, client: Mobilerun) -> None: - field = client.credentials.packages.credentials.fields.update( - field_type="email", - package_name="packageName", - credential_name="credentialName", - value="x", - ) - assert_matches_type(FieldUpdateResponse, field, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_update(self, client: Mobilerun) -> None: - response = client.credentials.packages.credentials.fields.with_raw_response.update( - field_type="email", - package_name="packageName", - credential_name="credentialName", - value="x", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - field = response.parse() - assert_matches_type(FieldUpdateResponse, field, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_update(self, client: Mobilerun) -> None: - with client.credentials.packages.credentials.fields.with_streaming_response.update( - field_type="email", - package_name="packageName", - credential_name="credentialName", - value="x", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - field = response.parse() - assert_matches_type(FieldUpdateResponse, field, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_update(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - client.credentials.packages.credentials.fields.with_raw_response.update( - field_type="email", - package_name="", - credential_name="credentialName", - value="x", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): - client.credentials.packages.credentials.fields.with_raw_response.update( - field_type="email", - package_name="packageName", - credential_name="", - value="x", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_delete(self, client: Mobilerun) -> None: - field = client.credentials.packages.credentials.fields.delete( - field_type="email", - package_name="packageName", - credential_name="credentialName", - ) - assert_matches_type(FieldDeleteResponse, field, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_delete(self, client: Mobilerun) -> None: - response = client.credentials.packages.credentials.fields.with_raw_response.delete( - field_type="email", - package_name="packageName", - credential_name="credentialName", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - field = response.parse() - assert_matches_type(FieldDeleteResponse, field, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_delete(self, client: Mobilerun) -> None: - with client.credentials.packages.credentials.fields.with_streaming_response.delete( - field_type="email", - package_name="packageName", - credential_name="credentialName", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - field = response.parse() - assert_matches_type(FieldDeleteResponse, field, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_delete(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - client.credentials.packages.credentials.fields.with_raw_response.delete( - field_type="email", - package_name="", - credential_name="credentialName", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): - client.credentials.packages.credentials.fields.with_raw_response.delete( - field_type="email", - package_name="packageName", - credential_name="", - ) - - -class TestAsyncFields: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create(self, async_client: AsyncMobilerun) -> None: - field = await async_client.credentials.packages.credentials.fields.create( - credential_name="credentialName", - package_name="packageName", - field_type="email", - value="x", - ) - assert_matches_type(FieldCreateResponse, field, path=["response"]) - - @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.credentials.packages.credentials.fields.with_raw_response.create( - credential_name="credentialName", - package_name="packageName", - field_type="email", - value="x", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - field = await response.parse() - assert_matches_type(FieldCreateResponse, field, path=["response"]) - - @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.credentials.packages.credentials.fields.with_streaming_response.create( - credential_name="credentialName", - package_name="packageName", - field_type="email", - value="x", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - field = await response.parse() - assert_matches_type(FieldCreateResponse, field, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_create(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - await async_client.credentials.packages.credentials.fields.with_raw_response.create( - credential_name="credentialName", - package_name="", - field_type="email", - value="x", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): - await async_client.credentials.packages.credentials.fields.with_raw_response.create( - credential_name="", - package_name="packageName", - field_type="email", - value="x", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_update(self, async_client: AsyncMobilerun) -> None: - field = await async_client.credentials.packages.credentials.fields.update( - field_type="email", - package_name="packageName", - credential_name="credentialName", - value="x", - ) - assert_matches_type(FieldUpdateResponse, field, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_update(self, async_client: AsyncMobilerun) -> None: - response = await async_client.credentials.packages.credentials.fields.with_raw_response.update( - field_type="email", - package_name="packageName", - credential_name="credentialName", - value="x", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - field = await response.parse() - assert_matches_type(FieldUpdateResponse, field, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_update(self, async_client: AsyncMobilerun) -> None: - async with async_client.credentials.packages.credentials.fields.with_streaming_response.update( - field_type="email", - package_name="packageName", - credential_name="credentialName", - value="x", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - field = await response.parse() - assert_matches_type(FieldUpdateResponse, field, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_update(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - await async_client.credentials.packages.credentials.fields.with_raw_response.update( - field_type="email", - package_name="", - credential_name="credentialName", - value="x", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): - await async_client.credentials.packages.credentials.fields.with_raw_response.update( - field_type="email", - package_name="packageName", - credential_name="", - value="x", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_delete(self, async_client: AsyncMobilerun) -> None: - field = await async_client.credentials.packages.credentials.fields.delete( - field_type="email", - package_name="packageName", - credential_name="credentialName", - ) - assert_matches_type(FieldDeleteResponse, field, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_delete(self, async_client: AsyncMobilerun) -> None: - response = await async_client.credentials.packages.credentials.fields.with_raw_response.delete( - field_type="email", - package_name="packageName", - credential_name="credentialName", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - field = await response.parse() - assert_matches_type(FieldDeleteResponse, field, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_delete(self, async_client: AsyncMobilerun) -> None: - async with async_client.credentials.packages.credentials.fields.with_streaming_response.delete( - field_type="email", - package_name="packageName", - credential_name="credentialName", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - field = await response.parse() - assert_matches_type(FieldDeleteResponse, field, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_delete(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - await async_client.credentials.packages.credentials.fields.with_raw_response.delete( - field_type="email", - package_name="", - credential_name="credentialName", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): - await async_client.credentials.packages.credentials.fields.with_raw_response.delete( - field_type="email", - package_name="packageName", - credential_name="", - ) diff --git a/tests/api_resources/credentials/packages/test_credentials.py b/tests/api_resources/credentials/packages/test_credentials.py deleted file mode 100644 index 991d557..0000000 --- a/tests/api_resources/credentials/packages/test_credentials.py +++ /dev/null @@ -1,376 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from tests.utils import assert_matches_type -from mobilerun_sdk import Mobilerun, AsyncMobilerun -from mobilerun_sdk.types.credentials.packages import ( - CredentialCreateResponse, - CredentialDeleteResponse, - CredentialRetrieveResponse, -) - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestCredentials: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create(self, client: Mobilerun) -> None: - credential = client.credentials.packages.credentials.create( - package_name="packageName", - credential_name="26f1kl_-n-71", - fields=[ - { - "field_type": "email", - "value": "x", - } - ], - ) - assert_matches_type(CredentialCreateResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_create(self, client: Mobilerun) -> None: - response = client.credentials.packages.credentials.with_raw_response.create( - package_name="packageName", - credential_name="26f1kl_-n-71", - fields=[ - { - "field_type": "email", - "value": "x", - } - ], - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - credential = response.parse() - assert_matches_type(CredentialCreateResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_create(self, client: Mobilerun) -> None: - with client.credentials.packages.credentials.with_streaming_response.create( - package_name="packageName", - credential_name="26f1kl_-n-71", - fields=[ - { - "field_type": "email", - "value": "x", - } - ], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - credential = response.parse() - assert_matches_type(CredentialCreateResponse, credential, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_create(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - client.credentials.packages.credentials.with_raw_response.create( - package_name="", - credential_name="26f1kl_-n-71", - fields=[ - { - "field_type": "email", - "value": "x", - } - ], - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_retrieve(self, client: Mobilerun) -> None: - credential = client.credentials.packages.credentials.retrieve( - credential_name="credentialName", - package_name="packageName", - ) - assert_matches_type(CredentialRetrieveResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_retrieve(self, client: Mobilerun) -> None: - response = client.credentials.packages.credentials.with_raw_response.retrieve( - credential_name="credentialName", - package_name="packageName", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - credential = response.parse() - assert_matches_type(CredentialRetrieveResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_retrieve(self, client: Mobilerun) -> None: - with client.credentials.packages.credentials.with_streaming_response.retrieve( - credential_name="credentialName", - package_name="packageName", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - credential = response.parse() - assert_matches_type(CredentialRetrieveResponse, credential, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_retrieve(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - client.credentials.packages.credentials.with_raw_response.retrieve( - credential_name="credentialName", - package_name="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): - client.credentials.packages.credentials.with_raw_response.retrieve( - credential_name="", - package_name="packageName", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_delete(self, client: Mobilerun) -> None: - credential = client.credentials.packages.credentials.delete( - credential_name="credentialName", - package_name="packageName", - ) - assert_matches_type(CredentialDeleteResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_delete(self, client: Mobilerun) -> None: - response = client.credentials.packages.credentials.with_raw_response.delete( - credential_name="credentialName", - package_name="packageName", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - credential = response.parse() - assert_matches_type(CredentialDeleteResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_delete(self, client: Mobilerun) -> None: - with client.credentials.packages.credentials.with_streaming_response.delete( - credential_name="credentialName", - package_name="packageName", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - credential = response.parse() - assert_matches_type(CredentialDeleteResponse, credential, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_delete(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - client.credentials.packages.credentials.with_raw_response.delete( - credential_name="credentialName", - package_name="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): - client.credentials.packages.credentials.with_raw_response.delete( - credential_name="", - package_name="packageName", - ) - - -class TestAsyncCredentials: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create(self, async_client: AsyncMobilerun) -> None: - credential = await async_client.credentials.packages.credentials.create( - package_name="packageName", - credential_name="26f1kl_-n-71", - fields=[ - { - "field_type": "email", - "value": "x", - } - ], - ) - assert_matches_type(CredentialCreateResponse, credential, path=["response"]) - - @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.credentials.packages.credentials.with_raw_response.create( - package_name="packageName", - credential_name="26f1kl_-n-71", - fields=[ - { - "field_type": "email", - "value": "x", - } - ], - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - credential = await response.parse() - assert_matches_type(CredentialCreateResponse, credential, path=["response"]) - - @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.credentials.packages.credentials.with_streaming_response.create( - package_name="packageName", - credential_name="26f1kl_-n-71", - fields=[ - { - "field_type": "email", - "value": "x", - } - ], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - credential = await response.parse() - assert_matches_type(CredentialCreateResponse, credential, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_create(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - await async_client.credentials.packages.credentials.with_raw_response.create( - package_name="", - credential_name="26f1kl_-n-71", - fields=[ - { - "field_type": "email", - "value": "x", - } - ], - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_retrieve(self, async_client: AsyncMobilerun) -> None: - credential = await async_client.credentials.packages.credentials.retrieve( - credential_name="credentialName", - package_name="packageName", - ) - assert_matches_type(CredentialRetrieveResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_retrieve(self, async_client: AsyncMobilerun) -> None: - response = await async_client.credentials.packages.credentials.with_raw_response.retrieve( - credential_name="credentialName", - package_name="packageName", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - credential = await response.parse() - assert_matches_type(CredentialRetrieveResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_retrieve(self, async_client: AsyncMobilerun) -> None: - async with async_client.credentials.packages.credentials.with_streaming_response.retrieve( - credential_name="credentialName", - package_name="packageName", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - credential = await response.parse() - assert_matches_type(CredentialRetrieveResponse, credential, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_retrieve(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - await async_client.credentials.packages.credentials.with_raw_response.retrieve( - credential_name="credentialName", - package_name="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): - await async_client.credentials.packages.credentials.with_raw_response.retrieve( - credential_name="", - package_name="packageName", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_delete(self, async_client: AsyncMobilerun) -> None: - credential = await async_client.credentials.packages.credentials.delete( - credential_name="credentialName", - package_name="packageName", - ) - assert_matches_type(CredentialDeleteResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_delete(self, async_client: AsyncMobilerun) -> None: - response = await async_client.credentials.packages.credentials.with_raw_response.delete( - credential_name="credentialName", - package_name="packageName", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - credential = await response.parse() - assert_matches_type(CredentialDeleteResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_delete(self, async_client: AsyncMobilerun) -> None: - async with async_client.credentials.packages.credentials.with_streaming_response.delete( - credential_name="credentialName", - package_name="packageName", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - credential = await response.parse() - assert_matches_type(CredentialDeleteResponse, credential, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_delete(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - await async_client.credentials.packages.credentials.with_raw_response.delete( - credential_name="credentialName", - package_name="", - ) - - with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): - await async_client.credentials.packages.credentials.with_raw_response.delete( - credential_name="", - package_name="packageName", - ) diff --git a/tests/api_resources/credentials/test_packages.py b/tests/api_resources/credentials/test_packages.py deleted file mode 100644 index fe14887..0000000 --- a/tests/api_resources/credentials/test_packages.py +++ /dev/null @@ -1,176 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from tests.utils import assert_matches_type -from mobilerun_sdk import Mobilerun, AsyncMobilerun -from mobilerun_sdk.types.credentials import PackageListResponse, PackageCreateResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestPackages: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create(self, client: Mobilerun) -> None: - package = client.credentials.packages.create( - package_name="packageName", - ) - assert_matches_type(PackageCreateResponse, package, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_create(self, client: Mobilerun) -> None: - response = client.credentials.packages.with_raw_response.create( - package_name="packageName", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - package = response.parse() - assert_matches_type(PackageCreateResponse, package, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_create(self, client: Mobilerun) -> None: - with client.credentials.packages.with_streaming_response.create( - package_name="packageName", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - package = response.parse() - assert_matches_type(PackageCreateResponse, package, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_list(self, client: Mobilerun) -> None: - package = client.credentials.packages.list( - "packageName", - ) - assert_matches_type(PackageListResponse, package, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_list(self, client: Mobilerun) -> None: - response = client.credentials.packages.with_raw_response.list( - "packageName", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - package = response.parse() - assert_matches_type(PackageListResponse, package, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_list(self, client: Mobilerun) -> None: - with client.credentials.packages.with_streaming_response.list( - "packageName", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - package = response.parse() - assert_matches_type(PackageListResponse, package, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_list(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - client.credentials.packages.with_raw_response.list( - "", - ) - - -class TestAsyncPackages: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create(self, async_client: AsyncMobilerun) -> None: - package = await async_client.credentials.packages.create( - package_name="packageName", - ) - assert_matches_type(PackageCreateResponse, package, path=["response"]) - - @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.credentials.packages.with_raw_response.create( - package_name="packageName", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - package = await response.parse() - assert_matches_type(PackageCreateResponse, package, path=["response"]) - - @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.credentials.packages.with_streaming_response.create( - package_name="packageName", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - package = await response.parse() - assert_matches_type(PackageCreateResponse, package, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_list(self, async_client: AsyncMobilerun) -> None: - package = await async_client.credentials.packages.list( - "packageName", - ) - assert_matches_type(PackageListResponse, package, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: - response = await async_client.credentials.packages.with_raw_response.list( - "packageName", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - package = await response.parse() - assert_matches_type(PackageListResponse, package, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: - async with async_client.credentials.packages.with_streaming_response.list( - "packageName", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - package = await response.parse() - assert_matches_type(PackageListResponse, package, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_list(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): - await async_client.credentials.packages.with_raw_response.list( - "", - ) diff --git a/tests/api_resources/test_apps.py b/tests/api_resources/test_apps.py deleted file mode 100644 index 7fd88df..0000000 --- a/tests/api_resources/test_apps.py +++ /dev/null @@ -1,712 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from tests.utils import assert_matches_type -from mobilerun_sdk import Mobilerun, AsyncMobilerun -from mobilerun_sdk.types import ( - AppListResponse, - AppDeleteResponse, - AppRetrieveResponse, - AppMarkFailedResponse, - AppListVersionsResponse, - AppConfirmUploadResponse, - AppCreateSignedUploadURLResponse, -) - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestApps: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_retrieve(self, client: Mobilerun) -> None: - app = client.apps.retrieve( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(AppRetrieveResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_retrieve(self, client: Mobilerun) -> None: - response = client.apps.with_raw_response.retrieve( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = response.parse() - assert_matches_type(AppRetrieveResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_retrieve(self, client: Mobilerun) -> None: - with client.apps.with_streaming_response.retrieve( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - app = response.parse() - assert_matches_type(AppRetrieveResponse, app, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_retrieve(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): - client.apps.with_raw_response.retrieve( - "", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_list(self, client: Mobilerun) -> None: - app = client.apps.list() - assert_matches_type(AppListResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_list_with_all_params(self, client: Mobilerun) -> None: - app = client.apps.list( - order="asc", - page=1, - page_size=1, - platform="all", - query="query", - sort_by="createdAt", - status="all", - ) - assert_matches_type(AppListResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_list(self, client: Mobilerun) -> None: - response = client.apps.with_raw_response.list() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = response.parse() - assert_matches_type(AppListResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_list(self, client: Mobilerun) -> None: - with client.apps.with_streaming_response.list() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - app = response.parse() - assert_matches_type(AppListResponse, app, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_delete(self, client: Mobilerun) -> None: - app = client.apps.delete( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(AppDeleteResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_delete(self, client: Mobilerun) -> None: - response = client.apps.with_raw_response.delete( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = response.parse() - assert_matches_type(AppDeleteResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_delete(self, client: Mobilerun) -> None: - with client.apps.with_streaming_response.delete( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - app = response.parse() - assert_matches_type(AppDeleteResponse, app, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_delete(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): - client.apps.with_raw_response.delete( - "", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_confirm_upload(self, client: Mobilerun) -> None: - app = client.apps.confirm_upload( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(AppConfirmUploadResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_confirm_upload(self, client: Mobilerun) -> None: - response = client.apps.with_raw_response.confirm_upload( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = response.parse() - assert_matches_type(AppConfirmUploadResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_confirm_upload(self, client: Mobilerun) -> None: - with client.apps.with_streaming_response.confirm_upload( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - app = response.parse() - assert_matches_type(AppConfirmUploadResponse, app, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_confirm_upload(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): - client.apps.with_raw_response.confirm_upload( - "", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create_signed_upload_url(self, client: Mobilerun) -> None: - app = client.apps.create_signed_upload_url( - bundle_id="x", - display_name="x", - files=[ - { - "content_type": "x", - "file_name": "x", - } - ], - size_bytes=0, - version_code=0, - version_name="x", - ) - assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create_signed_upload_url_with_all_params(self, client: Mobilerun) -> None: - app = client.apps.create_signed_upload_url( - bundle_id="x", - display_name="x", - files=[ - { - "content_type": "x", - "file_name": "x", - } - ], - size_bytes=0, - version_code=0, - version_name="x", - country="US", - description="description", - developer_name="developerName", - icon_url="iconURL", - platform="android", - target_sdk=0, - ) - assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_create_signed_upload_url(self, client: Mobilerun) -> None: - response = client.apps.with_raw_response.create_signed_upload_url( - bundle_id="x", - display_name="x", - files=[ - { - "content_type": "x", - "file_name": "x", - } - ], - size_bytes=0, - version_code=0, - version_name="x", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = response.parse() - assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_create_signed_upload_url(self, client: Mobilerun) -> None: - with client.apps.with_streaming_response.create_signed_upload_url( - bundle_id="x", - display_name="x", - files=[ - { - "content_type": "x", - "file_name": "x", - } - ], - size_bytes=0, - version_code=0, - version_name="x", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - app = response.parse() - assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_list_versions(self, client: Mobilerun) -> None: - app = client.apps.list_versions( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(AppListVersionsResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_list_versions(self, client: Mobilerun) -> None: - response = client.apps.with_raw_response.list_versions( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = response.parse() - assert_matches_type(AppListVersionsResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_list_versions(self, client: Mobilerun) -> None: - with client.apps.with_streaming_response.list_versions( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - app = response.parse() - assert_matches_type(AppListVersionsResponse, app, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_list_versions(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): - client.apps.with_raw_response.list_versions( - "", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_mark_failed(self, client: Mobilerun) -> None: - app = client.apps.mark_failed( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(AppMarkFailedResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_mark_failed(self, client: Mobilerun) -> None: - response = client.apps.with_raw_response.mark_failed( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = response.parse() - assert_matches_type(AppMarkFailedResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_mark_failed(self, client: Mobilerun) -> None: - with client.apps.with_streaming_response.mark_failed( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - app = response.parse() - assert_matches_type(AppMarkFailedResponse, app, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_mark_failed(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): - client.apps.with_raw_response.mark_failed( - "", - ) - - -class TestAsyncApps: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_retrieve(self, async_client: AsyncMobilerun) -> None: - app = await async_client.apps.retrieve( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(AppRetrieveResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_retrieve(self, async_client: AsyncMobilerun) -> None: - response = await async_client.apps.with_raw_response.retrieve( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = await response.parse() - assert_matches_type(AppRetrieveResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_retrieve(self, async_client: AsyncMobilerun) -> None: - async with async_client.apps.with_streaming_response.retrieve( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - app = await response.parse() - assert_matches_type(AppRetrieveResponse, app, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_retrieve(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): - await async_client.apps.with_raw_response.retrieve( - "", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_list(self, async_client: AsyncMobilerun) -> None: - app = await async_client.apps.list() - assert_matches_type(AppListResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: - app = await async_client.apps.list( - order="asc", - page=1, - page_size=1, - platform="all", - query="query", - sort_by="createdAt", - status="all", - ) - assert_matches_type(AppListResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: - response = await async_client.apps.with_raw_response.list() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = await response.parse() - assert_matches_type(AppListResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: - async with async_client.apps.with_streaming_response.list() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - app = await response.parse() - assert_matches_type(AppListResponse, app, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_delete(self, async_client: AsyncMobilerun) -> None: - app = await async_client.apps.delete( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(AppDeleteResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_delete(self, async_client: AsyncMobilerun) -> None: - response = await async_client.apps.with_raw_response.delete( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = await response.parse() - assert_matches_type(AppDeleteResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_delete(self, async_client: AsyncMobilerun) -> None: - async with async_client.apps.with_streaming_response.delete( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - app = await response.parse() - assert_matches_type(AppDeleteResponse, app, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_delete(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): - await async_client.apps.with_raw_response.delete( - "", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_confirm_upload(self, async_client: AsyncMobilerun) -> None: - app = await async_client.apps.confirm_upload( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(AppConfirmUploadResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_confirm_upload(self, async_client: AsyncMobilerun) -> None: - response = await async_client.apps.with_raw_response.confirm_upload( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = await response.parse() - assert_matches_type(AppConfirmUploadResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_confirm_upload(self, async_client: AsyncMobilerun) -> None: - async with async_client.apps.with_streaming_response.confirm_upload( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - app = await response.parse() - assert_matches_type(AppConfirmUploadResponse, app, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_confirm_upload(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): - await async_client.apps.with_raw_response.confirm_upload( - "", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create_signed_upload_url(self, async_client: AsyncMobilerun) -> None: - app = await async_client.apps.create_signed_upload_url( - bundle_id="x", - display_name="x", - files=[ - { - "content_type": "x", - "file_name": "x", - } - ], - size_bytes=0, - version_code=0, - version_name="x", - ) - assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create_signed_upload_url_with_all_params(self, async_client: AsyncMobilerun) -> None: - app = await async_client.apps.create_signed_upload_url( - bundle_id="x", - display_name="x", - files=[ - { - "content_type": "x", - "file_name": "x", - } - ], - size_bytes=0, - version_code=0, - version_name="x", - country="US", - description="description", - developer_name="developerName", - icon_url="iconURL", - platform="android", - target_sdk=0, - ) - assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_create_signed_upload_url(self, async_client: AsyncMobilerun) -> None: - response = await async_client.apps.with_raw_response.create_signed_upload_url( - bundle_id="x", - display_name="x", - files=[ - { - "content_type": "x", - "file_name": "x", - } - ], - size_bytes=0, - version_code=0, - version_name="x", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = await response.parse() - assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_create_signed_upload_url(self, async_client: AsyncMobilerun) -> None: - async with async_client.apps.with_streaming_response.create_signed_upload_url( - bundle_id="x", - display_name="x", - files=[ - { - "content_type": "x", - "file_name": "x", - } - ], - size_bytes=0, - version_code=0, - version_name="x", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - app = await response.parse() - assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_list_versions(self, async_client: AsyncMobilerun) -> None: - app = await async_client.apps.list_versions( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(AppListVersionsResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_list_versions(self, async_client: AsyncMobilerun) -> None: - response = await async_client.apps.with_raw_response.list_versions( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = await response.parse() - assert_matches_type(AppListVersionsResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_list_versions(self, async_client: AsyncMobilerun) -> None: - async with async_client.apps.with_streaming_response.list_versions( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - app = await response.parse() - assert_matches_type(AppListVersionsResponse, app, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_list_versions(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): - await async_client.apps.with_raw_response.list_versions( - "", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_mark_failed(self, async_client: AsyncMobilerun) -> None: - app = await async_client.apps.mark_failed( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(AppMarkFailedResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_mark_failed(self, async_client: AsyncMobilerun) -> None: - response = await async_client.apps.with_raw_response.mark_failed( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - app = await response.parse() - assert_matches_type(AppMarkFailedResponse, app, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_mark_failed(self, async_client: AsyncMobilerun) -> None: - async with async_client.apps.with_streaming_response.mark_failed( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - app = await response.parse() - assert_matches_type(AppMarkFailedResponse, app, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_mark_failed(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): - await async_client.apps.with_raw_response.mark_failed( - "", - ) diff --git a/tests/api_resources/test_credentials.py b/tests/api_resources/test_credentials.py deleted file mode 100644 index d125d22..0000000 --- a/tests/api_resources/test_credentials.py +++ /dev/null @@ -1,98 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from tests.utils import assert_matches_type -from mobilerun_sdk import Mobilerun, AsyncMobilerun -from mobilerun_sdk.types import CredentialListResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestCredentials: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_list(self, client: Mobilerun) -> None: - credential = client.credentials.list() - assert_matches_type(CredentialListResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_list_with_all_params(self, client: Mobilerun) -> None: - credential = client.credentials.list( - page=1, - page_size=1, - ) - assert_matches_type(CredentialListResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_list(self, client: Mobilerun) -> None: - response = client.credentials.with_raw_response.list() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - credential = response.parse() - assert_matches_type(CredentialListResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_list(self, client: Mobilerun) -> None: - with client.credentials.with_streaming_response.list() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - credential = response.parse() - assert_matches_type(CredentialListResponse, credential, path=["response"]) - - assert cast(Any, response.is_closed) is True - - -class TestAsyncCredentials: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_list(self, async_client: AsyncMobilerun) -> None: - credential = await async_client.credentials.list() - assert_matches_type(CredentialListResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: - credential = await async_client.credentials.list( - page=1, - page_size=1, - ) - assert_matches_type(CredentialListResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: - response = await async_client.credentials.with_raw_response.list() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - credential = await response.parse() - assert_matches_type(CredentialListResponse, credential, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: - async with async_client.credentials.with_streaming_response.list() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - credential = await response.parse() - assert_matches_type(CredentialListResponse, credential, path=["response"]) - - assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_proxies.py b/tests/api_resources/test_proxies.py index b96cc4d..1a6fc78 100644 --- a/tests/api_resources/test_proxies.py +++ b/tests/api_resources/test_proxies.py @@ -9,14 +9,7 @@ from tests.utils import assert_matches_type from mobilerun_sdk import Mobilerun, AsyncMobilerun -from mobilerun_sdk.types import ( - ProxyListResponse, - ProxyCreateResponse, - ProxyDeleteResponse, - ProxyLookupResponse, - ProxyUpdateResponse, - ProxyRetrieveResponse, -) +from mobilerun_sdk.types import ProxyLookupResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -24,335 +17,6 @@ class TestProxies: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create_overload_1(self, client: Mobilerun) -> None: - proxy = client.proxies.create( - host="x", - name="xxx", - password="x", - port=1, - protocol="socks5", - user="x", - ) - assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_create_overload_1(self, client: Mobilerun) -> None: - response = client.proxies.with_raw_response.create( - host="x", - name="xxx", - password="x", - port=1, - protocol="socks5", - user="x", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - proxy = response.parse() - assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_create_overload_1(self, client: Mobilerun) -> None: - with client.proxies.with_streaming_response.create( - host="x", - name="xxx", - password="x", - port=1, - protocol="socks5", - user="x", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - proxy = response.parse() - assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create_overload_2(self, client: Mobilerun) -> None: - proxy = client.proxies.create( - config="x", - name="xxx", - protocol="wireguard", - ) - assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_create_overload_2(self, client: Mobilerun) -> None: - response = client.proxies.with_raw_response.create( - config="x", - name="xxx", - protocol="wireguard", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - proxy = response.parse() - assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_create_overload_2(self, client: Mobilerun) -> None: - with client.proxies.with_streaming_response.create( - config="x", - name="xxx", - protocol="wireguard", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - proxy = response.parse() - assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_retrieve(self, client: Mobilerun) -> None: - proxy = client.proxies.retrieve( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_retrieve(self, client: Mobilerun) -> None: - response = client.proxies.with_raw_response.retrieve( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - proxy = response.parse() - assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_retrieve(self, client: Mobilerun) -> None: - with client.proxies.with_streaming_response.retrieve( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - proxy = response.parse() - assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_retrieve(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): - client.proxies.with_raw_response.retrieve( - "", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_update_overload_1(self, client: Mobilerun) -> None: - proxy = client.proxies.update( - proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - host="x", - name="xxx", - password="x", - port=1, - protocol="socks5", - user="x", - ) - assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_update_overload_1(self, client: Mobilerun) -> None: - response = client.proxies.with_raw_response.update( - proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - host="x", - name="xxx", - password="x", - port=1, - protocol="socks5", - user="x", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - proxy = response.parse() - assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_update_overload_1(self, client: Mobilerun) -> None: - with client.proxies.with_streaming_response.update( - proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - host="x", - name="xxx", - password="x", - port=1, - protocol="socks5", - user="x", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - proxy = response.parse() - assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_update_overload_1(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): - client.proxies.with_raw_response.update( - proxy_id="", - host="x", - name="xxx", - password="x", - port=1, - protocol="socks5", - user="x", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_update_overload_2(self, client: Mobilerun) -> None: - proxy = client.proxies.update( - proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - config="x", - name="xxx", - protocol="wireguard", - ) - assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_update_overload_2(self, client: Mobilerun) -> None: - response = client.proxies.with_raw_response.update( - proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - config="x", - name="xxx", - protocol="wireguard", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - proxy = response.parse() - assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_update_overload_2(self, client: Mobilerun) -> None: - with client.proxies.with_streaming_response.update( - proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - config="x", - name="xxx", - protocol="wireguard", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - proxy = response.parse() - assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_update_overload_2(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): - client.proxies.with_raw_response.update( - proxy_id="", - config="x", - name="xxx", - protocol="wireguard", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_list(self, client: Mobilerun) -> None: - proxy = client.proxies.list() - assert_matches_type(ProxyListResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_list_with_all_params(self, client: Mobilerun) -> None: - proxy = client.proxies.list( - protocol="socks5", - ) - assert_matches_type(ProxyListResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_list(self, client: Mobilerun) -> None: - response = client.proxies.with_raw_response.list() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - proxy = response.parse() - assert_matches_type(ProxyListResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_list(self, client: Mobilerun) -> None: - with client.proxies.with_streaming_response.list() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - proxy = response.parse() - assert_matches_type(ProxyListResponse, proxy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_delete(self, client: Mobilerun) -> None: - proxy = client.proxies.delete( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(ProxyDeleteResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_delete(self, client: Mobilerun) -> None: - response = client.proxies.with_raw_response.delete( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - proxy = response.parse() - assert_matches_type(ProxyDeleteResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_delete(self, client: Mobilerun) -> None: - with client.proxies.with_streaming_response.delete( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - proxy = response.parse() - assert_matches_type(ProxyDeleteResponse, proxy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_delete(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): - client.proxies.with_raw_response.delete( - "", - ) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_lookup(self, client: Mobilerun) -> None: @@ -415,335 +79,6 @@ class TestAsyncProxies: "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create_overload_1(self, async_client: AsyncMobilerun) -> None: - proxy = await async_client.proxies.create( - host="x", - name="xxx", - password="x", - port=1, - protocol="socks5", - user="x", - ) - assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_create_overload_1(self, async_client: AsyncMobilerun) -> None: - response = await async_client.proxies.with_raw_response.create( - host="x", - name="xxx", - password="x", - port=1, - protocol="socks5", - user="x", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - proxy = await response.parse() - assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_create_overload_1(self, async_client: AsyncMobilerun) -> None: - async with async_client.proxies.with_streaming_response.create( - host="x", - name="xxx", - password="x", - port=1, - protocol="socks5", - user="x", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - proxy = await response.parse() - assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create_overload_2(self, async_client: AsyncMobilerun) -> None: - proxy = await async_client.proxies.create( - config="x", - name="xxx", - protocol="wireguard", - ) - assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_create_overload_2(self, async_client: AsyncMobilerun) -> None: - response = await async_client.proxies.with_raw_response.create( - config="x", - name="xxx", - protocol="wireguard", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - proxy = await response.parse() - assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_create_overload_2(self, async_client: AsyncMobilerun) -> None: - async with async_client.proxies.with_streaming_response.create( - config="x", - name="xxx", - protocol="wireguard", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - proxy = await response.parse() - assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_retrieve(self, async_client: AsyncMobilerun) -> None: - proxy = await async_client.proxies.retrieve( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_retrieve(self, async_client: AsyncMobilerun) -> None: - response = await async_client.proxies.with_raw_response.retrieve( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - proxy = await response.parse() - assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_retrieve(self, async_client: AsyncMobilerun) -> None: - async with async_client.proxies.with_streaming_response.retrieve( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - proxy = await response.parse() - assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_retrieve(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): - await async_client.proxies.with_raw_response.retrieve( - "", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_update_overload_1(self, async_client: AsyncMobilerun) -> None: - proxy = await async_client.proxies.update( - proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - host="x", - name="xxx", - password="x", - port=1, - protocol="socks5", - user="x", - ) - assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_update_overload_1(self, async_client: AsyncMobilerun) -> None: - response = await async_client.proxies.with_raw_response.update( - proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - host="x", - name="xxx", - password="x", - port=1, - protocol="socks5", - user="x", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - proxy = await response.parse() - assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_update_overload_1(self, async_client: AsyncMobilerun) -> None: - async with async_client.proxies.with_streaming_response.update( - proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - host="x", - name="xxx", - password="x", - port=1, - protocol="socks5", - user="x", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - proxy = await response.parse() - assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_update_overload_1(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): - await async_client.proxies.with_raw_response.update( - proxy_id="", - host="x", - name="xxx", - password="x", - port=1, - protocol="socks5", - user="x", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_update_overload_2(self, async_client: AsyncMobilerun) -> None: - proxy = await async_client.proxies.update( - proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - config="x", - name="xxx", - protocol="wireguard", - ) - assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_update_overload_2(self, async_client: AsyncMobilerun) -> None: - response = await async_client.proxies.with_raw_response.update( - proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - config="x", - name="xxx", - protocol="wireguard", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - proxy = await response.parse() - assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_update_overload_2(self, async_client: AsyncMobilerun) -> None: - async with async_client.proxies.with_streaming_response.update( - proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - config="x", - name="xxx", - protocol="wireguard", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - proxy = await response.parse() - assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_update_overload_2(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): - await async_client.proxies.with_raw_response.update( - proxy_id="", - config="x", - name="xxx", - protocol="wireguard", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_list(self, async_client: AsyncMobilerun) -> None: - proxy = await async_client.proxies.list() - assert_matches_type(ProxyListResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: - proxy = await async_client.proxies.list( - protocol="socks5", - ) - assert_matches_type(ProxyListResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: - response = await async_client.proxies.with_raw_response.list() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - proxy = await response.parse() - assert_matches_type(ProxyListResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: - async with async_client.proxies.with_streaming_response.list() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - proxy = await response.parse() - assert_matches_type(ProxyListResponse, proxy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_delete(self, async_client: AsyncMobilerun) -> None: - proxy = await async_client.proxies.delete( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(ProxyDeleteResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_delete(self, async_client: AsyncMobilerun) -> None: - response = await async_client.proxies.with_raw_response.delete( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - proxy = await response.parse() - assert_matches_type(ProxyDeleteResponse, proxy, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_delete(self, async_client: AsyncMobilerun) -> None: - async with async_client.proxies.with_streaming_response.delete( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - proxy = await response.parse() - assert_matches_type(ProxyDeleteResponse, proxy, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_delete(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): - await async_client.proxies.with_raw_response.delete( - "", - ) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_lookup(self, async_client: AsyncMobilerun) -> None: From 472689f40d0225edcedb331fabda5d9b5ddbe390 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 30 May 2026 12:59:06 +0000 Subject: [PATCH 05/21] feat(api): api update --- .stats.yml | 6 +- api.md | 104 ++- src/mobilerun_sdk/_client.py | 112 ++- src/mobilerun_sdk/resources/__init__.py | 28 + src/mobilerun_sdk/resources/apps.py | 748 ++++++++++++++++++ src/mobilerun_sdk/resources/carriers.py | 4 + .../resources/credentials/__init__.py | 33 + .../resources/credentials/credentials.py | 225 ++++++ .../credentials/packages/__init__.py | 33 + .../packages/credentials/__init__.py | 33 + .../packages/credentials/credentials.py | 413 ++++++++++ .../packages/credentials/fields.py | 421 ++++++++++ .../credentials/packages/packages.py | 284 +++++++ .../resources/devices/devices.py | 18 +- src/mobilerun_sdk/resources/devices/tasks.py | 4 + src/mobilerun_sdk/resources/hooks.py | 4 - src/mobilerun_sdk/resources/models.py | 4 + src/mobilerun_sdk/resources/proxies.py | 677 +++++++++++++++- src/mobilerun_sdk/types/__init__.py | 21 +- .../types/app_confirm_upload_response.py | 13 + .../app_create_signed_upload_url_params.py | 43 + .../app_create_signed_upload_url_response.py | 26 + .../types/app_delete_response.py | 13 + src/mobilerun_sdk/types/app_list_params.py | 25 + src/mobilerun_sdk/types/app_list_response.py | 333 ++++++++ .../types/app_list_versions_response.py | 296 +++++++ .../types/app_mark_failed_response.py | 13 + .../types/app_retrieve_response.py | 35 + .../types/credential_list_params.py | 15 + .../types/credential_list_response.py | 15 + .../types/credentials/__init__.py | 4 + .../credentials/package_create_params.py | 13 + .../credentials/package_create_response.py | 21 + .../credentials/package_list_response.py | 12 + .../types/credentials/packages/__init__.py | 6 + .../types/credentials/packages/credential.py | 30 + .../packages/credential_create_params.py | 27 + .../packages/credential_create_response.py | 16 + .../packages/credential_delete_response.py | 16 + .../packages/credential_retrieve_response.py | 10 + .../packages/credentials/__init__.py | 6 + .../credentials/field_create_params.py | 22 + .../credentials/field_create_response.py | 16 + .../credentials/field_delete_response.py | 16 + .../credentials/field_update_params.py | 17 + .../credentials/field_update_response.py | 16 + .../types/device_create_params.py | 14 +- .../types/devices/state_ui_response.py | 104 +-- src/mobilerun_sdk/types/proxy_config.py | 38 +- src/mobilerun_sdk/types/proxy_config_param.py | 18 - .../types/proxy_create_params.py | 33 + .../types/proxy_create_response.py | 16 + .../types/proxy_delete_response.py | 16 + src/mobilerun_sdk/types/proxy_list_params.py | 11 + .../types/proxy_list_response.py | 12 + .../types/proxy_retrieve_response.py | 10 + .../types/proxy_update_params.py | 33 + .../types/proxy_update_response.py | 16 + src/mobilerun_sdk/types/shared/__init__.py | 1 + src/mobilerun_sdk/types/shared/device_spec.py | 14 +- src/mobilerun_sdk/types/shared/pagination.py | 21 + .../types/shared_params/device_spec.py | 14 +- tests/api_resources/credentials/__init__.py | 1 + .../credentials/packages/__init__.py | 1 + .../packages/credentials/__init__.py | 1 + .../packages/credentials/test_fields.py | 390 +++++++++ .../credentials/packages/test_credentials.py | 376 +++++++++ .../credentials/test_packages.py | 176 +++++ tests/api_resources/test_apps.py | 712 +++++++++++++++++ tests/api_resources/test_credentials.py | 98 +++ tests/api_resources/test_proxies.py | 667 +++++++++++++++- 71 files changed, 6878 insertions(+), 162 deletions(-) create mode 100644 src/mobilerun_sdk/resources/apps.py create mode 100644 src/mobilerun_sdk/resources/credentials/__init__.py create mode 100644 src/mobilerun_sdk/resources/credentials/credentials.py create mode 100644 src/mobilerun_sdk/resources/credentials/packages/__init__.py create mode 100644 src/mobilerun_sdk/resources/credentials/packages/credentials/__init__.py create mode 100644 src/mobilerun_sdk/resources/credentials/packages/credentials/credentials.py create mode 100644 src/mobilerun_sdk/resources/credentials/packages/credentials/fields.py create mode 100644 src/mobilerun_sdk/resources/credentials/packages/packages.py create mode 100644 src/mobilerun_sdk/types/app_confirm_upload_response.py create mode 100644 src/mobilerun_sdk/types/app_create_signed_upload_url_params.py create mode 100644 src/mobilerun_sdk/types/app_create_signed_upload_url_response.py create mode 100644 src/mobilerun_sdk/types/app_delete_response.py create mode 100644 src/mobilerun_sdk/types/app_list_params.py create mode 100644 src/mobilerun_sdk/types/app_list_response.py create mode 100644 src/mobilerun_sdk/types/app_list_versions_response.py create mode 100644 src/mobilerun_sdk/types/app_mark_failed_response.py create mode 100644 src/mobilerun_sdk/types/app_retrieve_response.py create mode 100644 src/mobilerun_sdk/types/credential_list_params.py create mode 100644 src/mobilerun_sdk/types/credential_list_response.py create mode 100644 src/mobilerun_sdk/types/credentials/package_create_params.py create mode 100644 src/mobilerun_sdk/types/credentials/package_create_response.py create mode 100644 src/mobilerun_sdk/types/credentials/package_list_response.py create mode 100644 src/mobilerun_sdk/types/credentials/packages/credential.py create mode 100644 src/mobilerun_sdk/types/credentials/packages/credential_create_params.py create mode 100644 src/mobilerun_sdk/types/credentials/packages/credential_create_response.py create mode 100644 src/mobilerun_sdk/types/credentials/packages/credential_delete_response.py create mode 100644 src/mobilerun_sdk/types/credentials/packages/credential_retrieve_response.py create mode 100644 src/mobilerun_sdk/types/credentials/packages/credentials/field_create_params.py create mode 100644 src/mobilerun_sdk/types/credentials/packages/credentials/field_create_response.py create mode 100644 src/mobilerun_sdk/types/credentials/packages/credentials/field_delete_response.py create mode 100644 src/mobilerun_sdk/types/credentials/packages/credentials/field_update_params.py create mode 100644 src/mobilerun_sdk/types/credentials/packages/credentials/field_update_response.py delete mode 100644 src/mobilerun_sdk/types/proxy_config_param.py create mode 100644 src/mobilerun_sdk/types/proxy_create_params.py create mode 100644 src/mobilerun_sdk/types/proxy_create_response.py create mode 100644 src/mobilerun_sdk/types/proxy_delete_response.py create mode 100644 src/mobilerun_sdk/types/proxy_list_params.py create mode 100644 src/mobilerun_sdk/types/proxy_list_response.py create mode 100644 src/mobilerun_sdk/types/proxy_retrieve_response.py create mode 100644 src/mobilerun_sdk/types/proxy_update_params.py create mode 100644 src/mobilerun_sdk/types/proxy_update_response.py create mode 100644 src/mobilerun_sdk/types/shared/pagination.py create mode 100644 tests/api_resources/credentials/__init__.py create mode 100644 tests/api_resources/credentials/packages/__init__.py create mode 100644 tests/api_resources/credentials/packages/credentials/__init__.py create mode 100644 tests/api_resources/credentials/packages/credentials/test_fields.py create mode 100644 tests/api_resources/credentials/packages/test_credentials.py create mode 100644 tests/api_resources/credentials/test_packages.py create mode 100644 tests/api_resources/test_apps.py create mode 100644 tests/api_resources/test_credentials.py diff --git a/.stats.yml b/.stats.yml index 6e46968..6616e99 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 86 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-423b2f04c14fefe08d8c773dc2a025e7775f5ef947a2ba1d8eebbf008106c9fc.yml -openapi_spec_hash: 7581f9f0e4fc01bad5ca519628671bab +configured_endpoints: 107 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-506128e71e04bea5ce31fd879d4c0ac5a313fc39cf9f39acd1cbb3cee95f74ab.yml +openapi_spec_hash: b45c764022d18add79f0516691749fa8 config_hash: 86398ea1292189c25296aefb64d3137d diff --git a/api.md b/api.md index 1dd0ca2..4b2c442 100644 --- a/api.md +++ b/api.md @@ -7,6 +7,7 @@ from mobilerun_sdk.types import ( DeviceSpec, Location, Meta, + Pagination, PaginationMeta, PermissionSet, Socks5, @@ -25,6 +26,32 @@ Methods: - client.agents.list() -> AgentListResponse +# Apps + +Types: + +```python +from mobilerun_sdk.types import ( + AppRetrieveResponse, + AppListResponse, + AppDeleteResponse, + AppConfirmUploadResponse, + AppCreateSignedUploadURLResponse, + AppListVersionsResponse, + AppMarkFailedResponse, +) +``` + +Methods: + +- client.apps.retrieve(id) -> AppRetrieveResponse +- client.apps.list(\*\*params) -> AppListResponse +- client.apps.delete(id) -> AppDeleteResponse +- client.apps.confirm_upload(id) -> AppConfirmUploadResponse +- client.apps.create_signed_upload_url(\*\*params) -> AppCreateSignedUploadURLResponse +- client.apps.list_versions(id) -> AppListVersionsResponse +- client.apps.mark_failed(id) -> AppMarkFailedResponse + # Carriers Types: @@ -49,6 +76,68 @@ Methods: - client.carriers.delete(carrier_id) -> CarrierDeleteResponse - client.carriers.lookup(\*\*params) -> CarrierLookupResponse +# Credentials + +Types: + +```python +from mobilerun_sdk.types import CredentialListResponse +``` + +Methods: + +- client.credentials.list(\*\*params) -> CredentialListResponse + +## Packages + +Types: + +```python +from mobilerun_sdk.types.credentials import PackageCreateResponse, PackageListResponse +``` + +Methods: + +- client.credentials.packages.create(\*\*params) -> PackageCreateResponse +- client.credentials.packages.list(package_name) -> PackageListResponse + +### Credentials + +Types: + +```python +from mobilerun_sdk.types.credentials.packages import ( + Credential, + CredentialCreateResponse, + CredentialRetrieveResponse, + CredentialDeleteResponse, +) +``` + +Methods: + +- client.credentials.packages.credentials.create(package_name, \*\*params) -> CredentialCreateResponse +- client.credentials.packages.credentials.retrieve(credential_name, \*, package_name) -> CredentialRetrieveResponse +- client.credentials.packages.credentials.delete(credential_name, \*, package_name) -> CredentialDeleteResponse + +#### Fields + +Types: + +```python +from mobilerun_sdk.types.credentials.packages.credentials import ( + FieldCreateResponse, + FieldUpdateResponse, + FieldDeleteResponse, +) +``` + +Methods: + +- client.credentials.packages.credentials.fields.create(credential_name, \*, package_name, \*\*params) -> FieldCreateResponse +- client.credentials.packages.credentials.fields.update(field_type, \*, package_name, credential_name, \*\*params) -> FieldUpdateResponse +- client.credentials.packages.credentials.fields.delete(field_type, \*, package_name, credential_name) -> FieldDeleteResponse + # Devices Types: @@ -318,11 +407,24 @@ Methods: Types: ```python -from mobilerun_sdk.types import ProxyConfig, ProxyLookupResponse +from mobilerun_sdk.types import ( + ProxyConfig, + ProxyCreateResponse, + ProxyRetrieveResponse, + ProxyUpdateResponse, + ProxyListResponse, + ProxyDeleteResponse, + ProxyLookupResponse, +) ``` Methods: +- client.proxies.create(\*\*params) -> ProxyCreateResponse +- client.proxies.retrieve(proxy_id) -> ProxyRetrieveResponse +- client.proxies.update(proxy_id, \*\*params) -> ProxyUpdateResponse +- client.proxies.list(\*\*params) -> ProxyListResponse +- client.proxies.delete(proxy_id) -> ProxyDeleteResponse - client.proxies.lookup(\*\*params) -> ProxyLookupResponse # Tasks diff --git a/src/mobilerun_sdk/_client.py b/src/mobilerun_sdk/_client.py index 3816717..28b10f0 100644 --- a/src/mobilerun_sdk/_client.py +++ b/src/mobilerun_sdk/_client.py @@ -36,7 +36,8 @@ ) if TYPE_CHECKING: - from .resources import hooks, tasks, agents, models, devices, proxies, carriers, profiles + from .resources import apps, hooks, tasks, agents, models, devices, proxies, carriers, profiles, credentials + from .resources.apps import AppsResource, AsyncAppsResource from .resources.hooks import HooksResource, AsyncHooksResource from .resources.agents import AgentsResource, AsyncAgentsResource from .resources.models import ModelsResource, AsyncModelsResource @@ -45,6 +46,7 @@ from .resources.profiles import ProfilesResource, AsyncProfilesResource from .resources.tasks.tasks import TasksResource, AsyncTasksResource from .resources.devices.devices import DevicesResource, AsyncDevicesResource + from .resources.credentials.credentials import CredentialsResource, AsyncCredentialsResource __all__ = [ "Timeout", @@ -125,12 +127,27 @@ def agents(self) -> AgentsResource: return AgentsResource(self) + @cached_property + def apps(self) -> AppsResource: + """App Management""" + from .resources.apps import AppsResource + + return AppsResource(self) + @cached_property def carriers(self) -> CarriersResource: + """Mobile Carriers""" from .resources.carriers import CarriersResource return CarriersResource(self) + @cached_property + def credentials(self) -> CredentialsResource: + """Vault & Secrets""" + from .resources.credentials import CredentialsResource + + return CredentialsResource(self) + @cached_property def devices(self) -> DevicesResource: from .resources.devices import DevicesResource @@ -139,13 +156,13 @@ def devices(self) -> DevicesResource: @cached_property def hooks(self) -> HooksResource: - """Webhooks API""" from .resources.hooks import HooksResource return HooksResource(self) @cached_property def models(self) -> ModelsResource: + """LLM Models""" from .resources.models import ModelsResource return ModelsResource(self) @@ -158,6 +175,7 @@ def profiles(self) -> ProfilesResource: @cached_property def proxies(self) -> ProxiesResource: + """Network Proxies""" from .resources.proxies import ProxiesResource return ProxiesResource(self) @@ -360,12 +378,27 @@ def agents(self) -> AsyncAgentsResource: return AsyncAgentsResource(self) + @cached_property + def apps(self) -> AsyncAppsResource: + """App Management""" + from .resources.apps import AsyncAppsResource + + return AsyncAppsResource(self) + @cached_property def carriers(self) -> AsyncCarriersResource: + """Mobile Carriers""" from .resources.carriers import AsyncCarriersResource return AsyncCarriersResource(self) + @cached_property + def credentials(self) -> AsyncCredentialsResource: + """Vault & Secrets""" + from .resources.credentials import AsyncCredentialsResource + + return AsyncCredentialsResource(self) + @cached_property def devices(self) -> AsyncDevicesResource: from .resources.devices import AsyncDevicesResource @@ -374,13 +407,13 @@ def devices(self) -> AsyncDevicesResource: @cached_property def hooks(self) -> AsyncHooksResource: - """Webhooks API""" from .resources.hooks import AsyncHooksResource return AsyncHooksResource(self) @cached_property def models(self) -> AsyncModelsResource: + """LLM Models""" from .resources.models import AsyncModelsResource return AsyncModelsResource(self) @@ -393,6 +426,7 @@ def profiles(self) -> AsyncProfilesResource: @cached_property def proxies(self) -> AsyncProxiesResource: + """Network Proxies""" from .resources.proxies import AsyncProxiesResource return AsyncProxiesResource(self) @@ -541,12 +575,27 @@ def agents(self) -> agents.AgentsResourceWithRawResponse: return AgentsResourceWithRawResponse(self._client.agents) + @cached_property + def apps(self) -> apps.AppsResourceWithRawResponse: + """App Management""" + from .resources.apps import AppsResourceWithRawResponse + + return AppsResourceWithRawResponse(self._client.apps) + @cached_property def carriers(self) -> carriers.CarriersResourceWithRawResponse: + """Mobile Carriers""" from .resources.carriers import CarriersResourceWithRawResponse return CarriersResourceWithRawResponse(self._client.carriers) + @cached_property + def credentials(self) -> credentials.CredentialsResourceWithRawResponse: + """Vault & Secrets""" + from .resources.credentials import CredentialsResourceWithRawResponse + + return CredentialsResourceWithRawResponse(self._client.credentials) + @cached_property def devices(self) -> devices.DevicesResourceWithRawResponse: from .resources.devices import DevicesResourceWithRawResponse @@ -555,13 +604,13 @@ def devices(self) -> devices.DevicesResourceWithRawResponse: @cached_property def hooks(self) -> hooks.HooksResourceWithRawResponse: - """Webhooks API""" from .resources.hooks import HooksResourceWithRawResponse return HooksResourceWithRawResponse(self._client.hooks) @cached_property def models(self) -> models.ModelsResourceWithRawResponse: + """LLM Models""" from .resources.models import ModelsResourceWithRawResponse return ModelsResourceWithRawResponse(self._client.models) @@ -574,6 +623,7 @@ def profiles(self) -> profiles.ProfilesResourceWithRawResponse: @cached_property def proxies(self) -> proxies.ProxiesResourceWithRawResponse: + """Network Proxies""" from .resources.proxies import ProxiesResourceWithRawResponse return ProxiesResourceWithRawResponse(self._client.proxies) @@ -599,12 +649,27 @@ def agents(self) -> agents.AsyncAgentsResourceWithRawResponse: return AsyncAgentsResourceWithRawResponse(self._client.agents) + @cached_property + def apps(self) -> apps.AsyncAppsResourceWithRawResponse: + """App Management""" + from .resources.apps import AsyncAppsResourceWithRawResponse + + return AsyncAppsResourceWithRawResponse(self._client.apps) + @cached_property def carriers(self) -> carriers.AsyncCarriersResourceWithRawResponse: + """Mobile Carriers""" from .resources.carriers import AsyncCarriersResourceWithRawResponse return AsyncCarriersResourceWithRawResponse(self._client.carriers) + @cached_property + def credentials(self) -> credentials.AsyncCredentialsResourceWithRawResponse: + """Vault & Secrets""" + from .resources.credentials import AsyncCredentialsResourceWithRawResponse + + return AsyncCredentialsResourceWithRawResponse(self._client.credentials) + @cached_property def devices(self) -> devices.AsyncDevicesResourceWithRawResponse: from .resources.devices import AsyncDevicesResourceWithRawResponse @@ -613,13 +678,13 @@ def devices(self) -> devices.AsyncDevicesResourceWithRawResponse: @cached_property def hooks(self) -> hooks.AsyncHooksResourceWithRawResponse: - """Webhooks API""" from .resources.hooks import AsyncHooksResourceWithRawResponse return AsyncHooksResourceWithRawResponse(self._client.hooks) @cached_property def models(self) -> models.AsyncModelsResourceWithRawResponse: + """LLM Models""" from .resources.models import AsyncModelsResourceWithRawResponse return AsyncModelsResourceWithRawResponse(self._client.models) @@ -632,6 +697,7 @@ def profiles(self) -> profiles.AsyncProfilesResourceWithRawResponse: @cached_property def proxies(self) -> proxies.AsyncProxiesResourceWithRawResponse: + """Network Proxies""" from .resources.proxies import AsyncProxiesResourceWithRawResponse return AsyncProxiesResourceWithRawResponse(self._client.proxies) @@ -657,12 +723,27 @@ def agents(self) -> agents.AgentsResourceWithStreamingResponse: return AgentsResourceWithStreamingResponse(self._client.agents) + @cached_property + def apps(self) -> apps.AppsResourceWithStreamingResponse: + """App Management""" + from .resources.apps import AppsResourceWithStreamingResponse + + return AppsResourceWithStreamingResponse(self._client.apps) + @cached_property def carriers(self) -> carriers.CarriersResourceWithStreamingResponse: + """Mobile Carriers""" from .resources.carriers import CarriersResourceWithStreamingResponse return CarriersResourceWithStreamingResponse(self._client.carriers) + @cached_property + def credentials(self) -> credentials.CredentialsResourceWithStreamingResponse: + """Vault & Secrets""" + from .resources.credentials import CredentialsResourceWithStreamingResponse + + return CredentialsResourceWithStreamingResponse(self._client.credentials) + @cached_property def devices(self) -> devices.DevicesResourceWithStreamingResponse: from .resources.devices import DevicesResourceWithStreamingResponse @@ -671,13 +752,13 @@ def devices(self) -> devices.DevicesResourceWithStreamingResponse: @cached_property def hooks(self) -> hooks.HooksResourceWithStreamingResponse: - """Webhooks API""" from .resources.hooks import HooksResourceWithStreamingResponse return HooksResourceWithStreamingResponse(self._client.hooks) @cached_property def models(self) -> models.ModelsResourceWithStreamingResponse: + """LLM Models""" from .resources.models import ModelsResourceWithStreamingResponse return ModelsResourceWithStreamingResponse(self._client.models) @@ -690,6 +771,7 @@ def profiles(self) -> profiles.ProfilesResourceWithStreamingResponse: @cached_property def proxies(self) -> proxies.ProxiesResourceWithStreamingResponse: + """Network Proxies""" from .resources.proxies import ProxiesResourceWithStreamingResponse return ProxiesResourceWithStreamingResponse(self._client.proxies) @@ -715,12 +797,27 @@ def agents(self) -> agents.AsyncAgentsResourceWithStreamingResponse: return AsyncAgentsResourceWithStreamingResponse(self._client.agents) + @cached_property + def apps(self) -> apps.AsyncAppsResourceWithStreamingResponse: + """App Management""" + from .resources.apps import AsyncAppsResourceWithStreamingResponse + + return AsyncAppsResourceWithStreamingResponse(self._client.apps) + @cached_property def carriers(self) -> carriers.AsyncCarriersResourceWithStreamingResponse: + """Mobile Carriers""" from .resources.carriers import AsyncCarriersResourceWithStreamingResponse return AsyncCarriersResourceWithStreamingResponse(self._client.carriers) + @cached_property + def credentials(self) -> credentials.AsyncCredentialsResourceWithStreamingResponse: + """Vault & Secrets""" + from .resources.credentials import AsyncCredentialsResourceWithStreamingResponse + + return AsyncCredentialsResourceWithStreamingResponse(self._client.credentials) + @cached_property def devices(self) -> devices.AsyncDevicesResourceWithStreamingResponse: from .resources.devices import AsyncDevicesResourceWithStreamingResponse @@ -729,13 +826,13 @@ def devices(self) -> devices.AsyncDevicesResourceWithStreamingResponse: @cached_property def hooks(self) -> hooks.AsyncHooksResourceWithStreamingResponse: - """Webhooks API""" from .resources.hooks import AsyncHooksResourceWithStreamingResponse return AsyncHooksResourceWithStreamingResponse(self._client.hooks) @cached_property def models(self) -> models.AsyncModelsResourceWithStreamingResponse: + """LLM Models""" from .resources.models import AsyncModelsResourceWithStreamingResponse return AsyncModelsResourceWithStreamingResponse(self._client.models) @@ -748,6 +845,7 @@ def profiles(self) -> profiles.AsyncProfilesResourceWithStreamingResponse: @cached_property def proxies(self) -> proxies.AsyncProxiesResourceWithStreamingResponse: + """Network Proxies""" from .resources.proxies import AsyncProxiesResourceWithStreamingResponse return AsyncProxiesResourceWithStreamingResponse(self._client.proxies) diff --git a/src/mobilerun_sdk/resources/__init__.py b/src/mobilerun_sdk/resources/__init__.py index 9ebd59d..21f473c 100644 --- a/src/mobilerun_sdk/resources/__init__.py +++ b/src/mobilerun_sdk/resources/__init__.py @@ -1,5 +1,13 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +from .apps import ( + AppsResource, + AsyncAppsResource, + AppsResourceWithRawResponse, + AsyncAppsResourceWithRawResponse, + AppsResourceWithStreamingResponse, + AsyncAppsResourceWithStreamingResponse, +) from .hooks import ( HooksResource, AsyncHooksResource, @@ -64,6 +72,14 @@ ProfilesResourceWithStreamingResponse, AsyncProfilesResourceWithStreamingResponse, ) +from .credentials import ( + CredentialsResource, + AsyncCredentialsResource, + CredentialsResourceWithRawResponse, + AsyncCredentialsResourceWithRawResponse, + CredentialsResourceWithStreamingResponse, + AsyncCredentialsResourceWithStreamingResponse, +) __all__ = [ "AgentsResource", @@ -72,12 +88,24 @@ "AsyncAgentsResourceWithRawResponse", "AgentsResourceWithStreamingResponse", "AsyncAgentsResourceWithStreamingResponse", + "AppsResource", + "AsyncAppsResource", + "AppsResourceWithRawResponse", + "AsyncAppsResourceWithRawResponse", + "AppsResourceWithStreamingResponse", + "AsyncAppsResourceWithStreamingResponse", "CarriersResource", "AsyncCarriersResource", "CarriersResourceWithRawResponse", "AsyncCarriersResourceWithRawResponse", "CarriersResourceWithStreamingResponse", "AsyncCarriersResourceWithStreamingResponse", + "CredentialsResource", + "AsyncCredentialsResource", + "CredentialsResourceWithRawResponse", + "AsyncCredentialsResourceWithRawResponse", + "CredentialsResourceWithStreamingResponse", + "AsyncCredentialsResourceWithStreamingResponse", "DevicesResource", "AsyncDevicesResource", "DevicesResourceWithRawResponse", diff --git a/src/mobilerun_sdk/resources/apps.py b/src/mobilerun_sdk/resources/apps.py new file mode 100644 index 0000000..3e2bb8f --- /dev/null +++ b/src/mobilerun_sdk/resources/apps.py @@ -0,0 +1,748 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Literal + +import httpx + +from ..types import app_list_params, app_create_signed_upload_url_params +from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from .._utils import path_template, maybe_transform, async_maybe_transform +from .._compat import cached_property +from .._resource import SyncAPIResource, AsyncAPIResource +from .._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from .._base_client import make_request_options +from ..types.app_list_response import AppListResponse +from ..types.app_delete_response import AppDeleteResponse +from ..types.app_retrieve_response import AppRetrieveResponse +from ..types.app_mark_failed_response import AppMarkFailedResponse +from ..types.app_list_versions_response import AppListVersionsResponse +from ..types.app_confirm_upload_response import AppConfirmUploadResponse +from ..types.app_create_signed_upload_url_response import AppCreateSignedUploadURLResponse + +__all__ = ["AppsResource", "AsyncAppsResource"] + + +class AppsResource(SyncAPIResource): + """App Management""" + + @cached_property + def with_raw_response(self) -> AppsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AppsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AppsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AppsResourceWithStreamingResponse(self) + + def retrieve( + self, + id: str, + *, + # 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, + ) -> AppRetrieveResponse: + """ + Retrieves an app by its ID + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._get( + path_template("/apps/{id}", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AppRetrieveResponse, + ) + + def list( + self, + *, + order: Literal["asc", "desc"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + platform: Literal["all", "android", "ios"] | Omit = omit, + query: str | Omit = omit, + sort_by: Literal["createdAt", "name"] | Omit = omit, + status: Literal["all", "queued", "available", "failed"] | 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, + ) -> AppListResponse: + """ + Retrieves a paginated list of apps with filtering and search capabilities + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get( + "/apps", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "order": order, + "page": page, + "page_size": page_size, + "platform": platform, + "query": query, + "sort_by": sort_by, + "status": status, + }, + app_list_params.AppListParams, + ), + ), + cast_to=AppListResponse, + ) + + def delete( + self, + id: str, + *, + # 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, + ) -> AppDeleteResponse: + """Deletes an uploaded app by ID. + + Removes files from R2 storage and the database + entry. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=AppDeleteResponse, + ) + + def confirm_upload( + self, + id: str, + *, + # 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, + ) -> AppConfirmUploadResponse: + """ + Verifies the APK file exists in R2 and sets the app status to available. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=AppConfirmUploadResponse, + ) + + def create_signed_upload_url( + self, + *, + bundle_id: str, + display_name: str, + files: Iterable[app_create_signed_upload_url_params.File], + size_bytes: float, + version_code: float, + version_name: str, + country: str | Omit = omit, + description: str | Omit = omit, + developer_name: str | Omit = omit, + icon_url: str | Omit = omit, + platform: Literal["android", "ios"] | Omit = omit, + target_sdk: float | 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, + ) -> AppCreateSignedUploadURLResponse: + """ + Creates or updates an app and returns pre-signed Cloudflare R2 upload URLs for + each file + + Args: + country: Country code for Search Results + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/apps/create-signed-upload-url", + body=maybe_transform( + { + "bundle_id": bundle_id, + "display_name": display_name, + "files": files, + "size_bytes": size_bytes, + "version_code": version_code, + "version_name": version_name, + "country": country, + "description": description, + "developer_name": developer_name, + "icon_url": icon_url, + "platform": platform, + "target_sdk": target_sdk, + }, + 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 + ), + cast_to=AppCreateSignedUploadURLResponse, + ) + + def list_versions( + self, + id: str, + *, + # 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, + ) -> AppListVersionsResponse: + """ + Retrieves all versions of an app visible to the user (own uploads + system + versions) + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._get( + path_template("/apps/{id}/versions", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AppListVersionsResponse, + ) + + def mark_failed( + self, + id: str, + *, + # 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, + ) -> AppMarkFailedResponse: + """ + Sets the app status to failed. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=AppMarkFailedResponse, + ) + + +class AsyncAppsResource(AsyncAPIResource): + """App Management""" + + @cached_property + def with_raw_response(self) -> AsyncAppsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncAppsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAppsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncAppsResourceWithStreamingResponse(self) + + async def retrieve( + self, + id: str, + *, + # 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, + ) -> AppRetrieveResponse: + """ + Retrieves an app by its ID + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._get( + path_template("/apps/{id}", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AppRetrieveResponse, + ) + + async def list( + self, + *, + order: Literal["asc", "desc"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + platform: Literal["all", "android", "ios"] | Omit = omit, + query: str | Omit = omit, + sort_by: Literal["createdAt", "name"] | Omit = omit, + status: Literal["all", "queued", "available", "failed"] | 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, + ) -> AppListResponse: + """ + Retrieves a paginated list of apps with filtering and search capabilities + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._get( + "/apps", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "order": order, + "page": page, + "page_size": page_size, + "platform": platform, + "query": query, + "sort_by": sort_by, + "status": status, + }, + app_list_params.AppListParams, + ), + ), + cast_to=AppListResponse, + ) + + async def delete( + self, + id: str, + *, + # 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, + ) -> AppDeleteResponse: + """Deletes an uploaded app by ID. + + Removes files from R2 storage and the database + entry. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=AppDeleteResponse, + ) + + async def confirm_upload( + self, + id: str, + *, + # 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, + ) -> AppConfirmUploadResponse: + """ + Verifies the APK file exists in R2 and sets the app status to available. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=AppConfirmUploadResponse, + ) + + async def create_signed_upload_url( + self, + *, + bundle_id: str, + display_name: str, + files: Iterable[app_create_signed_upload_url_params.File], + size_bytes: float, + version_code: float, + version_name: str, + country: str | Omit = omit, + description: str | Omit = omit, + developer_name: str | Omit = omit, + icon_url: str | Omit = omit, + platform: Literal["android", "ios"] | Omit = omit, + target_sdk: float | 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, + ) -> AppCreateSignedUploadURLResponse: + """ + Creates or updates an app and returns pre-signed Cloudflare R2 upload URLs for + each file + + Args: + country: Country code for Search Results + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/apps/create-signed-upload-url", + body=await async_maybe_transform( + { + "bundle_id": bundle_id, + "display_name": display_name, + "files": files, + "size_bytes": size_bytes, + "version_code": version_code, + "version_name": version_name, + "country": country, + "description": description, + "developer_name": developer_name, + "icon_url": icon_url, + "platform": platform, + "target_sdk": target_sdk, + }, + 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 + ), + cast_to=AppCreateSignedUploadURLResponse, + ) + + async def list_versions( + self, + id: str, + *, + # 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, + ) -> AppListVersionsResponse: + """ + Retrieves all versions of an app visible to the user (own uploads + system + versions) + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._get( + path_template("/apps/{id}/versions", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AppListVersionsResponse, + ) + + async def mark_failed( + self, + id: str, + *, + # 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, + ) -> AppMarkFailedResponse: + """ + Sets the app status to failed. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=AppMarkFailedResponse, + ) + + +class AppsResourceWithRawResponse: + def __init__(self, apps: AppsResource) -> None: + self._apps = apps + + self.retrieve = to_raw_response_wrapper( + apps.retrieve, + ) + self.list = to_raw_response_wrapper( + apps.list, + ) + self.delete = to_raw_response_wrapper( + apps.delete, + ) + self.confirm_upload = to_raw_response_wrapper( + apps.confirm_upload, + ) + self.create_signed_upload_url = to_raw_response_wrapper( + apps.create_signed_upload_url, + ) + self.list_versions = to_raw_response_wrapper( + apps.list_versions, + ) + self.mark_failed = to_raw_response_wrapper( + apps.mark_failed, + ) + + +class AsyncAppsResourceWithRawResponse: + def __init__(self, apps: AsyncAppsResource) -> None: + self._apps = apps + + self.retrieve = async_to_raw_response_wrapper( + apps.retrieve, + ) + self.list = async_to_raw_response_wrapper( + apps.list, + ) + self.delete = async_to_raw_response_wrapper( + apps.delete, + ) + self.confirm_upload = async_to_raw_response_wrapper( + apps.confirm_upload, + ) + self.create_signed_upload_url = async_to_raw_response_wrapper( + apps.create_signed_upload_url, + ) + self.list_versions = async_to_raw_response_wrapper( + apps.list_versions, + ) + self.mark_failed = async_to_raw_response_wrapper( + apps.mark_failed, + ) + + +class AppsResourceWithStreamingResponse: + def __init__(self, apps: AppsResource) -> None: + self._apps = apps + + self.retrieve = to_streamed_response_wrapper( + apps.retrieve, + ) + self.list = to_streamed_response_wrapper( + apps.list, + ) + self.delete = to_streamed_response_wrapper( + apps.delete, + ) + self.confirm_upload = to_streamed_response_wrapper( + apps.confirm_upload, + ) + self.create_signed_upload_url = to_streamed_response_wrapper( + apps.create_signed_upload_url, + ) + self.list_versions = to_streamed_response_wrapper( + apps.list_versions, + ) + self.mark_failed = to_streamed_response_wrapper( + apps.mark_failed, + ) + + +class AsyncAppsResourceWithStreamingResponse: + def __init__(self, apps: AsyncAppsResource) -> None: + self._apps = apps + + self.retrieve = async_to_streamed_response_wrapper( + apps.retrieve, + ) + self.list = async_to_streamed_response_wrapper( + apps.list, + ) + self.delete = async_to_streamed_response_wrapper( + apps.delete, + ) + self.confirm_upload = async_to_streamed_response_wrapper( + apps.confirm_upload, + ) + self.create_signed_upload_url = async_to_streamed_response_wrapper( + apps.create_signed_upload_url, + ) + self.list_versions = async_to_streamed_response_wrapper( + apps.list_versions, + ) + self.mark_failed = async_to_streamed_response_wrapper( + apps.mark_failed, + ) diff --git a/src/mobilerun_sdk/resources/carriers.py b/src/mobilerun_sdk/resources/carriers.py index a674b8f..d627159 100644 --- a/src/mobilerun_sdk/resources/carriers.py +++ b/src/mobilerun_sdk/resources/carriers.py @@ -29,6 +29,8 @@ class CarriersResource(SyncAPIResource): + """Mobile Carriers""" + @cached_property def with_raw_response(self) -> CarriersResourceWithRawResponse: """ @@ -417,6 +419,8 @@ def lookup( class AsyncCarriersResource(AsyncAPIResource): + """Mobile Carriers""" + @cached_property def with_raw_response(self) -> AsyncCarriersResourceWithRawResponse: """ diff --git a/src/mobilerun_sdk/resources/credentials/__init__.py b/src/mobilerun_sdk/resources/credentials/__init__.py new file mode 100644 index 0000000..2ab7903 --- /dev/null +++ b/src/mobilerun_sdk/resources/credentials/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .packages import ( + PackagesResource, + AsyncPackagesResource, + PackagesResourceWithRawResponse, + AsyncPackagesResourceWithRawResponse, + PackagesResourceWithStreamingResponse, + AsyncPackagesResourceWithStreamingResponse, +) +from .credentials import ( + CredentialsResource, + AsyncCredentialsResource, + CredentialsResourceWithRawResponse, + AsyncCredentialsResourceWithRawResponse, + CredentialsResourceWithStreamingResponse, + AsyncCredentialsResourceWithStreamingResponse, +) + +__all__ = [ + "PackagesResource", + "AsyncPackagesResource", + "PackagesResourceWithRawResponse", + "AsyncPackagesResourceWithRawResponse", + "PackagesResourceWithStreamingResponse", + "AsyncPackagesResourceWithStreamingResponse", + "CredentialsResource", + "AsyncCredentialsResource", + "CredentialsResourceWithRawResponse", + "AsyncCredentialsResourceWithRawResponse", + "CredentialsResourceWithStreamingResponse", + "AsyncCredentialsResourceWithStreamingResponse", +] diff --git a/src/mobilerun_sdk/resources/credentials/credentials.py b/src/mobilerun_sdk/resources/credentials/credentials.py new file mode 100644 index 0000000..9276d9f --- /dev/null +++ b/src/mobilerun_sdk/resources/credentials/credentials.py @@ -0,0 +1,225 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ...types import credential_list_params +from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ..._utils import maybe_transform, async_maybe_transform +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._base_client import make_request_options +from .packages.packages import ( + PackagesResource, + AsyncPackagesResource, + PackagesResourceWithRawResponse, + AsyncPackagesResourceWithRawResponse, + PackagesResourceWithStreamingResponse, + AsyncPackagesResourceWithStreamingResponse, +) +from ...types.credential_list_response import CredentialListResponse + +__all__ = ["CredentialsResource", "AsyncCredentialsResource"] + + +class CredentialsResource(SyncAPIResource): + """Vault & Secrets""" + + @cached_property + def packages(self) -> PackagesResource: + """Vault & Secrets""" + return PackagesResource(self._client) + + @cached_property + def with_raw_response(self) -> CredentialsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return CredentialsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> CredentialsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return CredentialsResourceWithStreamingResponse(self) + + def list( + self, + *, + page: int | Omit = omit, + page_size: int | 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, + ) -> CredentialListResponse: + """ + List all credentials for the authenticated user + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get( + "/credentials", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "page_size": page_size, + }, + credential_list_params.CredentialListParams, + ), + ), + cast_to=CredentialListResponse, + ) + + +class AsyncCredentialsResource(AsyncAPIResource): + """Vault & Secrets""" + + @cached_property + def packages(self) -> AsyncPackagesResource: + """Vault & Secrets""" + return AsyncPackagesResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncCredentialsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncCredentialsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncCredentialsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncCredentialsResourceWithStreamingResponse(self) + + async def list( + self, + *, + page: int | Omit = omit, + page_size: int | 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, + ) -> CredentialListResponse: + """ + List all credentials for the authenticated user + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._get( + "/credentials", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "page": page, + "page_size": page_size, + }, + credential_list_params.CredentialListParams, + ), + ), + cast_to=CredentialListResponse, + ) + + +class CredentialsResourceWithRawResponse: + def __init__(self, credentials: CredentialsResource) -> None: + self._credentials = credentials + + self.list = to_raw_response_wrapper( + credentials.list, + ) + + @cached_property + def packages(self) -> PackagesResourceWithRawResponse: + """Vault & Secrets""" + return PackagesResourceWithRawResponse(self._credentials.packages) + + +class AsyncCredentialsResourceWithRawResponse: + def __init__(self, credentials: AsyncCredentialsResource) -> None: + self._credentials = credentials + + self.list = async_to_raw_response_wrapper( + credentials.list, + ) + + @cached_property + def packages(self) -> AsyncPackagesResourceWithRawResponse: + """Vault & Secrets""" + return AsyncPackagesResourceWithRawResponse(self._credentials.packages) + + +class CredentialsResourceWithStreamingResponse: + def __init__(self, credentials: CredentialsResource) -> None: + self._credentials = credentials + + self.list = to_streamed_response_wrapper( + credentials.list, + ) + + @cached_property + def packages(self) -> PackagesResourceWithStreamingResponse: + """Vault & Secrets""" + return PackagesResourceWithStreamingResponse(self._credentials.packages) + + +class AsyncCredentialsResourceWithStreamingResponse: + def __init__(self, credentials: AsyncCredentialsResource) -> None: + self._credentials = credentials + + self.list = async_to_streamed_response_wrapper( + credentials.list, + ) + + @cached_property + def packages(self) -> AsyncPackagesResourceWithStreamingResponse: + """Vault & Secrets""" + return AsyncPackagesResourceWithStreamingResponse(self._credentials.packages) diff --git a/src/mobilerun_sdk/resources/credentials/packages/__init__.py b/src/mobilerun_sdk/resources/credentials/packages/__init__.py new file mode 100644 index 0000000..179ec4a --- /dev/null +++ b/src/mobilerun_sdk/resources/credentials/packages/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .packages import ( + PackagesResource, + AsyncPackagesResource, + PackagesResourceWithRawResponse, + AsyncPackagesResourceWithRawResponse, + PackagesResourceWithStreamingResponse, + AsyncPackagesResourceWithStreamingResponse, +) +from .credentials import ( + CredentialsResource, + AsyncCredentialsResource, + CredentialsResourceWithRawResponse, + AsyncCredentialsResourceWithRawResponse, + CredentialsResourceWithStreamingResponse, + AsyncCredentialsResourceWithStreamingResponse, +) + +__all__ = [ + "CredentialsResource", + "AsyncCredentialsResource", + "CredentialsResourceWithRawResponse", + "AsyncCredentialsResourceWithRawResponse", + "CredentialsResourceWithStreamingResponse", + "AsyncCredentialsResourceWithStreamingResponse", + "PackagesResource", + "AsyncPackagesResource", + "PackagesResourceWithRawResponse", + "AsyncPackagesResourceWithRawResponse", + "PackagesResourceWithStreamingResponse", + "AsyncPackagesResourceWithStreamingResponse", +] diff --git a/src/mobilerun_sdk/resources/credentials/packages/credentials/__init__.py b/src/mobilerun_sdk/resources/credentials/packages/credentials/__init__.py new file mode 100644 index 0000000..bfa68f3 --- /dev/null +++ b/src/mobilerun_sdk/resources/credentials/packages/credentials/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .fields import ( + FieldsResource, + AsyncFieldsResource, + FieldsResourceWithRawResponse, + AsyncFieldsResourceWithRawResponse, + FieldsResourceWithStreamingResponse, + AsyncFieldsResourceWithStreamingResponse, +) +from .credentials import ( + CredentialsResource, + AsyncCredentialsResource, + CredentialsResourceWithRawResponse, + AsyncCredentialsResourceWithRawResponse, + CredentialsResourceWithStreamingResponse, + AsyncCredentialsResourceWithStreamingResponse, +) + +__all__ = [ + "FieldsResource", + "AsyncFieldsResource", + "FieldsResourceWithRawResponse", + "AsyncFieldsResourceWithRawResponse", + "FieldsResourceWithStreamingResponse", + "AsyncFieldsResourceWithStreamingResponse", + "CredentialsResource", + "AsyncCredentialsResource", + "CredentialsResourceWithRawResponse", + "AsyncCredentialsResourceWithRawResponse", + "CredentialsResourceWithStreamingResponse", + "AsyncCredentialsResourceWithStreamingResponse", +] diff --git a/src/mobilerun_sdk/resources/credentials/packages/credentials/credentials.py b/src/mobilerun_sdk/resources/credentials/packages/credentials/credentials.py new file mode 100644 index 0000000..df12c15 --- /dev/null +++ b/src/mobilerun_sdk/resources/credentials/packages/credentials/credentials.py @@ -0,0 +1,413 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable + +import httpx + +from .fields import ( + FieldsResource, + AsyncFieldsResource, + FieldsResourceWithRawResponse, + AsyncFieldsResourceWithRawResponse, + FieldsResourceWithStreamingResponse, + AsyncFieldsResourceWithStreamingResponse, +) +from ....._types import Body, Query, Headers, NotGiven, not_given +from ....._utils import path_template, maybe_transform, async_maybe_transform +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....._base_client import make_request_options +from .....types.credentials.packages import credential_create_params +from .....types.credentials.packages.credential_create_response import CredentialCreateResponse +from .....types.credentials.packages.credential_delete_response import CredentialDeleteResponse +from .....types.credentials.packages.credential_retrieve_response import CredentialRetrieveResponse + +__all__ = ["CredentialsResource", "AsyncCredentialsResource"] + + +class CredentialsResource(SyncAPIResource): + """Vault & Secrets""" + + @cached_property + def fields(self) -> FieldsResource: + """Vault & Secrets""" + return FieldsResource(self._client) + + @cached_property + def with_raw_response(self) -> CredentialsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return CredentialsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> CredentialsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return CredentialsResourceWithStreamingResponse(self) + + def create( + self, + package_name: str, + *, + credential_name: str, + fields: Iterable[credential_create_params.Field], + # 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, + ) -> CredentialCreateResponse: + """ + Create a credential with fields for a package + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not package_name: + raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") + return self._post( + path_template("/credentials/packages/{package_name}", package_name=package_name), + body=maybe_transform( + { + "credential_name": credential_name, + "fields": fields, + }, + credential_create_params.CredentialCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CredentialCreateResponse, + ) + + def retrieve( + self, + credential_name: str, + *, + package_name: str, + # 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, + ) -> CredentialRetrieveResponse: + """ + Get a specific credential with its fields + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not package_name: + raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") + if not credential_name: + raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") + return self._get( + path_template( + "/credentials/packages/{package_name}/credentials/{credential_name}", + package_name=package_name, + credential_name=credential_name, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CredentialRetrieveResponse, + ) + + def delete( + self, + credential_name: str, + *, + package_name: str, + # 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, + ) -> CredentialDeleteResponse: + """ + Delete a credential and all its fields + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not package_name: + raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") + if not credential_name: + raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") + return self._delete( + path_template( + "/credentials/packages/{package_name}/credentials/{credential_name}", + package_name=package_name, + credential_name=credential_name, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CredentialDeleteResponse, + ) + + +class AsyncCredentialsResource(AsyncAPIResource): + """Vault & Secrets""" + + @cached_property + def fields(self) -> AsyncFieldsResource: + """Vault & Secrets""" + return AsyncFieldsResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncCredentialsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncCredentialsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncCredentialsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncCredentialsResourceWithStreamingResponse(self) + + async def create( + self, + package_name: str, + *, + credential_name: str, + fields: Iterable[credential_create_params.Field], + # 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, + ) -> CredentialCreateResponse: + """ + Create a credential with fields for a package + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not package_name: + raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") + return await self._post( + path_template("/credentials/packages/{package_name}", package_name=package_name), + body=await async_maybe_transform( + { + "credential_name": credential_name, + "fields": fields, + }, + credential_create_params.CredentialCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CredentialCreateResponse, + ) + + async def retrieve( + self, + credential_name: str, + *, + package_name: str, + # 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, + ) -> CredentialRetrieveResponse: + """ + Get a specific credential with its fields + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not package_name: + raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") + if not credential_name: + raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") + return await self._get( + path_template( + "/credentials/packages/{package_name}/credentials/{credential_name}", + package_name=package_name, + credential_name=credential_name, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CredentialRetrieveResponse, + ) + + async def delete( + self, + credential_name: str, + *, + package_name: str, + # 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, + ) -> CredentialDeleteResponse: + """ + Delete a credential and all its fields + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not package_name: + raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") + if not credential_name: + raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") + return await self._delete( + path_template( + "/credentials/packages/{package_name}/credentials/{credential_name}", + package_name=package_name, + credential_name=credential_name, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CredentialDeleteResponse, + ) + + +class CredentialsResourceWithRawResponse: + def __init__(self, credentials: CredentialsResource) -> None: + self._credentials = credentials + + self.create = to_raw_response_wrapper( + credentials.create, + ) + self.retrieve = to_raw_response_wrapper( + credentials.retrieve, + ) + self.delete = to_raw_response_wrapper( + credentials.delete, + ) + + @cached_property + def fields(self) -> FieldsResourceWithRawResponse: + """Vault & Secrets""" + return FieldsResourceWithRawResponse(self._credentials.fields) + + +class AsyncCredentialsResourceWithRawResponse: + def __init__(self, credentials: AsyncCredentialsResource) -> None: + self._credentials = credentials + + self.create = async_to_raw_response_wrapper( + credentials.create, + ) + self.retrieve = async_to_raw_response_wrapper( + credentials.retrieve, + ) + self.delete = async_to_raw_response_wrapper( + credentials.delete, + ) + + @cached_property + def fields(self) -> AsyncFieldsResourceWithRawResponse: + """Vault & Secrets""" + return AsyncFieldsResourceWithRawResponse(self._credentials.fields) + + +class CredentialsResourceWithStreamingResponse: + def __init__(self, credentials: CredentialsResource) -> None: + self._credentials = credentials + + self.create = to_streamed_response_wrapper( + credentials.create, + ) + self.retrieve = to_streamed_response_wrapper( + credentials.retrieve, + ) + self.delete = to_streamed_response_wrapper( + credentials.delete, + ) + + @cached_property + def fields(self) -> FieldsResourceWithStreamingResponse: + """Vault & Secrets""" + return FieldsResourceWithStreamingResponse(self._credentials.fields) + + +class AsyncCredentialsResourceWithStreamingResponse: + def __init__(self, credentials: AsyncCredentialsResource) -> None: + self._credentials = credentials + + self.create = async_to_streamed_response_wrapper( + credentials.create, + ) + self.retrieve = async_to_streamed_response_wrapper( + credentials.retrieve, + ) + self.delete = async_to_streamed_response_wrapper( + credentials.delete, + ) + + @cached_property + def fields(self) -> AsyncFieldsResourceWithStreamingResponse: + """Vault & Secrets""" + return AsyncFieldsResourceWithStreamingResponse(self._credentials.fields) diff --git a/src/mobilerun_sdk/resources/credentials/packages/credentials/fields.py b/src/mobilerun_sdk/resources/credentials/packages/credentials/fields.py new file mode 100644 index 0000000..38ebfd9 --- /dev/null +++ b/src/mobilerun_sdk/resources/credentials/packages/credentials/fields.py @@ -0,0 +1,421 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal + +import httpx + +from ....._types import Body, Query, Headers, NotGiven, not_given +from ....._utils import path_template, maybe_transform, async_maybe_transform +from ....._compat import cached_property +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....._base_client import make_request_options +from .....types.credentials.packages.credentials import field_create_params, field_update_params +from .....types.credentials.packages.credentials.field_create_response import FieldCreateResponse +from .....types.credentials.packages.credentials.field_delete_response import FieldDeleteResponse +from .....types.credentials.packages.credentials.field_update_response import FieldUpdateResponse + +__all__ = ["FieldsResource", "AsyncFieldsResource"] + + +class FieldsResource(SyncAPIResource): + """Vault & Secrets""" + + @cached_property + def with_raw_response(self) -> FieldsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return FieldsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> FieldsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return FieldsResourceWithStreamingResponse(self) + + def create( + self, + credential_name: str, + *, + package_name: str, + field_type: Literal[ + "email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes" + ], + value: str, + # 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, + ) -> FieldCreateResponse: + """ + Add a new field to an existing credential + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not package_name: + raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") + if not credential_name: + raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") + return self._post( + path_template( + "/credentials/packages/{package_name}/credentials/{credential_name}/fields", + package_name=package_name, + credential_name=credential_name, + ), + body=maybe_transform( + { + "field_type": field_type, + "value": value, + }, + field_create_params.FieldCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FieldCreateResponse, + ) + + def update( + self, + field_type: Literal[ + "email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes" + ], + *, + package_name: str, + credential_name: str, + value: str, + # 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, + ) -> FieldUpdateResponse: + """ + Update the value of a credential field + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not package_name: + raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") + if not credential_name: + raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") + if not field_type: + raise ValueError(f"Expected a non-empty value for `field_type` but received {field_type!r}") + return self._patch( + path_template( + "/credentials/packages/{package_name}/credentials/{credential_name}/fields/{field_type}", + package_name=package_name, + credential_name=credential_name, + field_type=field_type, + ), + 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 + ), + cast_to=FieldUpdateResponse, + ) + + def delete( + self, + field_type: Literal[ + "email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes" + ], + *, + package_name: str, + credential_name: str, + # 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, + ) -> FieldDeleteResponse: + """ + Delete a field from a credential + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not package_name: + raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") + if not credential_name: + raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") + if not field_type: + raise ValueError(f"Expected a non-empty value for `field_type` but received {field_type!r}") + return self._delete( + path_template( + "/credentials/packages/{package_name}/credentials/{credential_name}/fields/{field_type}", + package_name=package_name, + credential_name=credential_name, + field_type=field_type, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FieldDeleteResponse, + ) + + +class AsyncFieldsResource(AsyncAPIResource): + """Vault & Secrets""" + + @cached_property + def with_raw_response(self) -> AsyncFieldsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncFieldsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncFieldsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncFieldsResourceWithStreamingResponse(self) + + async def create( + self, + credential_name: str, + *, + package_name: str, + field_type: Literal[ + "email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes" + ], + value: str, + # 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, + ) -> FieldCreateResponse: + """ + Add a new field to an existing credential + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not package_name: + raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") + if not credential_name: + raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") + return await self._post( + path_template( + "/credentials/packages/{package_name}/credentials/{credential_name}/fields", + package_name=package_name, + credential_name=credential_name, + ), + body=await async_maybe_transform( + { + "field_type": field_type, + "value": value, + }, + field_create_params.FieldCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FieldCreateResponse, + ) + + async def update( + self, + field_type: Literal[ + "email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes" + ], + *, + package_name: str, + credential_name: str, + value: str, + # 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, + ) -> FieldUpdateResponse: + """ + Update the value of a credential field + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not package_name: + raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") + if not credential_name: + raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") + if not field_type: + raise ValueError(f"Expected a non-empty value for `field_type` but received {field_type!r}") + return await self._patch( + path_template( + "/credentials/packages/{package_name}/credentials/{credential_name}/fields/{field_type}", + package_name=package_name, + credential_name=credential_name, + field_type=field_type, + ), + 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 + ), + cast_to=FieldUpdateResponse, + ) + + async def delete( + self, + field_type: Literal[ + "email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes" + ], + *, + package_name: str, + credential_name: str, + # 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, + ) -> FieldDeleteResponse: + """ + Delete a field from a credential + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not package_name: + raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") + if not credential_name: + raise ValueError(f"Expected a non-empty value for `credential_name` but received {credential_name!r}") + if not field_type: + raise ValueError(f"Expected a non-empty value for `field_type` but received {field_type!r}") + return await self._delete( + path_template( + "/credentials/packages/{package_name}/credentials/{credential_name}/fields/{field_type}", + package_name=package_name, + credential_name=credential_name, + field_type=field_type, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FieldDeleteResponse, + ) + + +class FieldsResourceWithRawResponse: + def __init__(self, fields: FieldsResource) -> None: + self._fields = fields + + self.create = to_raw_response_wrapper( + fields.create, + ) + self.update = to_raw_response_wrapper( + fields.update, + ) + self.delete = to_raw_response_wrapper( + fields.delete, + ) + + +class AsyncFieldsResourceWithRawResponse: + def __init__(self, fields: AsyncFieldsResource) -> None: + self._fields = fields + + self.create = async_to_raw_response_wrapper( + fields.create, + ) + self.update = async_to_raw_response_wrapper( + fields.update, + ) + self.delete = async_to_raw_response_wrapper( + fields.delete, + ) + + +class FieldsResourceWithStreamingResponse: + def __init__(self, fields: FieldsResource) -> None: + self._fields = fields + + self.create = to_streamed_response_wrapper( + fields.create, + ) + self.update = to_streamed_response_wrapper( + fields.update, + ) + self.delete = to_streamed_response_wrapper( + fields.delete, + ) + + +class AsyncFieldsResourceWithStreamingResponse: + def __init__(self, fields: AsyncFieldsResource) -> None: + self._fields = fields + + self.create = async_to_streamed_response_wrapper( + fields.create, + ) + self.update = async_to_streamed_response_wrapper( + fields.update, + ) + self.delete = async_to_streamed_response_wrapper( + fields.delete, + ) diff --git a/src/mobilerun_sdk/resources/credentials/packages/packages.py b/src/mobilerun_sdk/resources/credentials/packages/packages.py new file mode 100644 index 0000000..135ccdd --- /dev/null +++ b/src/mobilerun_sdk/resources/credentials/packages/packages.py @@ -0,0 +1,284 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._base_client import make_request_options +from ....types.credentials import package_create_params +from .credentials.credentials import ( + CredentialsResource, + AsyncCredentialsResource, + CredentialsResourceWithRawResponse, + AsyncCredentialsResourceWithRawResponse, + CredentialsResourceWithStreamingResponse, + AsyncCredentialsResourceWithStreamingResponse, +) +from ....types.credentials.package_list_response import PackageListResponse +from ....types.credentials.package_create_response import PackageCreateResponse + +__all__ = ["PackagesResource", "AsyncPackagesResource"] + + +class PackagesResource(SyncAPIResource): + """Vault & Secrets""" + + @cached_property + def credentials(self) -> CredentialsResource: + """Vault & Secrets""" + return CredentialsResource(self._client) + + @cached_property + def with_raw_response(self) -> PackagesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return PackagesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> PackagesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return PackagesResourceWithStreamingResponse(self) + + def create( + self, + *, + package_name: str, + # 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, + ) -> PackageCreateResponse: + """ + Initialize a new package/app + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=PackageCreateResponse, + ) + + def list( + self, + package_name: str, + *, + # 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, + ) -> PackageListResponse: + """ + List credentials for a specific package + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not package_name: + raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") + return self._get( + path_template("/credentials/packages/{package_name}", package_name=package_name), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=PackageListResponse, + ) + + +class AsyncPackagesResource(AsyncAPIResource): + """Vault & Secrets""" + + @cached_property + def credentials(self) -> AsyncCredentialsResource: + """Vault & Secrets""" + return AsyncCredentialsResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncPackagesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncPackagesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncPackagesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncPackagesResourceWithStreamingResponse(self) + + async def create( + self, + *, + package_name: str, + # 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, + ) -> PackageCreateResponse: + """ + Initialize a new package/app + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=PackageCreateResponse, + ) + + async def list( + self, + package_name: str, + *, + # 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, + ) -> PackageListResponse: + """ + List credentials for a specific package + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not package_name: + raise ValueError(f"Expected a non-empty value for `package_name` but received {package_name!r}") + return await self._get( + path_template("/credentials/packages/{package_name}", package_name=package_name), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=PackageListResponse, + ) + + +class PackagesResourceWithRawResponse: + def __init__(self, packages: PackagesResource) -> None: + self._packages = packages + + self.create = to_raw_response_wrapper( + packages.create, + ) + self.list = to_raw_response_wrapper( + packages.list, + ) + + @cached_property + def credentials(self) -> CredentialsResourceWithRawResponse: + """Vault & Secrets""" + return CredentialsResourceWithRawResponse(self._packages.credentials) + + +class AsyncPackagesResourceWithRawResponse: + def __init__(self, packages: AsyncPackagesResource) -> None: + self._packages = packages + + self.create = async_to_raw_response_wrapper( + packages.create, + ) + self.list = async_to_raw_response_wrapper( + packages.list, + ) + + @cached_property + def credentials(self) -> AsyncCredentialsResourceWithRawResponse: + """Vault & Secrets""" + return AsyncCredentialsResourceWithRawResponse(self._packages.credentials) + + +class PackagesResourceWithStreamingResponse: + def __init__(self, packages: PackagesResource) -> None: + self._packages = packages + + self.create = to_streamed_response_wrapper( + packages.create, + ) + self.list = to_streamed_response_wrapper( + packages.list, + ) + + @cached_property + def credentials(self) -> CredentialsResourceWithStreamingResponse: + """Vault & Secrets""" + return CredentialsResourceWithStreamingResponse(self._packages.credentials) + + +class AsyncPackagesResourceWithStreamingResponse: + def __init__(self, packages: AsyncPackagesResource) -> None: + self._packages = packages + + self.create = async_to_streamed_response_wrapper( + packages.create, + ) + self.list = async_to_streamed_response_wrapper( + packages.list, + ) + + @cached_property + def credentials(self) -> AsyncCredentialsResourceWithStreamingResponse: + """Vault & Secrets""" + return AsyncCredentialsResourceWithStreamingResponse(self._packages.credentials) diff --git a/src/mobilerun_sdk/resources/devices/devices.py b/src/mobilerun_sdk/resources/devices/devices.py index b70b517..31c41ed 100644 --- a/src/mobilerun_sdk/resources/devices/devices.py +++ b/src/mobilerun_sdk/resources/devices/devices.py @@ -48,12 +48,7 @@ TasksResourceWithStreamingResponse, AsyncTasksResourceWithStreamingResponse, ) -from ...types import ( - device_list_params, - device_create_params, - device_set_name_params, - device_terminate_params, -) +from ...types import device_list_params, device_create_params, device_set_name_params, device_terminate_params from .actions import ( ActionsResource, AsyncActionsResource, @@ -130,7 +125,6 @@ ) from ..._base_client import make_request_options from ...types.device import Device -from ...types.proxy_config_param import ProxyConfigParam from ...types.device_list_response import DeviceListResponse from ...types.device_count_response import DeviceCountResponse from ...types.shared_params.location import Location @@ -184,6 +178,7 @@ def state(self) -> StateResource: @cached_property def tasks(self) -> TasksResource: + """Device Management""" return TasksResource(self._client) @cached_property @@ -229,7 +224,7 @@ def create( locale: str | Omit = omit, location: Location | Omit = omit, name: str | Omit = omit, - proxy: ProxyConfigParam | Omit = omit, + proxy: device_create_params.Proxy | Omit = omit, timezone: 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. @@ -678,6 +673,7 @@ def state(self) -> AsyncStateResource: @cached_property def tasks(self) -> AsyncTasksResource: + """Device Management""" return AsyncTasksResource(self._client) @cached_property @@ -723,7 +719,7 @@ async def create( locale: str | Omit = omit, location: Location | Omit = omit, name: str | Omit = omit, - proxy: ProxyConfigParam | Omit = omit, + proxy: device_create_params.Proxy | Omit = omit, timezone: 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. @@ -1206,6 +1202,7 @@ def state(self) -> StateResourceWithRawResponse: @cached_property def tasks(self) -> TasksResourceWithRawResponse: + """Device Management""" return TasksResourceWithRawResponse(self._devices.tasks) @cached_property @@ -1294,6 +1291,7 @@ def state(self) -> AsyncStateResourceWithRawResponse: @cached_property def tasks(self) -> AsyncTasksResourceWithRawResponse: + """Device Management""" return AsyncTasksResourceWithRawResponse(self._devices.tasks) @cached_property @@ -1382,6 +1380,7 @@ def state(self) -> StateResourceWithStreamingResponse: @cached_property def tasks(self) -> TasksResourceWithStreamingResponse: + """Device Management""" return TasksResourceWithStreamingResponse(self._devices.tasks) @cached_property @@ -1470,6 +1469,7 @@ def state(self) -> AsyncStateResourceWithStreamingResponse: @cached_property def tasks(self) -> AsyncTasksResourceWithStreamingResponse: + """Device Management""" return AsyncTasksResourceWithStreamingResponse(self._devices.tasks) @cached_property diff --git a/src/mobilerun_sdk/resources/devices/tasks.py b/src/mobilerun_sdk/resources/devices/tasks.py index 62c8d6f..061d2ca 100644 --- a/src/mobilerun_sdk/resources/devices/tasks.py +++ b/src/mobilerun_sdk/resources/devices/tasks.py @@ -24,6 +24,8 @@ class TasksResource(SyncAPIResource): + """Device Management""" + @cached_property def with_raw_response(self) -> TasksResourceWithRawResponse: """ @@ -94,6 +96,8 @@ def list( class AsyncTasksResource(AsyncAPIResource): + """Device Management""" + @cached_property def with_raw_response(self) -> AsyncTasksResourceWithRawResponse: """ diff --git a/src/mobilerun_sdk/resources/hooks.py b/src/mobilerun_sdk/resources/hooks.py index 39a730c..6f3c43b 100644 --- a/src/mobilerun_sdk/resources/hooks.py +++ b/src/mobilerun_sdk/resources/hooks.py @@ -32,8 +32,6 @@ class HooksResource(SyncAPIResource): - """Webhooks API""" - @cached_property def with_raw_response(self) -> HooksResourceWithRawResponse: """ @@ -357,8 +355,6 @@ def unsubscribe( class AsyncHooksResource(AsyncAPIResource): - """Webhooks API""" - @cached_property def with_raw_response(self) -> AsyncHooksResourceWithRawResponse: """ diff --git a/src/mobilerun_sdk/resources/models.py b/src/mobilerun_sdk/resources/models.py index d1edbdd..4bb2764 100644 --- a/src/mobilerun_sdk/resources/models.py +++ b/src/mobilerun_sdk/resources/models.py @@ -20,6 +20,8 @@ class ModelsResource(SyncAPIResource): + """LLM Models""" + @cached_property def with_raw_response(self) -> ModelsResourceWithRawResponse: """ @@ -60,6 +62,8 @@ def list( class AsyncModelsResource(AsyncAPIResource): + """LLM Models""" + @cached_property def with_raw_response(self) -> AsyncModelsResourceWithRawResponse: """ diff --git a/src/mobilerun_sdk/resources/proxies.py b/src/mobilerun_sdk/resources/proxies.py index 1e8cfed..4abd363 100644 --- a/src/mobilerun_sdk/resources/proxies.py +++ b/src/mobilerun_sdk/resources/proxies.py @@ -2,11 +2,13 @@ from __future__ import annotations +from typing_extensions import Literal, overload + import httpx -from ..types import proxy_lookup_params -from .._types import Body, Query, Headers, NotGiven, not_given -from .._utils import maybe_transform, async_maybe_transform +from ..types import proxy_list_params, proxy_create_params, proxy_lookup_params, proxy_update_params +from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from .._utils import path_template, required_args, maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -16,12 +18,19 @@ async_to_streamed_response_wrapper, ) from .._base_client import make_request_options +from ..types.proxy_list_response import ProxyListResponse +from ..types.proxy_create_response import ProxyCreateResponse +from ..types.proxy_delete_response import ProxyDeleteResponse from ..types.proxy_lookup_response import ProxyLookupResponse +from ..types.proxy_update_response import ProxyUpdateResponse +from ..types.proxy_retrieve_response import ProxyRetrieveResponse __all__ = ["ProxiesResource", "AsyncProxiesResource"] class ProxiesResource(SyncAPIResource): + """Network Proxies""" + @cached_property def with_raw_response(self) -> ProxiesResourceWithRawResponse: """ @@ -41,6 +50,306 @@ def with_streaming_response(self) -> ProxiesResourceWithStreamingResponse: """ return ProxiesResourceWithStreamingResponse(self) + @overload + def create( + self, + *, + host: str, + name: str, + password: str, + port: int, + protocol: Literal["socks5"], + user: str, + # 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, + ) -> ProxyCreateResponse: + """ + Create a new proxy config + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @overload + def create( + self, + *, + config: str, + name: str, + protocol: Literal["wireguard"], + # 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, + ) -> ProxyCreateResponse: + """ + Create a new proxy config + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @required_args(["host", "name", "password", "port", "protocol", "user"], ["config", "name", "protocol"]) + def create( + self, + *, + host: str | Omit = omit, + name: str, + password: str | Omit = omit, + port: int | Omit = omit, + protocol: Literal["socks5"] | Literal["wireguard"], + user: str | Omit = omit, + config: 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, + ) -> ProxyCreateResponse: + return self._post( + "/proxies", + body=maybe_transform( + { + "host": host, + "name": name, + "password": password, + "port": port, + "protocol": protocol, + "user": user, + "config": config, + }, + proxy_create_params.ProxyCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ProxyCreateResponse, + ) + + def retrieve( + self, + proxy_id: str, + *, + # 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, + ) -> ProxyRetrieveResponse: + """ + Get a specific proxy config + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not proxy_id: + raise ValueError(f"Expected a non-empty value for `proxy_id` but received {proxy_id!r}") + return self._get( + 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 + ), + cast_to=ProxyRetrieveResponse, + ) + + @overload + def update( + self, + proxy_id: str, + *, + host: str, + name: str, + password: str, + port: int, + protocol: Literal["socks5"], + user: str, + # 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, + ) -> ProxyUpdateResponse: + """ + Update a proxy config + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @overload + def update( + self, + proxy_id: str, + *, + config: str, + name: str, + protocol: Literal["wireguard"], + # 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, + ) -> ProxyUpdateResponse: + """ + Update a proxy config + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @required_args(["host", "name", "password", "port", "protocol", "user"], ["config", "name", "protocol"]) + def update( + self, + proxy_id: str, + *, + host: str | Omit = omit, + name: str, + password: str | Omit = omit, + port: int | Omit = omit, + protocol: Literal["socks5"] | Literal["wireguard"], + user: str | Omit = omit, + config: 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, + ) -> ProxyUpdateResponse: + if not proxy_id: + raise ValueError(f"Expected a non-empty value for `proxy_id` but received {proxy_id!r}") + return self._put( + path_template("/proxies/{proxy_id}", proxy_id=proxy_id), + body=maybe_transform( + { + "host": host, + "name": name, + "password": password, + "port": port, + "protocol": protocol, + "user": user, + "config": config, + }, + proxy_update_params.ProxyUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ProxyUpdateResponse, + ) + + def list( + self, + *, + protocol: Literal["socks5", "wireguard"] | 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, + ) -> ProxyListResponse: + """ + List all proxy configs for the authenticated user + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get( + "/proxies", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"protocol": protocol}, proxy_list_params.ProxyListParams), + ), + cast_to=ProxyListResponse, + ) + + def delete( + self, + proxy_id: str, + *, + # 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, + ) -> ProxyDeleteResponse: + """ + Delete a proxy config + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=ProxyDeleteResponse, + ) + def lookup( self, *, @@ -77,6 +386,8 @@ def lookup( class AsyncProxiesResource(AsyncAPIResource): + """Network Proxies""" + @cached_property def with_raw_response(self) -> AsyncProxiesResourceWithRawResponse: """ @@ -96,6 +407,306 @@ def with_streaming_response(self) -> AsyncProxiesResourceWithStreamingResponse: """ return AsyncProxiesResourceWithStreamingResponse(self) + @overload + async def create( + self, + *, + host: str, + name: str, + password: str, + port: int, + protocol: Literal["socks5"], + user: str, + # 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, + ) -> ProxyCreateResponse: + """ + Create a new proxy config + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @overload + async def create( + self, + *, + config: str, + name: str, + protocol: Literal["wireguard"], + # 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, + ) -> ProxyCreateResponse: + """ + Create a new proxy config + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @required_args(["host", "name", "password", "port", "protocol", "user"], ["config", "name", "protocol"]) + async def create( + self, + *, + host: str | Omit = omit, + name: str, + password: str | Omit = omit, + port: int | Omit = omit, + protocol: Literal["socks5"] | Literal["wireguard"], + user: str | Omit = omit, + config: 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, + ) -> ProxyCreateResponse: + return await self._post( + "/proxies", + body=await async_maybe_transform( + { + "host": host, + "name": name, + "password": password, + "port": port, + "protocol": protocol, + "user": user, + "config": config, + }, + proxy_create_params.ProxyCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ProxyCreateResponse, + ) + + async def retrieve( + self, + proxy_id: str, + *, + # 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, + ) -> ProxyRetrieveResponse: + """ + Get a specific proxy config + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not proxy_id: + raise ValueError(f"Expected a non-empty value for `proxy_id` but received {proxy_id!r}") + return await self._get( + 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 + ), + cast_to=ProxyRetrieveResponse, + ) + + @overload + async def update( + self, + proxy_id: str, + *, + host: str, + name: str, + password: str, + port: int, + protocol: Literal["socks5"], + user: str, + # 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, + ) -> ProxyUpdateResponse: + """ + Update a proxy config + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @overload + async def update( + self, + proxy_id: str, + *, + config: str, + name: str, + protocol: Literal["wireguard"], + # 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, + ) -> ProxyUpdateResponse: + """ + Update a proxy config + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @required_args(["host", "name", "password", "port", "protocol", "user"], ["config", "name", "protocol"]) + async def update( + self, + proxy_id: str, + *, + host: str | Omit = omit, + name: str, + password: str | Omit = omit, + port: int | Omit = omit, + protocol: Literal["socks5"] | Literal["wireguard"], + user: str | Omit = omit, + config: 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, + ) -> ProxyUpdateResponse: + if not proxy_id: + raise ValueError(f"Expected a non-empty value for `proxy_id` but received {proxy_id!r}") + return await self._put( + path_template("/proxies/{proxy_id}", proxy_id=proxy_id), + body=await async_maybe_transform( + { + "host": host, + "name": name, + "password": password, + "port": port, + "protocol": protocol, + "user": user, + "config": config, + }, + proxy_update_params.ProxyUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ProxyUpdateResponse, + ) + + async def list( + self, + *, + protocol: Literal["socks5", "wireguard"] | 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, + ) -> ProxyListResponse: + """ + List all proxy configs for the authenticated user + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._get( + "/proxies", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform({"protocol": protocol}, proxy_list_params.ProxyListParams), + ), + cast_to=ProxyListResponse, + ) + + async def delete( + self, + proxy_id: str, + *, + # 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, + ) -> ProxyDeleteResponse: + """ + Delete a proxy config + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=ProxyDeleteResponse, + ) + async def lookup( self, *, @@ -135,6 +746,21 @@ class ProxiesResourceWithRawResponse: def __init__(self, proxies: ProxiesResource) -> None: self._proxies = proxies + self.create = to_raw_response_wrapper( + proxies.create, + ) + self.retrieve = to_raw_response_wrapper( + proxies.retrieve, + ) + self.update = to_raw_response_wrapper( + proxies.update, + ) + self.list = to_raw_response_wrapper( + proxies.list, + ) + self.delete = to_raw_response_wrapper( + proxies.delete, + ) self.lookup = to_raw_response_wrapper( proxies.lookup, ) @@ -144,6 +770,21 @@ class AsyncProxiesResourceWithRawResponse: def __init__(self, proxies: AsyncProxiesResource) -> None: self._proxies = proxies + self.create = async_to_raw_response_wrapper( + proxies.create, + ) + self.retrieve = async_to_raw_response_wrapper( + proxies.retrieve, + ) + self.update = async_to_raw_response_wrapper( + proxies.update, + ) + self.list = async_to_raw_response_wrapper( + proxies.list, + ) + self.delete = async_to_raw_response_wrapper( + proxies.delete, + ) self.lookup = async_to_raw_response_wrapper( proxies.lookup, ) @@ -153,6 +794,21 @@ class ProxiesResourceWithStreamingResponse: def __init__(self, proxies: ProxiesResource) -> None: self._proxies = proxies + self.create = to_streamed_response_wrapper( + proxies.create, + ) + self.retrieve = to_streamed_response_wrapper( + proxies.retrieve, + ) + self.update = to_streamed_response_wrapper( + proxies.update, + ) + self.list = to_streamed_response_wrapper( + proxies.list, + ) + self.delete = to_streamed_response_wrapper( + proxies.delete, + ) self.lookup = to_streamed_response_wrapper( proxies.lookup, ) @@ -162,6 +818,21 @@ class AsyncProxiesResourceWithStreamingResponse: def __init__(self, proxies: AsyncProxiesResource) -> None: self._proxies = proxies + self.create = async_to_streamed_response_wrapper( + proxies.create, + ) + self.retrieve = async_to_streamed_response_wrapper( + proxies.retrieve, + ) + self.update = async_to_streamed_response_wrapper( + proxies.update, + ) + self.list = async_to_streamed_response_wrapper( + proxies.list, + ) + self.delete = async_to_streamed_response_wrapper( + proxies.delete, + ) self.lookup = async_to_streamed_response_wrapper( proxies.lookup, ) diff --git a/src/mobilerun_sdk/types/__init__.py b/src/mobilerun_sdk/types/__init__.py index 94667ef..abff37b 100644 --- a/src/mobilerun_sdk/types/__init__.py +++ b/src/mobilerun_sdk/types/__init__.py @@ -9,6 +9,7 @@ Socks5 as Socks5, Location as Location, DeviceSpec as DeviceSpec, + Pagination as Pagination, DeviceCarrier as DeviceCarrier, PermissionSet as PermissionSet, PaginationMeta as PaginationMeta, @@ -18,28 +19,35 @@ from .task_status import TaskStatus as TaskStatus from .proxy_config import ProxyConfig as ProxyConfig from .usage_result import UsageResult as UsageResult +from .app_list_params import AppListParams as AppListParams from .task_run_params import TaskRunParams as TaskRunParams from .hook_list_params import HookListParams as HookListParams from .hook_test_params import HookTestParams as HookTestParams from .task_list_params import TaskListParams as TaskListParams +from .app_list_response import AppListResponse as AppListResponse +from .proxy_list_params import ProxyListParams as ProxyListParams from .task_run_response import TaskRunResponse as TaskRunResponse from .device_list_params import DeviceListParams as DeviceListParams from .hook_list_response import HookListResponse as HookListResponse from .hook_test_response import HookTestResponse as HookTestResponse from .hook_update_params import HookUpdateParams as HookUpdateParams -from .proxy_config_param import ProxyConfigParam as ProxyConfigParam from .task_list_response import TaskListResponse as TaskListResponse from .task_stop_response import TaskStopResponse as TaskStopResponse from .agent_list_response import AgentListResponse as AgentListResponse +from .app_delete_response import AppDeleteResponse as AppDeleteResponse from .carrier_list_params import CarrierListParams as CarrierListParams from .hook_perform_params import HookPerformParams as HookPerformParams from .model_list_response import ModelListResponse as ModelListResponse from .package_credentials import PackageCredentials as PackageCredentials from .profile_list_params import ProfileListParams as ProfileListParams +from .proxy_create_params import ProxyCreateParams as ProxyCreateParams +from .proxy_list_response import ProxyListResponse as ProxyListResponse from .proxy_lookup_params import ProxyLookupParams as ProxyLookupParams +from .proxy_update_params import ProxyUpdateParams as ProxyUpdateParams from .device_create_params import DeviceCreateParams as DeviceCreateParams from .device_list_response import DeviceListResponse as DeviceListResponse from .hook_update_response import HookUpdateResponse as HookUpdateResponse +from .app_retrieve_response import AppRetrieveResponse as AppRetrieveResponse from .carrier_create_params import CarrierCreateParams as CarrierCreateParams from .carrier_list_response import CarrierListResponse as CarrierListResponse from .carrier_lookup_params import CarrierLookupParams as CarrierLookupParams @@ -50,7 +58,11 @@ from .profile_create_params import ProfileCreateParams as ProfileCreateParams from .profile_list_response import ProfileListResponse as ProfileListResponse from .profile_update_params import ProfileUpdateParams as ProfileUpdateParams +from .proxy_create_response import ProxyCreateResponse as ProxyCreateResponse +from .proxy_delete_response import ProxyDeleteResponse as ProxyDeleteResponse from .proxy_lookup_response import ProxyLookupResponse as ProxyLookupResponse +from .proxy_update_response import ProxyUpdateResponse as ProxyUpdateResponse +from .credential_list_params import CredentialListParams as CredentialListParams from .device_set_name_params import DeviceSetNameParams as DeviceSetNameParams from .hook_retrieve_response import HookRetrieveResponse as HookRetrieveResponse from .task_retrieve_response import TaskRetrieveResponse as TaskRetrieveResponse @@ -61,13 +73,20 @@ from .device_terminate_params import DeviceTerminateParams as DeviceTerminateParams from .hook_subscribe_response import HookSubscribeResponse as HookSubscribeResponse from .profile_delete_response import ProfileDeleteResponse as ProfileDeleteResponse +from .proxy_retrieve_response import ProxyRetrieveResponse as ProxyRetrieveResponse +from .app_mark_failed_response import AppMarkFailedResponse as AppMarkFailedResponse +from .credential_list_response import CredentialListResponse as CredentialListResponse from .task_get_status_response import TaskGetStatusResponse as TaskGetStatusResponse from .task_run_streamed_params import TaskRunStreamedParams as TaskRunStreamedParams from .task_send_message_params import TaskSendMessageParams as TaskSendMessageParams from .carrier_retrieve_response import CarrierRetrieveResponse as CarrierRetrieveResponse from .hook_unsubscribe_response import HookUnsubscribeResponse as HookUnsubscribeResponse from .package_credentials_param import PackageCredentialsParam as PackageCredentialsParam +from .app_list_versions_response import AppListVersionsResponse as AppListVersionsResponse from .task_send_message_response import TaskSendMessageResponse as TaskSendMessageResponse +from .app_confirm_upload_response import AppConfirmUploadResponse as AppConfirmUploadResponse from .device_fingerprint_response import DeviceFingerprintResponse as DeviceFingerprintResponse from .task_get_trajectory_response import TaskGetTrajectoryResponse as TaskGetTrajectoryResponse from .hook_get_sample_data_response import HookGetSampleDataResponse as HookGetSampleDataResponse +from .app_create_signed_upload_url_params import AppCreateSignedUploadURLParams as AppCreateSignedUploadURLParams +from .app_create_signed_upload_url_response import AppCreateSignedUploadURLResponse as AppCreateSignedUploadURLResponse diff --git a/src/mobilerun_sdk/types/app_confirm_upload_response.py b/src/mobilerun_sdk/types/app_confirm_upload_response.py new file mode 100644 index 0000000..da579dc --- /dev/null +++ b/src/mobilerun_sdk/types/app_confirm_upload_response.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from .._models import BaseModel + +__all__ = ["AppConfirmUploadResponse"] + + +class AppConfirmUploadResponse(BaseModel): + message: str + + success: Literal[True] diff --git a/src/mobilerun_sdk/types/app_create_signed_upload_url_params.py b/src/mobilerun_sdk/types/app_create_signed_upload_url_params.py new file mode 100644 index 0000000..a374c4b --- /dev/null +++ b/src/mobilerun_sdk/types/app_create_signed_upload_url_params.py @@ -0,0 +1,43 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Literal, Required, Annotated, TypedDict + +from .._utils import PropertyInfo + +__all__ = ["AppCreateSignedUploadURLParams", "File"] + + +class AppCreateSignedUploadURLParams(TypedDict, total=False): + bundle_id: Required[Annotated[str, PropertyInfo(alias="bundleId")]] + + display_name: Required[Annotated[str, PropertyInfo(alias="displayName")]] + + files: Required[Iterable[File]] + + size_bytes: Required[Annotated[float, PropertyInfo(alias="sizeBytes")]] + + version_code: Required[Annotated[float, PropertyInfo(alias="versionCode")]] + + version_name: Required[Annotated[str, PropertyInfo(alias="versionName")]] + + country: str + """Country code for Search Results""" + + description: str + + developer_name: Annotated[str, PropertyInfo(alias="developerName")] + + icon_url: Annotated[str, PropertyInfo(alias="iconURL")] + + platform: Literal["android", "ios"] + + target_sdk: Annotated[float, PropertyInfo(alias="targetSdk")] + + +class File(TypedDict, total=False): + content_type: Required[Annotated[str, PropertyInfo(alias="contentType")]] + + file_name: Required[Annotated[str, PropertyInfo(alias="fileName")]] diff --git a/src/mobilerun_sdk/types/app_create_signed_upload_url_response.py b/src/mobilerun_sdk/types/app_create_signed_upload_url_response.py new file mode 100644 index 0000000..8d15581 --- /dev/null +++ b/src/mobilerun_sdk/types/app_create_signed_upload_url_response.py @@ -0,0 +1,26 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["AppCreateSignedUploadURLResponse", "R2UploadURL"] + + +class R2UploadURL(BaseModel): + file_name: str = FieldInfo(alias="fileName") + + r2_upload_url: str = FieldInfo(alias="r2UploadUrl") + + +class AppCreateSignedUploadURLResponse(BaseModel): + app_id: str = FieldInfo(alias="appId") + """App ID in the database""" + + r2_upload_urls: List[R2UploadURL] = FieldInfo(alias="r2UploadUrls") + """Pre-signed Cloudflare R2 URLs for uploading app files""" + + version_id: str = FieldInfo(alias="versionId") + """App version ID in the database""" diff --git a/src/mobilerun_sdk/types/app_delete_response.py b/src/mobilerun_sdk/types/app_delete_response.py new file mode 100644 index 0000000..5dce5fa --- /dev/null +++ b/src/mobilerun_sdk/types/app_delete_response.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from .._models import BaseModel + +__all__ = ["AppDeleteResponse"] + + +class AppDeleteResponse(BaseModel): + message: str + + success: Literal[True] diff --git a/src/mobilerun_sdk/types/app_list_params.py b/src/mobilerun_sdk/types/app_list_params.py new file mode 100644 index 0000000..319c937 --- /dev/null +++ b/src/mobilerun_sdk/types/app_list_params.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Annotated, TypedDict + +from .._utils import PropertyInfo + +__all__ = ["AppListParams"] + + +class AppListParams(TypedDict, total=False): + order: Literal["asc", "desc"] + + page: int + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + + platform: Literal["all", "android", "ios"] + + query: str + + sort_by: Annotated[Literal["createdAt", "name"], PropertyInfo(alias="sortBy")] + + status: Literal["all", "queued", "available", "failed"] diff --git a/src/mobilerun_sdk/types/app_list_response.py b/src/mobilerun_sdk/types/app_list_response.py new file mode 100644 index 0000000..f7e2394 --- /dev/null +++ b/src/mobilerun_sdk/types/app_list_response.py @@ -0,0 +1,333 @@ +# 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 +from .shared.pagination import Pagination + +__all__ = ["AppListResponse", "Count", "Item", "ItemVersion"] + + +class Count(BaseModel): + available_count: float = FieldInfo(alias="availableCount") + + failed_count: float = FieldInfo(alias="failedCount") + + queued_count: float = FieldInfo(alias="queuedCount") + + total_count: float = FieldInfo(alias="totalCount") + + +class ItemVersion(BaseModel): + id: str + + app_id: str = FieldInfo(alias="appId") + + country: Literal[ + "AF", + "AL", + "DZ", + "AS", + "AD", + "AO", + "AI", + "AQ", + "AG", + "AR", + "AM", + "AW", + "AP", + "AU", + "AT", + "AZ", + "BS", + "BH", + "BD", + "BB", + "BY", + "BE", + "BZ", + "BJ", + "BM", + "BT", + "BO", + "BQ", + "BA", + "BW", + "BV", + "BR", + "IO", + "BN", + "BG", + "BF", + "BI", + "KH", + "CM", + "CA", + "CV", + "KY", + "CF", + "TD", + "CL", + "CN", + "CX", + "CC", + "CO", + "KM", + "CG", + "CD", + "CK", + "CR", + "HR", + "CU", + "CW", + "CY", + "CZ", + "CI", + "DK", + "DJ", + "DM", + "DO", + "EC", + "EG", + "SV", + "GQ", + "ER", + "EE", + "ET", + "FK", + "FO", + "FJ", + "FI", + "FR", + "GF", + "PF", + "TF", + "GA", + "GM", + "GE", + "DE", + "GH", + "GI", + "GR", + "GL", + "GD", + "GP", + "GU", + "GT", + "GG", + "GN", + "GW", + "GY", + "HT", + "HM", + "VA", + "HN", + "HK", + "HU", + "IS", + "IN", + "ID", + "IR", + "IQ", + "IE", + "IM", + "IL", + "IT", + "JM", + "JP", + "JE", + "JO", + "KZ", + "KE", + "KI", + "KR", + "KW", + "KG", + "LA", + "LV", + "LB", + "LS", + "LR", + "LY", + "LI", + "LT", + "LU", + "MO", + "MG", + "MW", + "MY", + "MV", + "ML", + "MT", + "MH", + "MQ", + "MR", + "MU", + "YT", + "MX", + "FM", + "MD", + "MC", + "MN", + "ME", + "MS", + "MA", + "MZ", + "MM", + "NA", + "NR", + "NP", + "NL", + "AN", + "NC", + "NZ", + "NI", + "NE", + "NG", + "NU", + "NF", + "KP", + "MK", + "MP", + "NO", + "OM", + "PK", + "PW", + "PS", + "PA", + "PG", + "PY", + "PE", + "PH", + "PN", + "PL", + "PT", + "PR", + "QA", + "RE", + "RO", + "RU", + "RW", + "BL", + "SH", + "KN", + "LC", + "MF", + "PM", + "VC", + "WS", + "SM", + "ST", + "SA", + "SN", + "RS", + "CS", + "SC", + "SL", + "SG", + "SX", + "SK", + "SI", + "SB", + "SO", + "ZA", + "GS", + "SS", + "ES", + "LK", + "SD", + "SR", + "SJ", + "SZ", + "SE", + "CH", + "SY", + "TW", + "TJ", + "TZ", + "TH", + "TL", + "TG", + "TK", + "TO", + "TT", + "TN", + "TR", + "TM", + "TC", + "TV", + "UG", + "UA", + "AE", + "GB", + "US", + "UM", + "UY", + "UZ", + "VU", + "VE", + "VN", + "VG", + "VI", + "WF", + "EH", + "YE", + "ZM", + "ZW", + "AX", + ] + + created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None) + + queued_at: Optional[datetime] = FieldInfo(alias="queuedAt", default=None) + + size_bytes: Optional[int] = FieldInfo(alias="sizeBytes", default=None) + + source: Literal["user", "system", "portal"] + + status: Literal["queued", "available", "failed"] + + target_sdk: Optional[int] = FieldInfo(alias="targetSdk", default=None) + + updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None) + + user_id: Optional[str] = FieldInfo(alias="userId", default=None) + + version_code: int = FieldInfo(alias="versionCode") + + version_name: str = FieldInfo(alias="versionName") + + +class Item(BaseModel): + id: str + + bundle_id: str = FieldInfo(alias="bundleId") + + created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None) + + description: Optional[str] = None + + developer_name: Optional[str] = FieldInfo(alias="developerName", default=None) + + display_name: str = FieldInfo(alias="displayName") + + icon_url: str = FieldInfo(alias="iconURL") + + platform: Literal["android", "ios"] + + updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None) + + version: ItemVersion + + +class AppListResponse(BaseModel): + count: Count + + items: List[Item] + + pagination: Pagination diff --git a/src/mobilerun_sdk/types/app_list_versions_response.py b/src/mobilerun_sdk/types/app_list_versions_response.py new file mode 100644 index 0000000..130eab8 --- /dev/null +++ b/src/mobilerun_sdk/types/app_list_versions_response.py @@ -0,0 +1,296 @@ +# 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__ = ["AppListVersionsResponse", "Data"] + + +class Data(BaseModel): + id: str + + app_id: str = FieldInfo(alias="appId") + + country: Literal[ + "AF", + "AL", + "DZ", + "AS", + "AD", + "AO", + "AI", + "AQ", + "AG", + "AR", + "AM", + "AW", + "AP", + "AU", + "AT", + "AZ", + "BS", + "BH", + "BD", + "BB", + "BY", + "BE", + "BZ", + "BJ", + "BM", + "BT", + "BO", + "BQ", + "BA", + "BW", + "BV", + "BR", + "IO", + "BN", + "BG", + "BF", + "BI", + "KH", + "CM", + "CA", + "CV", + "KY", + "CF", + "TD", + "CL", + "CN", + "CX", + "CC", + "CO", + "KM", + "CG", + "CD", + "CK", + "CR", + "HR", + "CU", + "CW", + "CY", + "CZ", + "CI", + "DK", + "DJ", + "DM", + "DO", + "EC", + "EG", + "SV", + "GQ", + "ER", + "EE", + "ET", + "FK", + "FO", + "FJ", + "FI", + "FR", + "GF", + "PF", + "TF", + "GA", + "GM", + "GE", + "DE", + "GH", + "GI", + "GR", + "GL", + "GD", + "GP", + "GU", + "GT", + "GG", + "GN", + "GW", + "GY", + "HT", + "HM", + "VA", + "HN", + "HK", + "HU", + "IS", + "IN", + "ID", + "IR", + "IQ", + "IE", + "IM", + "IL", + "IT", + "JM", + "JP", + "JE", + "JO", + "KZ", + "KE", + "KI", + "KR", + "KW", + "KG", + "LA", + "LV", + "LB", + "LS", + "LR", + "LY", + "LI", + "LT", + "LU", + "MO", + "MG", + "MW", + "MY", + "MV", + "ML", + "MT", + "MH", + "MQ", + "MR", + "MU", + "YT", + "MX", + "FM", + "MD", + "MC", + "MN", + "ME", + "MS", + "MA", + "MZ", + "MM", + "NA", + "NR", + "NP", + "NL", + "AN", + "NC", + "NZ", + "NI", + "NE", + "NG", + "NU", + "NF", + "KP", + "MK", + "MP", + "NO", + "OM", + "PK", + "PW", + "PS", + "PA", + "PG", + "PY", + "PE", + "PH", + "PN", + "PL", + "PT", + "PR", + "QA", + "RE", + "RO", + "RU", + "RW", + "BL", + "SH", + "KN", + "LC", + "MF", + "PM", + "VC", + "WS", + "SM", + "ST", + "SA", + "SN", + "RS", + "CS", + "SC", + "SL", + "SG", + "SX", + "SK", + "SI", + "SB", + "SO", + "ZA", + "GS", + "SS", + "ES", + "LK", + "SD", + "SR", + "SJ", + "SZ", + "SE", + "CH", + "SY", + "TW", + "TJ", + "TZ", + "TH", + "TL", + "TG", + "TK", + "TO", + "TT", + "TN", + "TR", + "TM", + "TC", + "TV", + "UG", + "UA", + "AE", + "GB", + "US", + "UM", + "UY", + "UZ", + "VU", + "VE", + "VN", + "VG", + "VI", + "WF", + "EH", + "YE", + "ZM", + "ZW", + "AX", + ] + + created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None) + + queued_at: Optional[datetime] = FieldInfo(alias="queuedAt", default=None) + + size_bytes: Optional[int] = FieldInfo(alias="sizeBytes", default=None) + + source: Literal["user", "system", "portal"] + + status: Literal["queued", "available", "failed"] + + target_sdk: Optional[int] = FieldInfo(alias="targetSdk", default=None) + + updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None) + + user_id: Optional[str] = FieldInfo(alias="userId", default=None) + + version_code: int = FieldInfo(alias="versionCode") + + version_name: str = FieldInfo(alias="versionName") + + +class AppListVersionsResponse(BaseModel): + data: List[Data] diff --git a/src/mobilerun_sdk/types/app_mark_failed_response.py b/src/mobilerun_sdk/types/app_mark_failed_response.py new file mode 100644 index 0000000..4df598b --- /dev/null +++ b/src/mobilerun_sdk/types/app_mark_failed_response.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from .._models import BaseModel + +__all__ = ["AppMarkFailedResponse"] + + +class AppMarkFailedResponse(BaseModel): + message: str + + success: Literal[True] diff --git a/src/mobilerun_sdk/types/app_retrieve_response.py b/src/mobilerun_sdk/types/app_retrieve_response.py new file mode 100644 index 0000000..57fd551 --- /dev/null +++ b/src/mobilerun_sdk/types/app_retrieve_response.py @@ -0,0 +1,35 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["AppRetrieveResponse", "Data"] + + +class Data(BaseModel): + id: str + + bundle_id: str = FieldInfo(alias="bundleId") + + created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None) + + description: Optional[str] = None + + developer_name: Optional[str] = FieldInfo(alias="developerName", default=None) + + display_name: str = FieldInfo(alias="displayName") + + icon_url: str = FieldInfo(alias="iconURL") + + platform: Literal["android", "ios"] + + updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None) + + +class AppRetrieveResponse(BaseModel): + data: Data diff --git a/src/mobilerun_sdk/types/credential_list_params.py b/src/mobilerun_sdk/types/credential_list_params.py new file mode 100644 index 0000000..1f94a2e --- /dev/null +++ b/src/mobilerun_sdk/types/credential_list_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Annotated, TypedDict + +from .._utils import PropertyInfo + +__all__ = ["CredentialListParams"] + + +class CredentialListParams(TypedDict, total=False): + page: int + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] diff --git a/src/mobilerun_sdk/types/credential_list_response.py b/src/mobilerun_sdk/types/credential_list_response.py new file mode 100644 index 0000000..0721b2b --- /dev/null +++ b/src/mobilerun_sdk/types/credential_list_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from .._models import BaseModel +from .shared.pagination import Pagination +from .credentials.packages.credential import Credential + +__all__ = ["CredentialListResponse"] + + +class CredentialListResponse(BaseModel): + items: List[Credential] + + pagination: Pagination diff --git a/src/mobilerun_sdk/types/credentials/__init__.py b/src/mobilerun_sdk/types/credentials/__init__.py index f8ee8b1..d2b799c 100644 --- a/src/mobilerun_sdk/types/credentials/__init__.py +++ b/src/mobilerun_sdk/types/credentials/__init__.py @@ -1,3 +1,7 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations + +from .package_create_params import PackageCreateParams as PackageCreateParams +from .package_list_response import PackageListResponse as PackageListResponse +from .package_create_response import PackageCreateResponse as PackageCreateResponse diff --git a/src/mobilerun_sdk/types/credentials/package_create_params.py b/src/mobilerun_sdk/types/credentials/package_create_params.py new file mode 100644 index 0000000..50dad4a --- /dev/null +++ b/src/mobilerun_sdk/types/credentials/package_create_params.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["PackageCreateParams"] + + +class PackageCreateParams(TypedDict, total=False): + package_name: Required[Annotated[str, PropertyInfo(alias="packageName")]] diff --git a/src/mobilerun_sdk/types/credentials/package_create_response.py b/src/mobilerun_sdk/types/credentials/package_create_response.py new file mode 100644 index 0000000..8ff9fa8 --- /dev/null +++ b/src/mobilerun_sdk/types/credentials/package_create_response.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["PackageCreateResponse", "Data"] + + +class Data(BaseModel): + package_name: str = FieldInfo(alias="packageName") + + +class PackageCreateResponse(BaseModel): + data: Data + + message: str + + success: Literal[True] diff --git a/src/mobilerun_sdk/types/credentials/package_list_response.py b/src/mobilerun_sdk/types/credentials/package_list_response.py new file mode 100644 index 0000000..c9567e1 --- /dev/null +++ b/src/mobilerun_sdk/types/credentials/package_list_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ..._models import BaseModel +from .packages.credential import Credential + +__all__ = ["PackageListResponse"] + + +class PackageListResponse(BaseModel): + data: List[Credential] diff --git a/src/mobilerun_sdk/types/credentials/packages/__init__.py b/src/mobilerun_sdk/types/credentials/packages/__init__.py index f8ee8b1..a3bddb0 100644 --- a/src/mobilerun_sdk/types/credentials/packages/__init__.py +++ b/src/mobilerun_sdk/types/credentials/packages/__init__.py @@ -1,3 +1,9 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations + +from .credential import Credential as Credential +from .credential_create_params import CredentialCreateParams as CredentialCreateParams +from .credential_create_response import CredentialCreateResponse as CredentialCreateResponse +from .credential_delete_response import CredentialDeleteResponse as CredentialDeleteResponse +from .credential_retrieve_response import CredentialRetrieveResponse as CredentialRetrieveResponse diff --git a/src/mobilerun_sdk/types/credentials/packages/credential.py b/src/mobilerun_sdk/types/credentials/packages/credential.py new file mode 100644 index 0000000..686342d --- /dev/null +++ b/src/mobilerun_sdk/types/credentials/packages/credential.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ...._models import BaseModel + +__all__ = ["Credential", "Field"] + + +class Field(BaseModel): + field_type: Literal[ + "email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes" + ] = FieldInfo(alias="fieldType") + + value: str + + +class Credential(BaseModel): + credential_name: str = FieldInfo(alias="credentialName") + + fields: List[Field] + + package_name: str = FieldInfo(alias="packageName") + + secret_path: str = FieldInfo(alias="secretPath") + + user_id: str = FieldInfo(alias="userId") diff --git a/src/mobilerun_sdk/types/credentials/packages/credential_create_params.py b/src/mobilerun_sdk/types/credentials/packages/credential_create_params.py new file mode 100644 index 0000000..7925fa5 --- /dev/null +++ b/src/mobilerun_sdk/types/credentials/packages/credential_create_params.py @@ -0,0 +1,27 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["CredentialCreateParams", "Field"] + + +class CredentialCreateParams(TypedDict, total=False): + credential_name: Required[Annotated[str, PropertyInfo(alias="credentialName")]] + + fields: Required[Iterable[Field]] + + +class Field(TypedDict, total=False): + field_type: Required[ + Annotated[ + Literal["email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes"], + PropertyInfo(alias="fieldType"), + ] + ] + + value: Required[str] diff --git a/src/mobilerun_sdk/types/credentials/packages/credential_create_response.py b/src/mobilerun_sdk/types/credentials/packages/credential_create_response.py new file mode 100644 index 0000000..56749ca --- /dev/null +++ b/src/mobilerun_sdk/types/credentials/packages/credential_create_response.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ...._models import BaseModel +from .credential import Credential + +__all__ = ["CredentialCreateResponse"] + + +class CredentialCreateResponse(BaseModel): + data: Credential + + message: str + + success: Literal[True] diff --git a/src/mobilerun_sdk/types/credentials/packages/credential_delete_response.py b/src/mobilerun_sdk/types/credentials/packages/credential_delete_response.py new file mode 100644 index 0000000..9fc9bf4 --- /dev/null +++ b/src/mobilerun_sdk/types/credentials/packages/credential_delete_response.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ...._models import BaseModel +from .credential import Credential + +__all__ = ["CredentialDeleteResponse"] + + +class CredentialDeleteResponse(BaseModel): + data: Credential + + message: str + + success: Literal[True] diff --git a/src/mobilerun_sdk/types/credentials/packages/credential_retrieve_response.py b/src/mobilerun_sdk/types/credentials/packages/credential_retrieve_response.py new file mode 100644 index 0000000..ea546cc --- /dev/null +++ b/src/mobilerun_sdk/types/credentials/packages/credential_retrieve_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel +from .credential import Credential + +__all__ = ["CredentialRetrieveResponse"] + + +class CredentialRetrieveResponse(BaseModel): + data: Credential diff --git a/src/mobilerun_sdk/types/credentials/packages/credentials/__init__.py b/src/mobilerun_sdk/types/credentials/packages/credentials/__init__.py index f8ee8b1..f3e7873 100644 --- a/src/mobilerun_sdk/types/credentials/packages/credentials/__init__.py +++ b/src/mobilerun_sdk/types/credentials/packages/credentials/__init__.py @@ -1,3 +1,9 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations + +from .field_create_params import FieldCreateParams as FieldCreateParams +from .field_update_params import FieldUpdateParams as FieldUpdateParams +from .field_create_response import FieldCreateResponse as FieldCreateResponse +from .field_delete_response import FieldDeleteResponse as FieldDeleteResponse +from .field_update_response import FieldUpdateResponse as FieldUpdateResponse diff --git a/src/mobilerun_sdk/types/credentials/packages/credentials/field_create_params.py b/src/mobilerun_sdk/types/credentials/packages/credentials/field_create_params.py new file mode 100644 index 0000000..debabf7 --- /dev/null +++ b/src/mobilerun_sdk/types/credentials/packages/credentials/field_create_params.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ....._utils import PropertyInfo + +__all__ = ["FieldCreateParams"] + + +class FieldCreateParams(TypedDict, total=False): + package_name: Required[Annotated[str, PropertyInfo(alias="packageName")]] + + field_type: Required[ + Annotated[ + Literal["email", "username", "password", "api_token", "phone_number", "two_factor_secret", "backup_codes"], + PropertyInfo(alias="fieldType"), + ] + ] + + value: Required[str] diff --git a/src/mobilerun_sdk/types/credentials/packages/credentials/field_create_response.py b/src/mobilerun_sdk/types/credentials/packages/credentials/field_create_response.py new file mode 100644 index 0000000..2d7f2d0 --- /dev/null +++ b/src/mobilerun_sdk/types/credentials/packages/credentials/field_create_response.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ....._models import BaseModel +from ..credential import Credential + +__all__ = ["FieldCreateResponse"] + + +class FieldCreateResponse(BaseModel): + data: Credential + + message: str + + success: Literal[True] diff --git a/src/mobilerun_sdk/types/credentials/packages/credentials/field_delete_response.py b/src/mobilerun_sdk/types/credentials/packages/credentials/field_delete_response.py new file mode 100644 index 0000000..67e99f8 --- /dev/null +++ b/src/mobilerun_sdk/types/credentials/packages/credentials/field_delete_response.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ....._models import BaseModel +from ..credential import Credential + +__all__ = ["FieldDeleteResponse"] + + +class FieldDeleteResponse(BaseModel): + data: Credential + + message: str + + success: Literal[True] diff --git a/src/mobilerun_sdk/types/credentials/packages/credentials/field_update_params.py b/src/mobilerun_sdk/types/credentials/packages/credentials/field_update_params.py new file mode 100644 index 0000000..ed62fb1 --- /dev/null +++ b/src/mobilerun_sdk/types/credentials/packages/credentials/field_update_params.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from ....._utils import PropertyInfo + +__all__ = ["FieldUpdateParams"] + + +class FieldUpdateParams(TypedDict, total=False): + package_name: Required[Annotated[str, PropertyInfo(alias="packageName")]] + + credential_name: Required[Annotated[str, PropertyInfo(alias="credentialName")]] + + value: Required[str] diff --git a/src/mobilerun_sdk/types/credentials/packages/credentials/field_update_response.py b/src/mobilerun_sdk/types/credentials/packages/credentials/field_update_response.py new file mode 100644 index 0000000..8676ce3 --- /dev/null +++ b/src/mobilerun_sdk/types/credentials/packages/credentials/field_update_response.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ....._models import BaseModel +from ..credential import Credential + +__all__ = ["FieldUpdateResponse"] + + +class FieldUpdateResponse(BaseModel): + data: Credential + + message: str + + success: Literal[True] diff --git a/src/mobilerun_sdk/types/device_create_params.py b/src/mobilerun_sdk/types/device_create_params.py index 6d5b9b0..a631b9c 100644 --- a/src/mobilerun_sdk/types/device_create_params.py +++ b/src/mobilerun_sdk/types/device_create_params.py @@ -7,12 +7,12 @@ from .._types import SequenceNotStr from .._utils import PropertyInfo -from .proxy_config_param import ProxyConfigParam +from .shared_params.socks5 import Socks5 from .shared_params.location import Location from .shared_params.device_carrier import DeviceCarrier from .shared_params.device_identifiers import DeviceIdentifiers -__all__ = ["DeviceCreateParams"] +__all__ = ["DeviceCreateParams", "Proxy"] class DeviceCreateParams(TypedDict, total=False): @@ -48,6 +48,14 @@ class DeviceCreateParams(TypedDict, total=False): name: str - proxy: ProxyConfigParam + proxy: Proxy timezone: str + + +class Proxy(TypedDict, total=False): + name: str + + smart_ip: Annotated[bool, PropertyInfo(alias="smartIp")] + + socks5: Socks5 diff --git a/src/mobilerun_sdk/types/devices/state_ui_response.py b/src/mobilerun_sdk/types/devices/state_ui_response.py index 80cbe44..bdddd0c 100644 --- a/src/mobilerun_sdk/types/devices/state_ui_response.py +++ b/src/mobilerun_sdk/types/devices/state_ui_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Optional from pydantic import Field as FieldInfo @@ -9,64 +9,14 @@ __all__ = [ "StateUiResponse", - "A11yTree", - "A11yTreeBoundsInScreen", "DeviceContext", "DeviceContextDisplayMetrics", "DeviceContextFilteringParams", - "ImeTree", - "ImeTreeBoundsInScreen", "PhoneState", "PhoneStateFocusedElement", ] -class A11yTreeBoundsInScreen(BaseModel): - bottom: int - - left: int - - right: int - - top: int - - -class A11yTree(BaseModel): - bounds_in_screen: A11yTreeBoundsInScreen = FieldInfo(alias="boundsInScreen") - - children: Optional[List[object]] = None - - class_name: str = FieldInfo(alias="className") - - content_description: str = FieldInfo(alias="contentDescription") - - is_checkable: bool = FieldInfo(alias="isCheckable") - - is_checked: bool = FieldInfo(alias="isChecked") - - is_clickable: bool = FieldInfo(alias="isClickable") - - is_enabled: bool = FieldInfo(alias="isEnabled") - - is_focusable: bool = FieldInfo(alias="isFocusable") - - is_focused: bool = FieldInfo(alias="isFocused") - - is_long_clickable: bool = FieldInfo(alias="isLongClickable") - - is_password: bool = FieldInfo(alias="isPassword") - - is_scrollable: bool = FieldInfo(alias="isScrollable") - - is_selected: bool = FieldInfo(alias="isSelected") - - package_name: str = FieldInfo(alias="packageName") - - resource_id: str = FieldInfo(alias="resourceId") - - text: str - - class DeviceContextDisplayMetrics(BaseModel): density: float @@ -92,51 +42,7 @@ class DeviceContext(BaseModel): screen_bounds: Rect - -class ImeTreeBoundsInScreen(BaseModel): - bottom: int - - left: int - - right: int - - top: int - - -class ImeTree(BaseModel): - bounds_in_screen: ImeTreeBoundsInScreen = FieldInfo(alias="boundsInScreen") - - children: Optional[List[object]] = None - - class_name: str = FieldInfo(alias="className") - - content_description: str = FieldInfo(alias="contentDescription") - - is_checkable: bool = FieldInfo(alias="isCheckable") - - is_checked: bool = FieldInfo(alias="isChecked") - - is_clickable: bool = FieldInfo(alias="isClickable") - - is_enabled: bool = FieldInfo(alias="isEnabled") - - is_focusable: bool = FieldInfo(alias="isFocusable") - - is_focused: bool = FieldInfo(alias="isFocused") - - is_long_clickable: bool = FieldInfo(alias="isLongClickable") - - is_password: bool = FieldInfo(alias="isPassword") - - is_scrollable: bool = FieldInfo(alias="isScrollable") - - is_selected: bool = FieldInfo(alias="isSelected") - - package_name: str = FieldInfo(alias="packageName") - - resource_id: str = FieldInfo(alias="resourceId") - - text: str + screen_size: Rect = FieldInfo(alias="screenSize") class PhoneStateFocusedElement(BaseModel): @@ -162,13 +68,13 @@ class PhoneState(BaseModel): class StateUiResponse(BaseModel): - a11y_tree: A11yTree + a11y_tree: object device_context: DeviceContext - ime_tree: ImeTree - phone_state: PhoneState schema_: Optional[str] = FieldInfo(alias="$schema", default=None) """A URL to the JSON Schema for this object.""" + + ime_tree: Optional[object] = None diff --git a/src/mobilerun_sdk/types/proxy_config.py b/src/mobilerun_sdk/types/proxy_config.py index 5a5715b..52d651c 100644 --- a/src/mobilerun_sdk/types/proxy_config.py +++ b/src/mobilerun_sdk/types/proxy_config.py @@ -1,18 +1,42 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import Union +from typing_extensions import Literal, Annotated, TypeAlias from pydantic import Field as FieldInfo +from .._utils import PropertyInfo from .._models import BaseModel -from .shared.socks5 import Socks5 -__all__ = ["ProxyConfig"] +__all__ = ["ProxyConfig", "Socks5ProxyConfig", "WireguardProxyConfig"] -class ProxyConfig(BaseModel): - name: Optional[str] = None +class Socks5ProxyConfig(BaseModel): + host: str - smart_ip: Optional[bool] = FieldInfo(alias="smartIp", default=None) + name: str - socks5: Optional[Socks5] = None + password: str + + port: int + + protocol: Literal["socks5"] + + proxy_id: str = FieldInfo(alias="proxyId") + + user: str + + +class WireguardProxyConfig(BaseModel): + config: str + + name: str + + protocol: Literal["wireguard"] + + proxy_id: str = FieldInfo(alias="proxyId") + + +ProxyConfig: TypeAlias = Annotated[ + Union[Socks5ProxyConfig, WireguardProxyConfig], PropertyInfo(discriminator="protocol") +] diff --git a/src/mobilerun_sdk/types/proxy_config_param.py b/src/mobilerun_sdk/types/proxy_config_param.py deleted file mode 100644 index c169125..0000000 --- a/src/mobilerun_sdk/types/proxy_config_param.py +++ /dev/null @@ -1,18 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Annotated, TypedDict - -from .._utils import PropertyInfo -from .shared_params.socks5 import Socks5 - -__all__ = ["ProxyConfigParam"] - - -class ProxyConfigParam(TypedDict, total=False): - name: str - - smart_ip: Annotated[bool, PropertyInfo(alias="smartIp")] - - socks5: Socks5 diff --git a/src/mobilerun_sdk/types/proxy_create_params.py b/src/mobilerun_sdk/types/proxy_create_params.py new file mode 100644 index 0000000..1d9fdf4 --- /dev/null +++ b/src/mobilerun_sdk/types/proxy_create_params.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from typing_extensions import Literal, Required, TypeAlias, TypedDict + +__all__ = ["ProxyCreateParams", "CreateSocks5Proxy", "CreateWireguardProxy"] + + +class CreateSocks5Proxy(TypedDict, total=False): + host: Required[str] + + name: Required[str] + + password: Required[str] + + port: Required[int] + + protocol: Required[Literal["socks5"]] + + user: Required[str] + + +class CreateWireguardProxy(TypedDict, total=False): + config: Required[str] + + name: Required[str] + + protocol: Required[Literal["wireguard"]] + + +ProxyCreateParams: TypeAlias = Union[CreateSocks5Proxy, CreateWireguardProxy] diff --git a/src/mobilerun_sdk/types/proxy_create_response.py b/src/mobilerun_sdk/types/proxy_create_response.py new file mode 100644 index 0000000..72a8d2c --- /dev/null +++ b/src/mobilerun_sdk/types/proxy_create_response.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from .._models import BaseModel +from .proxy_config import ProxyConfig + +__all__ = ["ProxyCreateResponse"] + + +class ProxyCreateResponse(BaseModel): + data: ProxyConfig + + message: str + + success: Literal[True] diff --git a/src/mobilerun_sdk/types/proxy_delete_response.py b/src/mobilerun_sdk/types/proxy_delete_response.py new file mode 100644 index 0000000..872567b --- /dev/null +++ b/src/mobilerun_sdk/types/proxy_delete_response.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from .._models import BaseModel +from .proxy_config import ProxyConfig + +__all__ = ["ProxyDeleteResponse"] + + +class ProxyDeleteResponse(BaseModel): + data: ProxyConfig + + message: str + + success: Literal[True] diff --git a/src/mobilerun_sdk/types/proxy_list_params.py b/src/mobilerun_sdk/types/proxy_list_params.py new file mode 100644 index 0000000..6b3d14f --- /dev/null +++ b/src/mobilerun_sdk/types/proxy_list_params.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["ProxyListParams"] + + +class ProxyListParams(TypedDict, total=False): + protocol: Literal["socks5", "wireguard"] diff --git a/src/mobilerun_sdk/types/proxy_list_response.py b/src/mobilerun_sdk/types/proxy_list_response.py new file mode 100644 index 0000000..ff49af0 --- /dev/null +++ b/src/mobilerun_sdk/types/proxy_list_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from .._models import BaseModel +from .proxy_config import ProxyConfig + +__all__ = ["ProxyListResponse"] + + +class ProxyListResponse(BaseModel): + data: List[ProxyConfig] diff --git a/src/mobilerun_sdk/types/proxy_retrieve_response.py b/src/mobilerun_sdk/types/proxy_retrieve_response.py new file mode 100644 index 0000000..6c6a1c5 --- /dev/null +++ b/src/mobilerun_sdk/types/proxy_retrieve_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .._models import BaseModel +from .proxy_config import ProxyConfig + +__all__ = ["ProxyRetrieveResponse"] + + +class ProxyRetrieveResponse(BaseModel): + data: ProxyConfig diff --git a/src/mobilerun_sdk/types/proxy_update_params.py b/src/mobilerun_sdk/types/proxy_update_params.py new file mode 100644 index 0000000..ab81ede --- /dev/null +++ b/src/mobilerun_sdk/types/proxy_update_params.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from typing_extensions import Literal, Required, TypeAlias, TypedDict + +__all__ = ["ProxyUpdateParams", "UpdateSocks5Proxy", "UpdateWireguardProxy"] + + +class UpdateSocks5Proxy(TypedDict, total=False): + host: Required[str] + + name: Required[str] + + password: Required[str] + + port: Required[int] + + protocol: Required[Literal["socks5"]] + + user: Required[str] + + +class UpdateWireguardProxy(TypedDict, total=False): + config: Required[str] + + name: Required[str] + + protocol: Required[Literal["wireguard"]] + + +ProxyUpdateParams: TypeAlias = Union[UpdateSocks5Proxy, UpdateWireguardProxy] diff --git a/src/mobilerun_sdk/types/proxy_update_response.py b/src/mobilerun_sdk/types/proxy_update_response.py new file mode 100644 index 0000000..f1578b4 --- /dev/null +++ b/src/mobilerun_sdk/types/proxy_update_response.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from .._models import BaseModel +from .proxy_config import ProxyConfig + +__all__ = ["ProxyUpdateResponse"] + + +class ProxyUpdateResponse(BaseModel): + data: ProxyConfig + + message: str + + success: Literal[True] diff --git a/src/mobilerun_sdk/types/shared/__init__.py b/src/mobilerun_sdk/types/shared/__init__.py index 92ac387..7d0f116 100644 --- a/src/mobilerun_sdk/types/shared/__init__.py +++ b/src/mobilerun_sdk/types/shared/__init__.py @@ -3,6 +3,7 @@ from .meta import Meta as Meta from .socks5 import Socks5 as Socks5 from .location import Location as Location +from .pagination import Pagination as Pagination from .device_spec import DeviceSpec as DeviceSpec from .device_carrier import DeviceCarrier as DeviceCarrier from .permission_set import PermissionSet as PermissionSet diff --git a/src/mobilerun_sdk/types/shared/device_spec.py b/src/mobilerun_sdk/types/shared/device_spec.py index 0cbc319..64614c9 100644 --- a/src/mobilerun_sdk/types/shared/device_spec.py +++ b/src/mobilerun_sdk/types/shared/device_spec.py @@ -4,13 +4,21 @@ from pydantic import Field as FieldInfo +from .socks5 import Socks5 from .location import Location from ..._models import BaseModel -from ..proxy_config import ProxyConfig from .device_carrier import DeviceCarrier from .device_identifiers import DeviceIdentifiers -__all__ = ["DeviceSpec"] +__all__ = ["DeviceSpec", "Proxy"] + + +class Proxy(BaseModel): + name: Optional[str] = None + + smart_ip: Optional[bool] = FieldInfo(alias="smartIp", default=None) + + socks5: Optional[Socks5] = None class DeviceSpec(BaseModel): @@ -35,6 +43,6 @@ class DeviceSpec(BaseModel): name: Optional[str] = None - proxy: Optional[ProxyConfig] = None + proxy: Optional[Proxy] = None timezone: Optional[str] = None diff --git a/src/mobilerun_sdk/types/shared/pagination.py b/src/mobilerun_sdk/types/shared/pagination.py new file mode 100644 index 0000000..d5a8b19 --- /dev/null +++ b/src/mobilerun_sdk/types/shared/pagination.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["Pagination"] + + +class Pagination(BaseModel): + has_next: bool = FieldInfo(alias="hasNext") + + has_prev: bool = FieldInfo(alias="hasPrev") + + page: int + + pages: int + + page_size: int = FieldInfo(alias="pageSize") + + total: int diff --git a/src/mobilerun_sdk/types/shared_params/device_spec.py b/src/mobilerun_sdk/types/shared_params/device_spec.py index 90a7c89..7d1a43e 100644 --- a/src/mobilerun_sdk/types/shared_params/device_spec.py +++ b/src/mobilerun_sdk/types/shared_params/device_spec.py @@ -5,14 +5,22 @@ from typing import Optional from typing_extensions import Annotated, TypedDict +from .socks5 import Socks5 from ..._types import SequenceNotStr from ..._utils import PropertyInfo from .location import Location from .device_carrier import DeviceCarrier from .device_identifiers import DeviceIdentifiers -from ..proxy_config_param import ProxyConfigParam -__all__ = ["DeviceSpec"] +__all__ = ["DeviceSpec", "Proxy"] + + +class Proxy(TypedDict, total=False): + name: str + + smart_ip: Annotated[bool, PropertyInfo(alias="smartIp")] + + socks5: Socks5 class DeviceSpec(TypedDict, total=False): @@ -34,6 +42,6 @@ class DeviceSpec(TypedDict, total=False): name: str - proxy: ProxyConfigParam + proxy: Proxy timezone: str diff --git a/tests/api_resources/credentials/__init__.py b/tests/api_resources/credentials/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/credentials/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/credentials/packages/__init__.py b/tests/api_resources/credentials/packages/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/credentials/packages/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/credentials/packages/credentials/__init__.py b/tests/api_resources/credentials/packages/credentials/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/credentials/packages/credentials/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/credentials/packages/credentials/test_fields.py b/tests/api_resources/credentials/packages/credentials/test_fields.py new file mode 100644 index 0000000..b16a174 --- /dev/null +++ b/tests/api_resources/credentials/packages/credentials/test_fields.py @@ -0,0 +1,390 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.credentials.packages.credentials import ( + FieldCreateResponse, + FieldDeleteResponse, + FieldUpdateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestFields: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create(self, client: Mobilerun) -> None: + field = client.credentials.packages.credentials.fields.create( + credential_name="credentialName", + package_name="packageName", + field_type="email", + value="x", + ) + assert_matches_type(FieldCreateResponse, field, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: Mobilerun) -> None: + response = client.credentials.packages.credentials.fields.with_raw_response.create( + credential_name="credentialName", + package_name="packageName", + field_type="email", + value="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + field = response.parse() + assert_matches_type(FieldCreateResponse, field, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: Mobilerun) -> None: + with client.credentials.packages.credentials.fields.with_streaming_response.create( + credential_name="credentialName", + package_name="packageName", + field_type="email", + value="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + field = response.parse() + assert_matches_type(FieldCreateResponse, field, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_create(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): + client.credentials.packages.credentials.fields.with_raw_response.create( + credential_name="credentialName", + package_name="", + field_type="email", + value="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): + client.credentials.packages.credentials.fields.with_raw_response.create( + credential_name="", + package_name="packageName", + field_type="email", + value="x", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update(self, client: Mobilerun) -> None: + field = client.credentials.packages.credentials.fields.update( + field_type="email", + package_name="packageName", + credential_name="credentialName", + value="x", + ) + assert_matches_type(FieldUpdateResponse, field, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_update(self, client: Mobilerun) -> None: + response = client.credentials.packages.credentials.fields.with_raw_response.update( + field_type="email", + package_name="packageName", + credential_name="credentialName", + value="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + field = response.parse() + assert_matches_type(FieldUpdateResponse, field, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_update(self, client: Mobilerun) -> None: + with client.credentials.packages.credentials.fields.with_streaming_response.update( + field_type="email", + package_name="packageName", + credential_name="credentialName", + value="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + field = response.parse() + assert_matches_type(FieldUpdateResponse, field, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_update(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): + client.credentials.packages.credentials.fields.with_raw_response.update( + field_type="email", + package_name="", + credential_name="credentialName", + value="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): + client.credentials.packages.credentials.fields.with_raw_response.update( + field_type="email", + package_name="packageName", + credential_name="", + value="x", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete(self, client: Mobilerun) -> None: + field = client.credentials.packages.credentials.fields.delete( + field_type="email", + package_name="packageName", + credential_name="credentialName", + ) + assert_matches_type(FieldDeleteResponse, field, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete(self, client: Mobilerun) -> None: + response = client.credentials.packages.credentials.fields.with_raw_response.delete( + field_type="email", + package_name="packageName", + credential_name="credentialName", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + field = response.parse() + assert_matches_type(FieldDeleteResponse, field, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete(self, client: Mobilerun) -> None: + with client.credentials.packages.credentials.fields.with_streaming_response.delete( + field_type="email", + package_name="packageName", + credential_name="credentialName", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + field = response.parse() + assert_matches_type(FieldDeleteResponse, field, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_delete(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): + client.credentials.packages.credentials.fields.with_raw_response.delete( + field_type="email", + package_name="", + credential_name="credentialName", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): + client.credentials.packages.credentials.fields.with_raw_response.delete( + field_type="email", + package_name="packageName", + credential_name="", + ) + + +class TestAsyncFields: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create(self, async_client: AsyncMobilerun) -> None: + field = await async_client.credentials.packages.credentials.fields.create( + credential_name="credentialName", + package_name="packageName", + field_type="email", + value="x", + ) + assert_matches_type(FieldCreateResponse, field, path=["response"]) + + @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.credentials.packages.credentials.fields.with_raw_response.create( + credential_name="credentialName", + package_name="packageName", + field_type="email", + value="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + field = await response.parse() + assert_matches_type(FieldCreateResponse, field, path=["response"]) + + @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.credentials.packages.credentials.fields.with_streaming_response.create( + credential_name="credentialName", + package_name="packageName", + field_type="email", + value="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + field = await response.parse() + assert_matches_type(FieldCreateResponse, field, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_create(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): + await async_client.credentials.packages.credentials.fields.with_raw_response.create( + credential_name="credentialName", + package_name="", + field_type="email", + value="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): + await async_client.credentials.packages.credentials.fields.with_raw_response.create( + credential_name="", + package_name="packageName", + field_type="email", + value="x", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update(self, async_client: AsyncMobilerun) -> None: + field = await async_client.credentials.packages.credentials.fields.update( + field_type="email", + package_name="packageName", + credential_name="credentialName", + value="x", + ) + assert_matches_type(FieldUpdateResponse, field, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_update(self, async_client: AsyncMobilerun) -> None: + response = await async_client.credentials.packages.credentials.fields.with_raw_response.update( + field_type="email", + package_name="packageName", + credential_name="credentialName", + value="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + field = await response.parse() + assert_matches_type(FieldUpdateResponse, field, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_update(self, async_client: AsyncMobilerun) -> None: + async with async_client.credentials.packages.credentials.fields.with_streaming_response.update( + field_type="email", + package_name="packageName", + credential_name="credentialName", + value="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + field = await response.parse() + assert_matches_type(FieldUpdateResponse, field, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_update(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): + await async_client.credentials.packages.credentials.fields.with_raw_response.update( + field_type="email", + package_name="", + credential_name="credentialName", + value="x", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): + await async_client.credentials.packages.credentials.fields.with_raw_response.update( + field_type="email", + package_name="packageName", + credential_name="", + value="x", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete(self, async_client: AsyncMobilerun) -> None: + field = await async_client.credentials.packages.credentials.fields.delete( + field_type="email", + package_name="packageName", + credential_name="credentialName", + ) + assert_matches_type(FieldDeleteResponse, field, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncMobilerun) -> None: + response = await async_client.credentials.packages.credentials.fields.with_raw_response.delete( + field_type="email", + package_name="packageName", + credential_name="credentialName", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + field = await response.parse() + assert_matches_type(FieldDeleteResponse, field, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncMobilerun) -> None: + async with async_client.credentials.packages.credentials.fields.with_streaming_response.delete( + field_type="email", + package_name="packageName", + credential_name="credentialName", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + field = await response.parse() + assert_matches_type(FieldDeleteResponse, field, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_delete(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): + await async_client.credentials.packages.credentials.fields.with_raw_response.delete( + field_type="email", + package_name="", + credential_name="credentialName", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): + await async_client.credentials.packages.credentials.fields.with_raw_response.delete( + field_type="email", + package_name="packageName", + credential_name="", + ) diff --git a/tests/api_resources/credentials/packages/test_credentials.py b/tests/api_resources/credentials/packages/test_credentials.py new file mode 100644 index 0000000..991d557 --- /dev/null +++ b/tests/api_resources/credentials/packages/test_credentials.py @@ -0,0 +1,376 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.credentials.packages import ( + CredentialCreateResponse, + CredentialDeleteResponse, + CredentialRetrieveResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestCredentials: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create(self, client: Mobilerun) -> None: + credential = client.credentials.packages.credentials.create( + package_name="packageName", + credential_name="26f1kl_-n-71", + fields=[ + { + "field_type": "email", + "value": "x", + } + ], + ) + assert_matches_type(CredentialCreateResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: Mobilerun) -> None: + response = client.credentials.packages.credentials.with_raw_response.create( + package_name="packageName", + credential_name="26f1kl_-n-71", + fields=[ + { + "field_type": "email", + "value": "x", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + credential = response.parse() + assert_matches_type(CredentialCreateResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: Mobilerun) -> None: + with client.credentials.packages.credentials.with_streaming_response.create( + package_name="packageName", + credential_name="26f1kl_-n-71", + fields=[ + { + "field_type": "email", + "value": "x", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + credential = response.parse() + assert_matches_type(CredentialCreateResponse, credential, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_create(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): + client.credentials.packages.credentials.with_raw_response.create( + package_name="", + credential_name="26f1kl_-n-71", + fields=[ + { + "field_type": "email", + "value": "x", + } + ], + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve(self, client: Mobilerun) -> None: + credential = client.credentials.packages.credentials.retrieve( + credential_name="credentialName", + package_name="packageName", + ) + assert_matches_type(CredentialRetrieveResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve(self, client: Mobilerun) -> None: + response = client.credentials.packages.credentials.with_raw_response.retrieve( + credential_name="credentialName", + package_name="packageName", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + credential = response.parse() + assert_matches_type(CredentialRetrieveResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve(self, client: Mobilerun) -> None: + with client.credentials.packages.credentials.with_streaming_response.retrieve( + credential_name="credentialName", + package_name="packageName", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + credential = response.parse() + assert_matches_type(CredentialRetrieveResponse, credential, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_retrieve(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): + client.credentials.packages.credentials.with_raw_response.retrieve( + credential_name="credentialName", + package_name="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): + client.credentials.packages.credentials.with_raw_response.retrieve( + credential_name="", + package_name="packageName", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete(self, client: Mobilerun) -> None: + credential = client.credentials.packages.credentials.delete( + credential_name="credentialName", + package_name="packageName", + ) + assert_matches_type(CredentialDeleteResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete(self, client: Mobilerun) -> None: + response = client.credentials.packages.credentials.with_raw_response.delete( + credential_name="credentialName", + package_name="packageName", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + credential = response.parse() + assert_matches_type(CredentialDeleteResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete(self, client: Mobilerun) -> None: + with client.credentials.packages.credentials.with_streaming_response.delete( + credential_name="credentialName", + package_name="packageName", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + credential = response.parse() + assert_matches_type(CredentialDeleteResponse, credential, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_delete(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): + client.credentials.packages.credentials.with_raw_response.delete( + credential_name="credentialName", + package_name="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): + client.credentials.packages.credentials.with_raw_response.delete( + credential_name="", + package_name="packageName", + ) + + +class TestAsyncCredentials: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create(self, async_client: AsyncMobilerun) -> None: + credential = await async_client.credentials.packages.credentials.create( + package_name="packageName", + credential_name="26f1kl_-n-71", + fields=[ + { + "field_type": "email", + "value": "x", + } + ], + ) + assert_matches_type(CredentialCreateResponse, credential, path=["response"]) + + @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.credentials.packages.credentials.with_raw_response.create( + package_name="packageName", + credential_name="26f1kl_-n-71", + fields=[ + { + "field_type": "email", + "value": "x", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + credential = await response.parse() + assert_matches_type(CredentialCreateResponse, credential, path=["response"]) + + @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.credentials.packages.credentials.with_streaming_response.create( + package_name="packageName", + credential_name="26f1kl_-n-71", + fields=[ + { + "field_type": "email", + "value": "x", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + credential = await response.parse() + assert_matches_type(CredentialCreateResponse, credential, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_create(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): + await async_client.credentials.packages.credentials.with_raw_response.create( + package_name="", + credential_name="26f1kl_-n-71", + fields=[ + { + "field_type": "email", + "value": "x", + } + ], + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve(self, async_client: AsyncMobilerun) -> None: + credential = await async_client.credentials.packages.credentials.retrieve( + credential_name="credentialName", + package_name="packageName", + ) + assert_matches_type(CredentialRetrieveResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncMobilerun) -> None: + response = await async_client.credentials.packages.credentials.with_raw_response.retrieve( + credential_name="credentialName", + package_name="packageName", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + credential = await response.parse() + assert_matches_type(CredentialRetrieveResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncMobilerun) -> None: + async with async_client.credentials.packages.credentials.with_streaming_response.retrieve( + credential_name="credentialName", + package_name="packageName", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + credential = await response.parse() + assert_matches_type(CredentialRetrieveResponse, credential, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): + await async_client.credentials.packages.credentials.with_raw_response.retrieve( + credential_name="credentialName", + package_name="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): + await async_client.credentials.packages.credentials.with_raw_response.retrieve( + credential_name="", + package_name="packageName", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete(self, async_client: AsyncMobilerun) -> None: + credential = await async_client.credentials.packages.credentials.delete( + credential_name="credentialName", + package_name="packageName", + ) + assert_matches_type(CredentialDeleteResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncMobilerun) -> None: + response = await async_client.credentials.packages.credentials.with_raw_response.delete( + credential_name="credentialName", + package_name="packageName", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + credential = await response.parse() + assert_matches_type(CredentialDeleteResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncMobilerun) -> None: + async with async_client.credentials.packages.credentials.with_streaming_response.delete( + credential_name="credentialName", + package_name="packageName", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + credential = await response.parse() + assert_matches_type(CredentialDeleteResponse, credential, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_delete(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): + await async_client.credentials.packages.credentials.with_raw_response.delete( + credential_name="credentialName", + package_name="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `credential_name` but received ''"): + await async_client.credentials.packages.credentials.with_raw_response.delete( + credential_name="", + package_name="packageName", + ) diff --git a/tests/api_resources/credentials/test_packages.py b/tests/api_resources/credentials/test_packages.py new file mode 100644 index 0000000..fe14887 --- /dev/null +++ b/tests/api_resources/credentials/test_packages.py @@ -0,0 +1,176 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.credentials import PackageListResponse, PackageCreateResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestPackages: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create(self, client: Mobilerun) -> None: + package = client.credentials.packages.create( + package_name="packageName", + ) + assert_matches_type(PackageCreateResponse, package, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: Mobilerun) -> None: + response = client.credentials.packages.with_raw_response.create( + package_name="packageName", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + package = response.parse() + assert_matches_type(PackageCreateResponse, package, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: Mobilerun) -> None: + with client.credentials.packages.with_streaming_response.create( + package_name="packageName", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + package = response.parse() + assert_matches_type(PackageCreateResponse, package, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + package = client.credentials.packages.list( + "packageName", + ) + assert_matches_type(PackageListResponse, package, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.credentials.packages.with_raw_response.list( + "packageName", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + package = response.parse() + assert_matches_type(PackageListResponse, package, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.credentials.packages.with_streaming_response.list( + "packageName", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + package = response.parse() + assert_matches_type(PackageListResponse, package, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_list(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): + client.credentials.packages.with_raw_response.list( + "", + ) + + +class TestAsyncPackages: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create(self, async_client: AsyncMobilerun) -> None: + package = await async_client.credentials.packages.create( + package_name="packageName", + ) + assert_matches_type(PackageCreateResponse, package, path=["response"]) + + @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.credentials.packages.with_raw_response.create( + package_name="packageName", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + package = await response.parse() + assert_matches_type(PackageCreateResponse, package, path=["response"]) + + @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.credentials.packages.with_streaming_response.create( + package_name="packageName", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + package = await response.parse() + assert_matches_type(PackageCreateResponse, package, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + package = await async_client.credentials.packages.list( + "packageName", + ) + assert_matches_type(PackageListResponse, package, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.credentials.packages.with_raw_response.list( + "packageName", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + package = await response.parse() + assert_matches_type(PackageListResponse, package, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.credentials.packages.with_streaming_response.list( + "packageName", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + package = await response.parse() + assert_matches_type(PackageListResponse, package, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_list(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `package_name` but received ''"): + await async_client.credentials.packages.with_raw_response.list( + "", + ) diff --git a/tests/api_resources/test_apps.py b/tests/api_resources/test_apps.py new file mode 100644 index 0000000..7fd88df --- /dev/null +++ b/tests/api_resources/test_apps.py @@ -0,0 +1,712 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types import ( + AppListResponse, + AppDeleteResponse, + AppRetrieveResponse, + AppMarkFailedResponse, + AppListVersionsResponse, + AppConfirmUploadResponse, + AppCreateSignedUploadURLResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestApps: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve(self, client: Mobilerun) -> None: + app = client.apps.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(AppRetrieveResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve(self, client: Mobilerun) -> None: + response = client.apps.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = response.parse() + assert_matches_type(AppRetrieveResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve(self, client: Mobilerun) -> None: + with client.apps.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = response.parse() + assert_matches_type(AppRetrieveResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_retrieve(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.apps.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + app = client.apps.list() + assert_matches_type(AppListResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Mobilerun) -> None: + app = client.apps.list( + order="asc", + page=1, + page_size=1, + platform="all", + query="query", + sort_by="createdAt", + status="all", + ) + assert_matches_type(AppListResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.apps.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = response.parse() + assert_matches_type(AppListResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.apps.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = response.parse() + assert_matches_type(AppListResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete(self, client: Mobilerun) -> None: + app = client.apps.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(AppDeleteResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete(self, client: Mobilerun) -> None: + response = client.apps.with_raw_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = response.parse() + assert_matches_type(AppDeleteResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete(self, client: Mobilerun) -> None: + with client.apps.with_streaming_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = response.parse() + assert_matches_type(AppDeleteResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_delete(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.apps.with_raw_response.delete( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_confirm_upload(self, client: Mobilerun) -> None: + app = client.apps.confirm_upload( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(AppConfirmUploadResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_confirm_upload(self, client: Mobilerun) -> None: + response = client.apps.with_raw_response.confirm_upload( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = response.parse() + assert_matches_type(AppConfirmUploadResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_confirm_upload(self, client: Mobilerun) -> None: + with client.apps.with_streaming_response.confirm_upload( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = response.parse() + assert_matches_type(AppConfirmUploadResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_confirm_upload(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.apps.with_raw_response.confirm_upload( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_signed_upload_url(self, client: Mobilerun) -> None: + app = client.apps.create_signed_upload_url( + bundle_id="x", + display_name="x", + files=[ + { + "content_type": "x", + "file_name": "x", + } + ], + size_bytes=0, + version_code=0, + version_name="x", + ) + assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_signed_upload_url_with_all_params(self, client: Mobilerun) -> None: + app = client.apps.create_signed_upload_url( + bundle_id="x", + display_name="x", + files=[ + { + "content_type": "x", + "file_name": "x", + } + ], + size_bytes=0, + version_code=0, + version_name="x", + country="US", + description="description", + developer_name="developerName", + icon_url="iconURL", + platform="android", + target_sdk=0, + ) + assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create_signed_upload_url(self, client: Mobilerun) -> None: + response = client.apps.with_raw_response.create_signed_upload_url( + bundle_id="x", + display_name="x", + files=[ + { + "content_type": "x", + "file_name": "x", + } + ], + size_bytes=0, + version_code=0, + version_name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = response.parse() + assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create_signed_upload_url(self, client: Mobilerun) -> None: + with client.apps.with_streaming_response.create_signed_upload_url( + bundle_id="x", + display_name="x", + files=[ + { + "content_type": "x", + "file_name": "x", + } + ], + size_bytes=0, + version_code=0, + version_name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = response.parse() + assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_versions(self, client: Mobilerun) -> None: + app = client.apps.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(AppListVersionsResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list_versions(self, client: Mobilerun) -> None: + response = client.apps.with_raw_response.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = response.parse() + assert_matches_type(AppListVersionsResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list_versions(self, client: Mobilerun) -> None: + with client.apps.with_streaming_response.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = response.parse() + assert_matches_type(AppListVersionsResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_list_versions(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.apps.with_raw_response.list_versions( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_mark_failed(self, client: Mobilerun) -> None: + app = client.apps.mark_failed( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(AppMarkFailedResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_mark_failed(self, client: Mobilerun) -> None: + response = client.apps.with_raw_response.mark_failed( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = response.parse() + assert_matches_type(AppMarkFailedResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_mark_failed(self, client: Mobilerun) -> None: + with client.apps.with_streaming_response.mark_failed( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = response.parse() + assert_matches_type(AppMarkFailedResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_mark_failed(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.apps.with_raw_response.mark_failed( + "", + ) + + +class TestAsyncApps: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve(self, async_client: AsyncMobilerun) -> None: + app = await async_client.apps.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(AppRetrieveResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncMobilerun) -> None: + response = await async_client.apps.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = await response.parse() + assert_matches_type(AppRetrieveResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncMobilerun) -> None: + async with async_client.apps.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = await response.parse() + assert_matches_type(AppRetrieveResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.apps.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + app = await async_client.apps.list() + assert_matches_type(AppListResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: + app = await async_client.apps.list( + order="asc", + page=1, + page_size=1, + platform="all", + query="query", + sort_by="createdAt", + status="all", + ) + assert_matches_type(AppListResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.apps.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = await response.parse() + assert_matches_type(AppListResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.apps.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = await response.parse() + assert_matches_type(AppListResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete(self, async_client: AsyncMobilerun) -> None: + app = await async_client.apps.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(AppDeleteResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncMobilerun) -> None: + response = await async_client.apps.with_raw_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = await response.parse() + assert_matches_type(AppDeleteResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncMobilerun) -> None: + async with async_client.apps.with_streaming_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = await response.parse() + assert_matches_type(AppDeleteResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_delete(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.apps.with_raw_response.delete( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_confirm_upload(self, async_client: AsyncMobilerun) -> None: + app = await async_client.apps.confirm_upload( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(AppConfirmUploadResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_confirm_upload(self, async_client: AsyncMobilerun) -> None: + response = await async_client.apps.with_raw_response.confirm_upload( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = await response.parse() + assert_matches_type(AppConfirmUploadResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_confirm_upload(self, async_client: AsyncMobilerun) -> None: + async with async_client.apps.with_streaming_response.confirm_upload( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = await response.parse() + assert_matches_type(AppConfirmUploadResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_confirm_upload(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.apps.with_raw_response.confirm_upload( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create_signed_upload_url(self, async_client: AsyncMobilerun) -> None: + app = await async_client.apps.create_signed_upload_url( + bundle_id="x", + display_name="x", + files=[ + { + "content_type": "x", + "file_name": "x", + } + ], + size_bytes=0, + version_code=0, + version_name="x", + ) + assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create_signed_upload_url_with_all_params(self, async_client: AsyncMobilerun) -> None: + app = await async_client.apps.create_signed_upload_url( + bundle_id="x", + display_name="x", + files=[ + { + "content_type": "x", + "file_name": "x", + } + ], + size_bytes=0, + version_code=0, + version_name="x", + country="US", + description="description", + developer_name="developerName", + icon_url="iconURL", + platform="android", + target_sdk=0, + ) + assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_create_signed_upload_url(self, async_client: AsyncMobilerun) -> None: + response = await async_client.apps.with_raw_response.create_signed_upload_url( + bundle_id="x", + display_name="x", + files=[ + { + "content_type": "x", + "file_name": "x", + } + ], + size_bytes=0, + version_code=0, + version_name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = await response.parse() + assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_create_signed_upload_url(self, async_client: AsyncMobilerun) -> None: + async with async_client.apps.with_streaming_response.create_signed_upload_url( + bundle_id="x", + display_name="x", + files=[ + { + "content_type": "x", + "file_name": "x", + } + ], + size_bytes=0, + version_code=0, + version_name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = await response.parse() + assert_matches_type(AppCreateSignedUploadURLResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_versions(self, async_client: AsyncMobilerun) -> None: + app = await async_client.apps.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(AppListVersionsResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list_versions(self, async_client: AsyncMobilerun) -> None: + response = await async_client.apps.with_raw_response.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = await response.parse() + assert_matches_type(AppListVersionsResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list_versions(self, async_client: AsyncMobilerun) -> None: + async with async_client.apps.with_streaming_response.list_versions( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = await response.parse() + assert_matches_type(AppListVersionsResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_list_versions(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.apps.with_raw_response.list_versions( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_mark_failed(self, async_client: AsyncMobilerun) -> None: + app = await async_client.apps.mark_failed( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(AppMarkFailedResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_mark_failed(self, async_client: AsyncMobilerun) -> None: + response = await async_client.apps.with_raw_response.mark_failed( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + app = await response.parse() + assert_matches_type(AppMarkFailedResponse, app, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_mark_failed(self, async_client: AsyncMobilerun) -> None: + async with async_client.apps.with_streaming_response.mark_failed( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + app = await response.parse() + assert_matches_type(AppMarkFailedResponse, app, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_mark_failed(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.apps.with_raw_response.mark_failed( + "", + ) diff --git a/tests/api_resources/test_credentials.py b/tests/api_resources/test_credentials.py new file mode 100644 index 0000000..d125d22 --- /dev/null +++ b/tests/api_resources/test_credentials.py @@ -0,0 +1,98 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types import CredentialListResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestCredentials: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + credential = client.credentials.list() + assert_matches_type(CredentialListResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Mobilerun) -> None: + credential = client.credentials.list( + page=1, + page_size=1, + ) + assert_matches_type(CredentialListResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.credentials.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + credential = response.parse() + assert_matches_type(CredentialListResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.credentials.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + credential = response.parse() + assert_matches_type(CredentialListResponse, credential, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncCredentials: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + credential = await async_client.credentials.list() + assert_matches_type(CredentialListResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: + credential = await async_client.credentials.list( + page=1, + page_size=1, + ) + assert_matches_type(CredentialListResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.credentials.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + credential = await response.parse() + assert_matches_type(CredentialListResponse, credential, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.credentials.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + credential = await response.parse() + assert_matches_type(CredentialListResponse, credential, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_proxies.py b/tests/api_resources/test_proxies.py index 1a6fc78..b96cc4d 100644 --- a/tests/api_resources/test_proxies.py +++ b/tests/api_resources/test_proxies.py @@ -9,7 +9,14 @@ from tests.utils import assert_matches_type from mobilerun_sdk import Mobilerun, AsyncMobilerun -from mobilerun_sdk.types import ProxyLookupResponse +from mobilerun_sdk.types import ( + ProxyListResponse, + ProxyCreateResponse, + ProxyDeleteResponse, + ProxyLookupResponse, + ProxyUpdateResponse, + ProxyRetrieveResponse, +) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -17,6 +24,335 @@ class TestProxies: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_overload_1(self, client: Mobilerun) -> None: + proxy = client.proxies.create( + host="x", + name="xxx", + password="x", + port=1, + protocol="socks5", + user="x", + ) + assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create_overload_1(self, client: Mobilerun) -> None: + response = client.proxies.with_raw_response.create( + host="x", + name="xxx", + password="x", + port=1, + protocol="socks5", + user="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = response.parse() + assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create_overload_1(self, client: Mobilerun) -> None: + with client.proxies.with_streaming_response.create( + host="x", + name="xxx", + password="x", + port=1, + protocol="socks5", + user="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = response.parse() + assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_overload_2(self, client: Mobilerun) -> None: + proxy = client.proxies.create( + config="x", + name="xxx", + protocol="wireguard", + ) + assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create_overload_2(self, client: Mobilerun) -> None: + response = client.proxies.with_raw_response.create( + config="x", + name="xxx", + protocol="wireguard", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = response.parse() + assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create_overload_2(self, client: Mobilerun) -> None: + with client.proxies.with_streaming_response.create( + config="x", + name="xxx", + protocol="wireguard", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = response.parse() + assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve(self, client: Mobilerun) -> None: + proxy = client.proxies.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve(self, client: Mobilerun) -> None: + response = client.proxies.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = response.parse() + assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve(self, client: Mobilerun) -> None: + with client.proxies.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = response.parse() + assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_retrieve(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): + client.proxies.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update_overload_1(self, client: Mobilerun) -> None: + proxy = client.proxies.update( + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + host="x", + name="xxx", + password="x", + port=1, + protocol="socks5", + user="x", + ) + assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_update_overload_1(self, client: Mobilerun) -> None: + response = client.proxies.with_raw_response.update( + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + host="x", + name="xxx", + password="x", + port=1, + protocol="socks5", + user="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = response.parse() + assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_update_overload_1(self, client: Mobilerun) -> None: + with client.proxies.with_streaming_response.update( + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + host="x", + name="xxx", + password="x", + port=1, + protocol="socks5", + user="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = response.parse() + assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_update_overload_1(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): + client.proxies.with_raw_response.update( + proxy_id="", + host="x", + name="xxx", + password="x", + port=1, + protocol="socks5", + user="x", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update_overload_2(self, client: Mobilerun) -> None: + proxy = client.proxies.update( + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + config="x", + name="xxx", + protocol="wireguard", + ) + assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_update_overload_2(self, client: Mobilerun) -> None: + response = client.proxies.with_raw_response.update( + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + config="x", + name="xxx", + protocol="wireguard", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = response.parse() + assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_update_overload_2(self, client: Mobilerun) -> None: + with client.proxies.with_streaming_response.update( + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + config="x", + name="xxx", + protocol="wireguard", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = response.parse() + assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_update_overload_2(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): + client.proxies.with_raw_response.update( + proxy_id="", + config="x", + name="xxx", + protocol="wireguard", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + proxy = client.proxies.list() + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Mobilerun) -> None: + proxy = client.proxies.list( + protocol="socks5", + ) + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.proxies.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = response.parse() + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.proxies.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = response.parse() + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete(self, client: Mobilerun) -> None: + proxy = client.proxies.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ProxyDeleteResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete(self, client: Mobilerun) -> None: + response = client.proxies.with_raw_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = response.parse() + assert_matches_type(ProxyDeleteResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete(self, client: Mobilerun) -> None: + with client.proxies.with_streaming_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = response.parse() + assert_matches_type(ProxyDeleteResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_delete(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): + client.proxies.with_raw_response.delete( + "", + ) + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_lookup(self, client: Mobilerun) -> None: @@ -79,6 +415,335 @@ class TestAsyncProxies: "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create_overload_1(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.proxies.create( + host="x", + name="xxx", + password="x", + port=1, + protocol="socks5", + user="x", + ) + assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_create_overload_1(self, async_client: AsyncMobilerun) -> None: + response = await async_client.proxies.with_raw_response.create( + host="x", + name="xxx", + password="x", + port=1, + protocol="socks5", + user="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = await response.parse() + assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_create_overload_1(self, async_client: AsyncMobilerun) -> None: + async with async_client.proxies.with_streaming_response.create( + host="x", + name="xxx", + password="x", + port=1, + protocol="socks5", + user="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = await response.parse() + assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create_overload_2(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.proxies.create( + config="x", + name="xxx", + protocol="wireguard", + ) + assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_create_overload_2(self, async_client: AsyncMobilerun) -> None: + response = await async_client.proxies.with_raw_response.create( + config="x", + name="xxx", + protocol="wireguard", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = await response.parse() + assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_create_overload_2(self, async_client: AsyncMobilerun) -> None: + async with async_client.proxies.with_streaming_response.create( + config="x", + name="xxx", + protocol="wireguard", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = await response.parse() + assert_matches_type(ProxyCreateResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.proxies.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncMobilerun) -> None: + response = await async_client.proxies.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = await response.parse() + assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncMobilerun) -> None: + async with async_client.proxies.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = await response.parse() + assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): + await async_client.proxies.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_overload_1(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.proxies.update( + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + host="x", + name="xxx", + password="x", + port=1, + protocol="socks5", + user="x", + ) + assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_update_overload_1(self, async_client: AsyncMobilerun) -> None: + response = await async_client.proxies.with_raw_response.update( + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + host="x", + name="xxx", + password="x", + port=1, + protocol="socks5", + user="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = await response.parse() + assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_update_overload_1(self, async_client: AsyncMobilerun) -> None: + async with async_client.proxies.with_streaming_response.update( + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + host="x", + name="xxx", + password="x", + port=1, + protocol="socks5", + user="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = await response.parse() + assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_update_overload_1(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): + await async_client.proxies.with_raw_response.update( + proxy_id="", + host="x", + name="xxx", + password="x", + port=1, + protocol="socks5", + user="x", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_overload_2(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.proxies.update( + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + config="x", + name="xxx", + protocol="wireguard", + ) + assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_update_overload_2(self, async_client: AsyncMobilerun) -> None: + response = await async_client.proxies.with_raw_response.update( + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + config="x", + name="xxx", + protocol="wireguard", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = await response.parse() + assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_update_overload_2(self, async_client: AsyncMobilerun) -> None: + async with async_client.proxies.with_streaming_response.update( + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + config="x", + name="xxx", + protocol="wireguard", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = await response.parse() + assert_matches_type(ProxyUpdateResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_update_overload_2(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): + await async_client.proxies.with_raw_response.update( + proxy_id="", + config="x", + name="xxx", + protocol="wireguard", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.proxies.list() + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.proxies.list( + protocol="socks5", + ) + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.proxies.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = await response.parse() + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.proxies.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = await response.parse() + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.proxies.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ProxyDeleteResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncMobilerun) -> None: + response = await async_client.proxies.with_raw_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = await response.parse() + assert_matches_type(ProxyDeleteResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncMobilerun) -> None: + async with async_client.proxies.with_streaming_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = await response.parse() + assert_matches_type(ProxyDeleteResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_delete(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `proxy_id` but received ''"): + await async_client.proxies.with_raw_response.delete( + "", + ) + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_lookup(self, async_client: AsyncMobilerun) -> None: From 6413e60d73b86fab265de2f2fba94dba21e89d4d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 30 May 2026 13:00:32 +0000 Subject: [PATCH 06/21] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 6616e99..8930df3 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 107 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-506128e71e04bea5ce31fd879d4c0ac5a313fc39cf9f39acd1cbb3cee95f74ab.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-e96db2fc0746ff1c11c2e36e7c3bc2e3765b194d9901897d24a376528208e816.yml openapi_spec_hash: b45c764022d18add79f0516691749fa8 -config_hash: 86398ea1292189c25296aefb64d3137d +config_hash: e6de87b533e3e7e6470b59c22d61752a From 13645e2290241b8930ad56231b0aac9ffb0d8b9d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 5 Jun 2026 12:14:22 +0000 Subject: [PATCH 07/21] feat(api): api update --- .stats.yml | 4 +- .../resources/devices/devices.py | 6 +- .../types/devices/state_ui_response.py | 104 +++++++++++++++++- 3 files changed, 103 insertions(+), 11 deletions(-) diff --git a/.stats.yml b/.stats.yml index 8930df3..a4f99cd 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 107 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-e96db2fc0746ff1c11c2e36e7c3bc2e3765b194d9901897d24a376528208e816.yml -openapi_spec_hash: b45c764022d18add79f0516691749fa8 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-fe8a59659c2b27adecb125b1d2c4689afd7a1286789e1e9719416f9eb13d8d4a.yml +openapi_spec_hash: 16e6844fb9a11ac7c310db933f7d5856 config_hash: e6de87b533e3e7e6470b59c22d61752a diff --git a/src/mobilerun_sdk/resources/devices/devices.py b/src/mobilerun_sdk/resources/devices/devices.py index 31c41ed..cc71aa2 100644 --- a/src/mobilerun_sdk/resources/devices/devices.py +++ b/src/mobilerun_sdk/resources/devices/devices.py @@ -495,8 +495,7 @@ def reset( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Reset a device to a fresh state (VMOS one-click new device; non-VMOS providers - return 404) + Reset a device to a fresh state Args: extra_headers: Send extra headers @@ -990,8 +989,7 @@ async def reset( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Reset a device to a fresh state (VMOS one-click new device; non-VMOS providers - return 404) + Reset a device to a fresh state Args: extra_headers: Send extra headers diff --git a/src/mobilerun_sdk/types/devices/state_ui_response.py b/src/mobilerun_sdk/types/devices/state_ui_response.py index bdddd0c..80cbe44 100644 --- a/src/mobilerun_sdk/types/devices/state_ui_response.py +++ b/src/mobilerun_sdk/types/devices/state_ui_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Optional from pydantic import Field as FieldInfo @@ -9,14 +9,64 @@ __all__ = [ "StateUiResponse", + "A11yTree", + "A11yTreeBoundsInScreen", "DeviceContext", "DeviceContextDisplayMetrics", "DeviceContextFilteringParams", + "ImeTree", + "ImeTreeBoundsInScreen", "PhoneState", "PhoneStateFocusedElement", ] +class A11yTreeBoundsInScreen(BaseModel): + bottom: int + + left: int + + right: int + + top: int + + +class A11yTree(BaseModel): + bounds_in_screen: A11yTreeBoundsInScreen = FieldInfo(alias="boundsInScreen") + + children: Optional[List[object]] = None + + class_name: str = FieldInfo(alias="className") + + content_description: str = FieldInfo(alias="contentDescription") + + is_checkable: bool = FieldInfo(alias="isCheckable") + + is_checked: bool = FieldInfo(alias="isChecked") + + is_clickable: bool = FieldInfo(alias="isClickable") + + is_enabled: bool = FieldInfo(alias="isEnabled") + + is_focusable: bool = FieldInfo(alias="isFocusable") + + is_focused: bool = FieldInfo(alias="isFocused") + + is_long_clickable: bool = FieldInfo(alias="isLongClickable") + + is_password: bool = FieldInfo(alias="isPassword") + + is_scrollable: bool = FieldInfo(alias="isScrollable") + + is_selected: bool = FieldInfo(alias="isSelected") + + package_name: str = FieldInfo(alias="packageName") + + resource_id: str = FieldInfo(alias="resourceId") + + text: str + + class DeviceContextDisplayMetrics(BaseModel): density: float @@ -42,7 +92,51 @@ class DeviceContext(BaseModel): screen_bounds: Rect - screen_size: Rect = FieldInfo(alias="screenSize") + +class ImeTreeBoundsInScreen(BaseModel): + bottom: int + + left: int + + right: int + + top: int + + +class ImeTree(BaseModel): + bounds_in_screen: ImeTreeBoundsInScreen = FieldInfo(alias="boundsInScreen") + + children: Optional[List[object]] = None + + class_name: str = FieldInfo(alias="className") + + content_description: str = FieldInfo(alias="contentDescription") + + is_checkable: bool = FieldInfo(alias="isCheckable") + + is_checked: bool = FieldInfo(alias="isChecked") + + is_clickable: bool = FieldInfo(alias="isClickable") + + is_enabled: bool = FieldInfo(alias="isEnabled") + + is_focusable: bool = FieldInfo(alias="isFocusable") + + is_focused: bool = FieldInfo(alias="isFocused") + + is_long_clickable: bool = FieldInfo(alias="isLongClickable") + + is_password: bool = FieldInfo(alias="isPassword") + + is_scrollable: bool = FieldInfo(alias="isScrollable") + + is_selected: bool = FieldInfo(alias="isSelected") + + package_name: str = FieldInfo(alias="packageName") + + resource_id: str = FieldInfo(alias="resourceId") + + text: str class PhoneStateFocusedElement(BaseModel): @@ -68,13 +162,13 @@ class PhoneState(BaseModel): class StateUiResponse(BaseModel): - a11y_tree: object + a11y_tree: A11yTree device_context: DeviceContext + ime_tree: ImeTree + phone_state: PhoneState schema_: Optional[str] = FieldInfo(alias="$schema", default=None) """A URL to the JSON Schema for this object.""" - - ime_tree: Optional[object] = None From dff27332208ec1abb8f2a420dd11907782c10f79 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 5 Jun 2026 13:14:19 +0000 Subject: [PATCH 08/21] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index a4f99cd..686c5d7 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 107 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-fe8a59659c2b27adecb125b1d2c4689afd7a1286789e1e9719416f9eb13d8d4a.yml -openapi_spec_hash: 16e6844fb9a11ac7c310db933f7d5856 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-120613e5f27ac5df4fb4cac650afb561d8ec722fa7ab597631a24e2fdc9ded98.yml +openapi_spec_hash: f4c5ba7f704b9a2c5257a629118511af config_hash: e6de87b533e3e7e6470b59c22d61752a From b01d4969bea4f20289720122c261a9897af656f2 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 09:58:17 +0000 Subject: [PATCH 09/21] feat(api): enable workflows --- .stats.yml | 6 +- api.md | 208 +++++ src/mobilerun_sdk/_client.py | 51 +- src/mobilerun_sdk/resources/__init__.py | 14 + .../resources/workflows/__init__.py | 131 +++ .../resources/workflows/action_catalog.py | 268 +++++++ .../resources/workflows/actions/__init__.py | 33 + .../resources/workflows/actions/actions.py | 592 ++++++++++++++ .../resources/workflows/actions/services.py | 215 +++++ .../resources/workflows/events/__init__.py | 33 + .../resources/workflows/events/catalog.py | 267 +++++++ .../resources/workflows/events/events.py | 316 ++++++++ .../resources/workflows/executions.py | 402 ++++++++++ .../resources/workflows/flows/__init__.py | 33 + .../resources/workflows/flows/actions.py | 458 +++++++++++ .../resources/workflows/flows/flows.py | 703 ++++++++++++++++ .../resources/workflows/secrets.py | 311 ++++++++ .../resources/workflows/timezones.py | 135 ++++ .../resources/workflows/triggers.py | 753 ++++++++++++++++++ .../resources/workflows/workflows.py | 326 ++++++++ src/mobilerun_sdk/types/__init__.py | 1 + src/mobilerun_sdk/types/flow.py | 34 + src/mobilerun_sdk/types/workflows/__init__.py | 55 ++ src/mobilerun_sdk/types/workflows/action.py | 36 + .../types/workflows/action_catalog_entry.py | 30 + .../workflows/action_catalog_list_params.py | 17 + .../workflows/action_catalog_list_response.py | 15 + .../action_catalog_retrieve_response.py | 10 + .../types/workflows/action_create_params.py | 20 + .../types/workflows/action_create_response.py | 10 + .../types/workflows/action_delete_response.py | 9 + .../types/workflows/action_list_params.py | 23 + .../types/workflows/action_list_response.py | 15 + .../workflows/action_retrieve_response.py | 10 + .../types/workflows/action_update_params.py | 16 + .../types/workflows/action_update_response.py | 10 + .../types/workflows/actions/__init__.py | 6 + .../actions/service_list_methods_response.py | 38 + .../actions/service_list_response.py | 11 + .../types/workflows/event_dry_run_params.py | 18 + .../types/workflows/event_dry_run_response.py | 105 +++ .../types/workflows/event_ingest_params.py | 18 + .../types/workflows/event_ingest_response.py | 11 + .../types/workflows/events/__init__.py | 8 + .../workflows/events/catalog_list_params.py | 17 + .../workflows/events/catalog_list_response.py | 32 + .../events/catalog_register_params.py | 26 + .../events/catalog_register_response.py | 9 + .../workflows/execution_get_metrics_params.py | 20 + .../execution_get_metrics_response.py | 33 + .../types/workflows/execution_list_params.py | 32 + .../workflows/execution_list_response.py | 15 + .../workflows/execution_retrieve_response.py | 10 + .../workflows/flow_action_overrides_param.py | 12 + .../flow_child_action_input_param.py | 25 + .../types/workflows/flow_clone_params.py | 11 + .../types/workflows/flow_clone_response.py | 10 + .../types/workflows/flow_create_params.py | 44 + .../types/workflows/flow_create_response.py | 10 + .../types/workflows/flow_delete_response.py | 9 + .../types/workflows/flow_execution.py | 34 + .../types/workflows/flow_list_params.py | 26 + .../types/workflows/flow_list_response.py | 15 + .../types/workflows/flow_retrieve_response.py | 10 + .../types/workflows/flow_update_params.py | 24 + .../types/workflows/flow_update_response.py | 10 + .../types/workflows/flows/__init__.py | 11 + .../workflows/flows/action_add_params.py | 30 + .../workflows/flows/action_add_response.py | 10 + .../workflows/flows/action_list_response.py | 12 + .../workflows/flows/action_remove_response.py | 9 + .../workflows/flows/action_replace_params.py | 32 + .../flows/action_replace_response.py | 12 + .../types/workflows/flows/flow_action.py | 35 + .../types/workflows/secret_create_params.py | 15 + .../types/workflows/secret_create_response.py | 10 + .../types/workflows/secret_delete_response.py | 9 + .../types/workflows/secret_list_response.py | 12 + .../types/workflows/timezone_list_response.py | 11 + .../types/workflows/trigger_create_params.py | 48 ++ .../workflows/trigger_create_response.py | 55 ++ .../workflows/trigger_delete_response.py | 9 + .../types/workflows/trigger_fire_params.py | 26 + .../types/workflows/trigger_fire_response.py | 22 + .../types/workflows/trigger_list_params.py | 25 + .../types/workflows/trigger_list_response.py | 58 ++ .../workflows/trigger_retrieve_response.py | 55 ++ .../types/workflows/trigger_update_params.py | 48 ++ .../workflows/trigger_update_response.py | 55 ++ .../types/workflows/user_secret.py | 21 + tests/api_resources/workflows/__init__.py | 1 + .../workflows/actions/__init__.py | 1 + .../workflows/actions/test_services.py | 164 ++++ .../workflows/events/__init__.py | 1 + .../workflows/events/test_catalog.py | 201 +++++ .../api_resources/workflows/flows/__init__.py | 1 + .../workflows/flows/test_actions.py | 499 ++++++++++++ .../workflows/test_action_catalog.py | 187 +++++ tests/api_resources/workflows/test_actions.py | 482 +++++++++++ tests/api_resources/workflows/test_events.py | 203 +++++ .../workflows/test_executions.py | 280 +++++++ tests/api_resources/workflows/test_flows.py | 673 ++++++++++++++++ tests/api_resources/workflows/test_secrets.py | 262 ++++++ .../api_resources/workflows/test_timezones.py | 80 ++ .../api_resources/workflows/test_triggers.py | 647 +++++++++++++++ 105 files changed, 10523 insertions(+), 4 deletions(-) create mode 100644 src/mobilerun_sdk/resources/workflows/__init__.py create mode 100644 src/mobilerun_sdk/resources/workflows/action_catalog.py create mode 100644 src/mobilerun_sdk/resources/workflows/actions/__init__.py create mode 100644 src/mobilerun_sdk/resources/workflows/actions/actions.py create mode 100644 src/mobilerun_sdk/resources/workflows/actions/services.py create mode 100644 src/mobilerun_sdk/resources/workflows/events/__init__.py create mode 100644 src/mobilerun_sdk/resources/workflows/events/catalog.py create mode 100644 src/mobilerun_sdk/resources/workflows/events/events.py create mode 100644 src/mobilerun_sdk/resources/workflows/executions.py create mode 100644 src/mobilerun_sdk/resources/workflows/flows/__init__.py create mode 100644 src/mobilerun_sdk/resources/workflows/flows/actions.py create mode 100644 src/mobilerun_sdk/resources/workflows/flows/flows.py create mode 100644 src/mobilerun_sdk/resources/workflows/secrets.py create mode 100644 src/mobilerun_sdk/resources/workflows/timezones.py create mode 100644 src/mobilerun_sdk/resources/workflows/triggers.py create mode 100644 src/mobilerun_sdk/resources/workflows/workflows.py create mode 100644 src/mobilerun_sdk/types/flow.py create mode 100644 src/mobilerun_sdk/types/workflows/__init__.py create mode 100644 src/mobilerun_sdk/types/workflows/action.py create mode 100644 src/mobilerun_sdk/types/workflows/action_catalog_entry.py create mode 100644 src/mobilerun_sdk/types/workflows/action_catalog_list_params.py create mode 100644 src/mobilerun_sdk/types/workflows/action_catalog_list_response.py create mode 100644 src/mobilerun_sdk/types/workflows/action_catalog_retrieve_response.py create mode 100644 src/mobilerun_sdk/types/workflows/action_create_params.py create mode 100644 src/mobilerun_sdk/types/workflows/action_create_response.py create mode 100644 src/mobilerun_sdk/types/workflows/action_delete_response.py create mode 100644 src/mobilerun_sdk/types/workflows/action_list_params.py create mode 100644 src/mobilerun_sdk/types/workflows/action_list_response.py create mode 100644 src/mobilerun_sdk/types/workflows/action_retrieve_response.py create mode 100644 src/mobilerun_sdk/types/workflows/action_update_params.py create mode 100644 src/mobilerun_sdk/types/workflows/action_update_response.py create mode 100644 src/mobilerun_sdk/types/workflows/actions/__init__.py create mode 100644 src/mobilerun_sdk/types/workflows/actions/service_list_methods_response.py create mode 100644 src/mobilerun_sdk/types/workflows/actions/service_list_response.py create mode 100644 src/mobilerun_sdk/types/workflows/event_dry_run_params.py create mode 100644 src/mobilerun_sdk/types/workflows/event_dry_run_response.py create mode 100644 src/mobilerun_sdk/types/workflows/event_ingest_params.py create mode 100644 src/mobilerun_sdk/types/workflows/event_ingest_response.py create mode 100644 src/mobilerun_sdk/types/workflows/events/__init__.py create mode 100644 src/mobilerun_sdk/types/workflows/events/catalog_list_params.py create mode 100644 src/mobilerun_sdk/types/workflows/events/catalog_list_response.py create mode 100644 src/mobilerun_sdk/types/workflows/events/catalog_register_params.py create mode 100644 src/mobilerun_sdk/types/workflows/events/catalog_register_response.py create mode 100644 src/mobilerun_sdk/types/workflows/execution_get_metrics_params.py create mode 100644 src/mobilerun_sdk/types/workflows/execution_get_metrics_response.py create mode 100644 src/mobilerun_sdk/types/workflows/execution_list_params.py create mode 100644 src/mobilerun_sdk/types/workflows/execution_list_response.py create mode 100644 src/mobilerun_sdk/types/workflows/execution_retrieve_response.py create mode 100644 src/mobilerun_sdk/types/workflows/flow_action_overrides_param.py create mode 100644 src/mobilerun_sdk/types/workflows/flow_child_action_input_param.py create mode 100644 src/mobilerun_sdk/types/workflows/flow_clone_params.py create mode 100644 src/mobilerun_sdk/types/workflows/flow_clone_response.py create mode 100644 src/mobilerun_sdk/types/workflows/flow_create_params.py create mode 100644 src/mobilerun_sdk/types/workflows/flow_create_response.py create mode 100644 src/mobilerun_sdk/types/workflows/flow_delete_response.py create mode 100644 src/mobilerun_sdk/types/workflows/flow_execution.py create mode 100644 src/mobilerun_sdk/types/workflows/flow_list_params.py create mode 100644 src/mobilerun_sdk/types/workflows/flow_list_response.py create mode 100644 src/mobilerun_sdk/types/workflows/flow_retrieve_response.py create mode 100644 src/mobilerun_sdk/types/workflows/flow_update_params.py create mode 100644 src/mobilerun_sdk/types/workflows/flow_update_response.py create mode 100644 src/mobilerun_sdk/types/workflows/flows/__init__.py create mode 100644 src/mobilerun_sdk/types/workflows/flows/action_add_params.py create mode 100644 src/mobilerun_sdk/types/workflows/flows/action_add_response.py create mode 100644 src/mobilerun_sdk/types/workflows/flows/action_list_response.py create mode 100644 src/mobilerun_sdk/types/workflows/flows/action_remove_response.py create mode 100644 src/mobilerun_sdk/types/workflows/flows/action_replace_params.py create mode 100644 src/mobilerun_sdk/types/workflows/flows/action_replace_response.py create mode 100644 src/mobilerun_sdk/types/workflows/flows/flow_action.py create mode 100644 src/mobilerun_sdk/types/workflows/secret_create_params.py create mode 100644 src/mobilerun_sdk/types/workflows/secret_create_response.py create mode 100644 src/mobilerun_sdk/types/workflows/secret_delete_response.py create mode 100644 src/mobilerun_sdk/types/workflows/secret_list_response.py create mode 100644 src/mobilerun_sdk/types/workflows/timezone_list_response.py create mode 100644 src/mobilerun_sdk/types/workflows/trigger_create_params.py create mode 100644 src/mobilerun_sdk/types/workflows/trigger_create_response.py create mode 100644 src/mobilerun_sdk/types/workflows/trigger_delete_response.py create mode 100644 src/mobilerun_sdk/types/workflows/trigger_fire_params.py create mode 100644 src/mobilerun_sdk/types/workflows/trigger_fire_response.py create mode 100644 src/mobilerun_sdk/types/workflows/trigger_list_params.py create mode 100644 src/mobilerun_sdk/types/workflows/trigger_list_response.py create mode 100644 src/mobilerun_sdk/types/workflows/trigger_retrieve_response.py create mode 100644 src/mobilerun_sdk/types/workflows/trigger_update_params.py create mode 100644 src/mobilerun_sdk/types/workflows/trigger_update_response.py create mode 100644 src/mobilerun_sdk/types/workflows/user_secret.py create mode 100644 tests/api_resources/workflows/__init__.py create mode 100644 tests/api_resources/workflows/actions/__init__.py create mode 100644 tests/api_resources/workflows/actions/test_services.py create mode 100644 tests/api_resources/workflows/events/__init__.py create mode 100644 tests/api_resources/workflows/events/test_catalog.py create mode 100644 tests/api_resources/workflows/flows/__init__.py create mode 100644 tests/api_resources/workflows/flows/test_actions.py create mode 100644 tests/api_resources/workflows/test_action_catalog.py create mode 100644 tests/api_resources/workflows/test_actions.py create mode 100644 tests/api_resources/workflows/test_events.py create mode 100644 tests/api_resources/workflows/test_executions.py create mode 100644 tests/api_resources/workflows/test_flows.py create mode 100644 tests/api_resources/workflows/test_secrets.py create mode 100644 tests/api_resources/workflows/test_timezones.py create mode 100644 tests/api_resources/workflows/test_triggers.py diff --git a/.stats.yml b/.stats.yml index 686c5d7..68ccaa5 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 107 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-120613e5f27ac5df4fb4cac650afb561d8ec722fa7ab597631a24e2fdc9ded98.yml +configured_endpoints: 143 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-69e013739016ee44f75587844c51a010330e3a22c0e7e2cd0a43c3194753ce33.yml openapi_spec_hash: f4c5ba7f704b9a2c5257a629118511af -config_hash: e6de87b533e3e7e6470b59c22d61752a +config_hash: ca9f428d668195546c3a4e1f5faf1abc diff --git a/api.md b/api.md index 4b2c442..f4c61d4 100644 --- a/api.md +++ b/api.md @@ -484,3 +484,211 @@ Methods: - client.tasks.ui_states.retrieve(index, \*, task_id) -> MediaResponse - client.tasks.ui_states.list(task_id) -> UiStateListResponse + +# Workflows + +Types: + +```python +from mobilerun_sdk.types import Flow +``` + +## Triggers + +Types: + +```python +from mobilerun_sdk.types.workflows import ( + TriggerCreateResponse, + TriggerRetrieveResponse, + TriggerUpdateResponse, + TriggerListResponse, + TriggerDeleteResponse, + TriggerFireResponse, +) +``` + +Methods: + +- client.workflows.triggers.create(\*\*params) -> TriggerCreateResponse +- client.workflows.triggers.retrieve(trigger_id) -> TriggerRetrieveResponse +- client.workflows.triggers.update(trigger_id, \*\*params) -> TriggerUpdateResponse +- client.workflows.triggers.list(\*\*params) -> TriggerListResponse +- client.workflows.triggers.delete(trigger_id) -> TriggerDeleteResponse +- client.workflows.triggers.fire(trigger_id, \*\*params) -> TriggerFireResponse + +## ActionCatalog + +Types: + +```python +from mobilerun_sdk.types.workflows import ( + ActionCatalogEntry, + ActionCatalogRetrieveResponse, + ActionCatalogListResponse, +) +``` + +Methods: + +- client.workflows.action_catalog.retrieve(catalog_entry_id) -> ActionCatalogRetrieveResponse +- client.workflows.action_catalog.list(\*\*params) -> ActionCatalogListResponse + +## Actions + +Types: + +```python +from mobilerun_sdk.types.workflows import ( + Action, + ActionCreateResponse, + ActionRetrieveResponse, + ActionUpdateResponse, + ActionListResponse, + ActionDeleteResponse, +) +``` + +Methods: + +- client.workflows.actions.create(\*\*params) -> ActionCreateResponse +- client.workflows.actions.retrieve(action_id) -> ActionRetrieveResponse +- client.workflows.actions.update(action_id, \*\*params) -> ActionUpdateResponse +- client.workflows.actions.list(\*\*params) -> ActionListResponse +- client.workflows.actions.delete(action_id) -> ActionDeleteResponse + +### Services + +Types: + +```python +from mobilerun_sdk.types.workflows.actions import ServiceListResponse, ServiceListMethodsResponse +``` + +Methods: + +- client.workflows.actions.services.list() -> ServiceListResponse +- client.workflows.actions.services.list_methods(service) -> ServiceListMethodsResponse + +## Flows + +Types: + +```python +from mobilerun_sdk.types.workflows import ( + FlowActionOverrides, + FlowChildActionInput, + FlowCreateResponse, + FlowRetrieveResponse, + FlowUpdateResponse, + FlowListResponse, + FlowDeleteResponse, + FlowCloneResponse, +) +``` + +Methods: + +- client.workflows.flows.create(\*\*params) -> FlowCreateResponse +- client.workflows.flows.retrieve(flow_id) -> FlowRetrieveResponse +- client.workflows.flows.update(flow_id, \*\*params) -> FlowUpdateResponse +- client.workflows.flows.list(\*\*params) -> FlowListResponse +- client.workflows.flows.delete(flow_id) -> FlowDeleteResponse +- client.workflows.flows.clone(flow_id, \*\*params) -> FlowCloneResponse + +### Actions + +Types: + +```python +from mobilerun_sdk.types.workflows.flows import ( + FlowAction, + ActionListResponse, + ActionAddResponse, + ActionRemoveResponse, + ActionReplaceResponse, +) +``` + +Methods: + +- client.workflows.flows.actions.list(flow_id) -> ActionListResponse +- client.workflows.flows.actions.add(flow_id, \*\*params) -> ActionAddResponse +- client.workflows.flows.actions.remove(flow_action_id, \*, flow_id) -> ActionRemoveResponse +- client.workflows.flows.actions.replace(flow_id, \*\*params) -> ActionReplaceResponse + +## Events + +Types: + +```python +from mobilerun_sdk.types.workflows import EventDryRunResponse, EventIngestResponse +``` + +Methods: + +- client.workflows.events.dry_run(\*\*params) -> EventDryRunResponse +- client.workflows.events.ingest(\*\*params) -> EventIngestResponse + +### Catalog + +Types: + +```python +from mobilerun_sdk.types.workflows.events import CatalogListResponse, CatalogRegisterResponse +``` + +Methods: + +- client.workflows.events.catalog.list(\*\*params) -> CatalogListResponse +- client.workflows.events.catalog.register(\*\*params) -> CatalogRegisterResponse + +## Executions + +Types: + +```python +from mobilerun_sdk.types.workflows import ( + FlowExecution, + ExecutionRetrieveResponse, + ExecutionListResponse, + ExecutionGetMetricsResponse, +) +``` + +Methods: + +- client.workflows.executions.retrieve(execution_id) -> ExecutionRetrieveResponse +- client.workflows.executions.list(\*\*params) -> ExecutionListResponse +- client.workflows.executions.get_metrics(\*\*params) -> ExecutionGetMetricsResponse + +## Timezones + +Types: + +```python +from mobilerun_sdk.types.workflows import TimezoneListResponse +``` + +Methods: + +- client.workflows.timezones.list() -> TimezoneListResponse + +## Secrets + +Types: + +```python +from mobilerun_sdk.types.workflows import ( + UserSecret, + SecretCreateResponse, + SecretListResponse, + SecretDeleteResponse, +) +``` + +Methods: + +- client.workflows.secrets.create(\*\*params) -> SecretCreateResponse +- client.workflows.secrets.list() -> SecretListResponse +- client.workflows.secrets.delete(secret_id) -> SecretDeleteResponse diff --git a/src/mobilerun_sdk/_client.py b/src/mobilerun_sdk/_client.py index 28b10f0..b4f4f87 100644 --- a/src/mobilerun_sdk/_client.py +++ b/src/mobilerun_sdk/_client.py @@ -36,7 +36,19 @@ ) if TYPE_CHECKING: - from .resources import apps, hooks, tasks, agents, models, devices, proxies, carriers, profiles, credentials + from .resources import ( + apps, + hooks, + tasks, + agents, + models, + devices, + proxies, + carriers, + profiles, + workflows, + credentials, + ) from .resources.apps import AppsResource, AsyncAppsResource from .resources.hooks import HooksResource, AsyncHooksResource from .resources.agents import AgentsResource, AsyncAgentsResource @@ -46,6 +58,7 @@ from .resources.profiles import ProfilesResource, AsyncProfilesResource from .resources.tasks.tasks import TasksResource, AsyncTasksResource from .resources.devices.devices import DevicesResource, AsyncDevicesResource + from .resources.workflows.workflows import WorkflowsResource, AsyncWorkflowsResource from .resources.credentials.credentials import CredentialsResource, AsyncCredentialsResource __all__ = [ @@ -187,6 +200,12 @@ def tasks(self) -> TasksResource: return TasksResource(self) + @cached_property + def workflows(self) -> WorkflowsResource: + from .resources.workflows import WorkflowsResource + + return WorkflowsResource(self) + @cached_property def with_raw_response(self) -> MobilerunWithRawResponse: return MobilerunWithRawResponse(self) @@ -438,6 +457,12 @@ def tasks(self) -> AsyncTasksResource: return AsyncTasksResource(self) + @cached_property + def workflows(self) -> AsyncWorkflowsResource: + from .resources.workflows import AsyncWorkflowsResource + + return AsyncWorkflowsResource(self) + @cached_property def with_raw_response(self) -> AsyncMobilerunWithRawResponse: return AsyncMobilerunWithRawResponse(self) @@ -635,6 +660,12 @@ def tasks(self) -> tasks.TasksResourceWithRawResponse: return TasksResourceWithRawResponse(self._client.tasks) + @cached_property + def workflows(self) -> workflows.WorkflowsResourceWithRawResponse: + from .resources.workflows import WorkflowsResourceWithRawResponse + + return WorkflowsResourceWithRawResponse(self._client.workflows) + class AsyncMobilerunWithRawResponse: _client: AsyncMobilerun @@ -709,6 +740,12 @@ def tasks(self) -> tasks.AsyncTasksResourceWithRawResponse: return AsyncTasksResourceWithRawResponse(self._client.tasks) + @cached_property + def workflows(self) -> workflows.AsyncWorkflowsResourceWithRawResponse: + from .resources.workflows import AsyncWorkflowsResourceWithRawResponse + + return AsyncWorkflowsResourceWithRawResponse(self._client.workflows) + class MobilerunWithStreamedResponse: _client: Mobilerun @@ -783,6 +820,12 @@ def tasks(self) -> tasks.TasksResourceWithStreamingResponse: return TasksResourceWithStreamingResponse(self._client.tasks) + @cached_property + def workflows(self) -> workflows.WorkflowsResourceWithStreamingResponse: + from .resources.workflows import WorkflowsResourceWithStreamingResponse + + return WorkflowsResourceWithStreamingResponse(self._client.workflows) + class AsyncMobilerunWithStreamedResponse: _client: AsyncMobilerun @@ -857,6 +900,12 @@ def tasks(self) -> tasks.AsyncTasksResourceWithStreamingResponse: return AsyncTasksResourceWithStreamingResponse(self._client.tasks) + @cached_property + def workflows(self) -> workflows.AsyncWorkflowsResourceWithStreamingResponse: + from .resources.workflows import AsyncWorkflowsResourceWithStreamingResponse + + return AsyncWorkflowsResourceWithStreamingResponse(self._client.workflows) + Client = Mobilerun diff --git a/src/mobilerun_sdk/resources/__init__.py b/src/mobilerun_sdk/resources/__init__.py index 21f473c..39e06ee 100644 --- a/src/mobilerun_sdk/resources/__init__.py +++ b/src/mobilerun_sdk/resources/__init__.py @@ -72,6 +72,14 @@ ProfilesResourceWithStreamingResponse, AsyncProfilesResourceWithStreamingResponse, ) +from .workflows import ( + WorkflowsResource, + AsyncWorkflowsResource, + WorkflowsResourceWithRawResponse, + AsyncWorkflowsResourceWithRawResponse, + WorkflowsResourceWithStreamingResponse, + AsyncWorkflowsResourceWithStreamingResponse, +) from .credentials import ( CredentialsResource, AsyncCredentialsResource, @@ -142,4 +150,10 @@ "AsyncTasksResourceWithRawResponse", "TasksResourceWithStreamingResponse", "AsyncTasksResourceWithStreamingResponse", + "WorkflowsResource", + "AsyncWorkflowsResource", + "WorkflowsResourceWithRawResponse", + "AsyncWorkflowsResourceWithRawResponse", + "WorkflowsResourceWithStreamingResponse", + "AsyncWorkflowsResourceWithStreamingResponse", ] diff --git a/src/mobilerun_sdk/resources/workflows/__init__.py b/src/mobilerun_sdk/resources/workflows/__init__.py new file mode 100644 index 0000000..9923a1b --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/__init__.py @@ -0,0 +1,131 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .flows import ( + FlowsResource, + AsyncFlowsResource, + FlowsResourceWithRawResponse, + AsyncFlowsResourceWithRawResponse, + FlowsResourceWithStreamingResponse, + AsyncFlowsResourceWithStreamingResponse, +) +from .events import ( + EventsResource, + AsyncEventsResource, + EventsResourceWithRawResponse, + AsyncEventsResourceWithRawResponse, + EventsResourceWithStreamingResponse, + AsyncEventsResourceWithStreamingResponse, +) +from .actions import ( + ActionsResource, + AsyncActionsResource, + ActionsResourceWithRawResponse, + AsyncActionsResourceWithRawResponse, + ActionsResourceWithStreamingResponse, + AsyncActionsResourceWithStreamingResponse, +) +from .secrets import ( + SecretsResource, + AsyncSecretsResource, + SecretsResourceWithRawResponse, + AsyncSecretsResourceWithRawResponse, + SecretsResourceWithStreamingResponse, + AsyncSecretsResourceWithStreamingResponse, +) +from .triggers import ( + TriggersResource, + AsyncTriggersResource, + TriggersResourceWithRawResponse, + AsyncTriggersResourceWithRawResponse, + TriggersResourceWithStreamingResponse, + AsyncTriggersResourceWithStreamingResponse, +) +from .timezones import ( + TimezonesResource, + AsyncTimezonesResource, + TimezonesResourceWithRawResponse, + AsyncTimezonesResourceWithRawResponse, + TimezonesResourceWithStreamingResponse, + AsyncTimezonesResourceWithStreamingResponse, +) +from .workflows import ( + WorkflowsResource, + AsyncWorkflowsResource, + WorkflowsResourceWithRawResponse, + AsyncWorkflowsResourceWithRawResponse, + WorkflowsResourceWithStreamingResponse, + AsyncWorkflowsResourceWithStreamingResponse, +) +from .executions import ( + ExecutionsResource, + AsyncExecutionsResource, + ExecutionsResourceWithRawResponse, + AsyncExecutionsResourceWithRawResponse, + ExecutionsResourceWithStreamingResponse, + AsyncExecutionsResourceWithStreamingResponse, +) +from .action_catalog import ( + ActionCatalogResource, + AsyncActionCatalogResource, + ActionCatalogResourceWithRawResponse, + AsyncActionCatalogResourceWithRawResponse, + ActionCatalogResourceWithStreamingResponse, + AsyncActionCatalogResourceWithStreamingResponse, +) + +__all__ = [ + "TriggersResource", + "AsyncTriggersResource", + "TriggersResourceWithRawResponse", + "AsyncTriggersResourceWithRawResponse", + "TriggersResourceWithStreamingResponse", + "AsyncTriggersResourceWithStreamingResponse", + "ActionCatalogResource", + "AsyncActionCatalogResource", + "ActionCatalogResourceWithRawResponse", + "AsyncActionCatalogResourceWithRawResponse", + "ActionCatalogResourceWithStreamingResponse", + "AsyncActionCatalogResourceWithStreamingResponse", + "ActionsResource", + "AsyncActionsResource", + "ActionsResourceWithRawResponse", + "AsyncActionsResourceWithRawResponse", + "ActionsResourceWithStreamingResponse", + "AsyncActionsResourceWithStreamingResponse", + "FlowsResource", + "AsyncFlowsResource", + "FlowsResourceWithRawResponse", + "AsyncFlowsResourceWithRawResponse", + "FlowsResourceWithStreamingResponse", + "AsyncFlowsResourceWithStreamingResponse", + "EventsResource", + "AsyncEventsResource", + "EventsResourceWithRawResponse", + "AsyncEventsResourceWithRawResponse", + "EventsResourceWithStreamingResponse", + "AsyncEventsResourceWithStreamingResponse", + "ExecutionsResource", + "AsyncExecutionsResource", + "ExecutionsResourceWithRawResponse", + "AsyncExecutionsResourceWithRawResponse", + "ExecutionsResourceWithStreamingResponse", + "AsyncExecutionsResourceWithStreamingResponse", + "TimezonesResource", + "AsyncTimezonesResource", + "TimezonesResourceWithRawResponse", + "AsyncTimezonesResourceWithRawResponse", + "TimezonesResourceWithStreamingResponse", + "AsyncTimezonesResourceWithStreamingResponse", + "SecretsResource", + "AsyncSecretsResource", + "SecretsResourceWithRawResponse", + "AsyncSecretsResourceWithRawResponse", + "SecretsResourceWithStreamingResponse", + "AsyncSecretsResourceWithStreamingResponse", + "WorkflowsResource", + "AsyncWorkflowsResource", + "WorkflowsResourceWithRawResponse", + "AsyncWorkflowsResourceWithRawResponse", + "WorkflowsResourceWithStreamingResponse", + "AsyncWorkflowsResourceWithStreamingResponse", +] diff --git a/src/mobilerun_sdk/resources/workflows/action_catalog.py b/src/mobilerun_sdk/resources/workflows/action_catalog.py new file mode 100644 index 0000000..b637dd4 --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/action_catalog.py @@ -0,0 +1,268 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal + +import httpx + +from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ..._utils import path_template, maybe_transform, async_maybe_transform +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._base_client import make_request_options +from ...types.workflows import action_catalog_list_params +from ...types.workflows.action_catalog_list_response import ActionCatalogListResponse +from ...types.workflows.action_catalog_retrieve_response import ActionCatalogRetrieveResponse + +__all__ = ["ActionCatalogResource", "AsyncActionCatalogResource"] + + +class ActionCatalogResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> ActionCatalogResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return ActionCatalogResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ActionCatalogResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return ActionCatalogResourceWithStreamingResponse(self) + + def retrieve( + self, + catalog_entry_id: str, + *, + # 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, + ) -> ActionCatalogRetrieveResponse: + """ + Get a catalog entry + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not catalog_entry_id: + raise ValueError(f"Expected a non-empty value for `catalog_entry_id` but received {catalog_entry_id!r}") + return self._get( + path_template("/action-catalog/{catalog_entry_id}", catalog_entry_id=catalog_entry_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ActionCatalogRetrieveResponse, + ) + + def list( + self, + *, + page: int | Omit = omit, + page_size: int | Omit = omit, + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] | 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, + ) -> ActionCatalogListResponse: + """ + List action catalog entries + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get( + "/action-catalog", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "page_size": page_size, + "service": service, + }, + action_catalog_list_params.ActionCatalogListParams, + ), + ), + cast_to=ActionCatalogListResponse, + ) + + +class AsyncActionCatalogResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncActionCatalogResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncActionCatalogResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncActionCatalogResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncActionCatalogResourceWithStreamingResponse(self) + + async def retrieve( + self, + catalog_entry_id: str, + *, + # 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, + ) -> ActionCatalogRetrieveResponse: + """ + Get a catalog entry + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not catalog_entry_id: + raise ValueError(f"Expected a non-empty value for `catalog_entry_id` but received {catalog_entry_id!r}") + return await self._get( + path_template("/action-catalog/{catalog_entry_id}", catalog_entry_id=catalog_entry_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ActionCatalogRetrieveResponse, + ) + + async def list( + self, + *, + page: int | Omit = omit, + page_size: int | Omit = omit, + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] | 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, + ) -> ActionCatalogListResponse: + """ + List action catalog entries + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._get( + "/action-catalog", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "page": page, + "page_size": page_size, + "service": service, + }, + action_catalog_list_params.ActionCatalogListParams, + ), + ), + cast_to=ActionCatalogListResponse, + ) + + +class ActionCatalogResourceWithRawResponse: + def __init__(self, action_catalog: ActionCatalogResource) -> None: + self._action_catalog = action_catalog + + self.retrieve = to_raw_response_wrapper( + action_catalog.retrieve, + ) + self.list = to_raw_response_wrapper( + action_catalog.list, + ) + + +class AsyncActionCatalogResourceWithRawResponse: + def __init__(self, action_catalog: AsyncActionCatalogResource) -> None: + self._action_catalog = action_catalog + + self.retrieve = async_to_raw_response_wrapper( + action_catalog.retrieve, + ) + self.list = async_to_raw_response_wrapper( + action_catalog.list, + ) + + +class ActionCatalogResourceWithStreamingResponse: + def __init__(self, action_catalog: ActionCatalogResource) -> None: + self._action_catalog = action_catalog + + self.retrieve = to_streamed_response_wrapper( + action_catalog.retrieve, + ) + self.list = to_streamed_response_wrapper( + action_catalog.list, + ) + + +class AsyncActionCatalogResourceWithStreamingResponse: + def __init__(self, action_catalog: AsyncActionCatalogResource) -> None: + self._action_catalog = action_catalog + + self.retrieve = async_to_streamed_response_wrapper( + action_catalog.retrieve, + ) + self.list = async_to_streamed_response_wrapper( + action_catalog.list, + ) diff --git a/src/mobilerun_sdk/resources/workflows/actions/__init__.py b/src/mobilerun_sdk/resources/workflows/actions/__init__.py new file mode 100644 index 0000000..f4307e4 --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/actions/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .actions import ( + ActionsResource, + AsyncActionsResource, + ActionsResourceWithRawResponse, + AsyncActionsResourceWithRawResponse, + ActionsResourceWithStreamingResponse, + AsyncActionsResourceWithStreamingResponse, +) +from .services import ( + ServicesResource, + AsyncServicesResource, + ServicesResourceWithRawResponse, + AsyncServicesResourceWithRawResponse, + ServicesResourceWithStreamingResponse, + AsyncServicesResourceWithStreamingResponse, +) + +__all__ = [ + "ServicesResource", + "AsyncServicesResource", + "ServicesResourceWithRawResponse", + "AsyncServicesResourceWithRawResponse", + "ServicesResourceWithStreamingResponse", + "AsyncServicesResourceWithStreamingResponse", + "ActionsResource", + "AsyncActionsResource", + "ActionsResourceWithRawResponse", + "AsyncActionsResourceWithRawResponse", + "ActionsResourceWithStreamingResponse", + "AsyncActionsResourceWithStreamingResponse", +] diff --git a/src/mobilerun_sdk/resources/workflows/actions/actions.py b/src/mobilerun_sdk/resources/workflows/actions/actions.py new file mode 100644 index 0000000..2b4723a --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/actions/actions.py @@ -0,0 +1,592 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Optional +from typing_extensions import Literal + +import httpx + +from .services import ( + ServicesResource, + AsyncServicesResource, + ServicesResourceWithRawResponse, + AsyncServicesResourceWithRawResponse, + ServicesResourceWithStreamingResponse, + AsyncServicesResourceWithStreamingResponse, +) +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._base_client import make_request_options +from ....types.workflows import action_list_params, action_create_params, action_update_params +from ....types.workflows.action_list_response import ActionListResponse +from ....types.workflows.action_create_response import ActionCreateResponse +from ....types.workflows.action_delete_response import ActionDeleteResponse +from ....types.workflows.action_update_response import ActionUpdateResponse +from ....types.workflows.action_retrieve_response import ActionRetrieveResponse + +__all__ = ["ActionsResource", "AsyncActionsResource"] + + +class ActionsResource(SyncAPIResource): + @cached_property + def services(self) -> ServicesResource: + return ServicesResource(self._client) + + @cached_property + def with_raw_response(self) -> ActionsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return ActionsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ActionsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return ActionsResourceWithStreamingResponse(self) + + def create( + self, + *, + catalog_entry_id: str, + name: str, + description: str | Omit = omit, + params: Dict[str, Optional[object]] | 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, + ) -> ActionCreateResponse: + """ + Create an action + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/actions", + body=maybe_transform( + { + "catalog_entry_id": catalog_entry_id, + "name": name, + "description": description, + "params": params, + }, + action_create_params.ActionCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ActionCreateResponse, + ) + + def retrieve( + self, + action_id: str, + *, + # 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, + ) -> ActionRetrieveResponse: + """ + Get an action + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not action_id: + raise ValueError(f"Expected a non-empty value for `action_id` but received {action_id!r}") + return self._get( + 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 + ), + cast_to=ActionRetrieveResponse, + ) + + def update( + self, + action_id: str, + *, + description: str | Omit = omit, + name: str | Omit = omit, + params: Dict[str, Optional[object]] | 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, + ) -> ActionUpdateResponse: + """ + Update an action + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not action_id: + raise ValueError(f"Expected a non-empty value for `action_id` but received {action_id!r}") + return self._patch( + path_template("/actions/{action_id}", action_id=action_id), + body=maybe_transform( + { + "description": description, + "name": name, + "params": params, + }, + action_update_params.ActionUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ActionUpdateResponse, + ) + + def list( + self, + *, + order_by: Literal["name", "createdAt", "updatedAt"] | Omit = omit, + order_by_direction: Literal["asc", "desc"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + search: str | Omit = omit, + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] | 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, + ) -> ActionListResponse: + """ + List actions + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get( + "/actions", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "order_by": order_by, + "order_by_direction": order_by_direction, + "page": page, + "page_size": page_size, + "search": search, + "service": service, + }, + action_list_params.ActionListParams, + ), + ), + cast_to=ActionListResponse, + ) + + def delete( + self, + action_id: str, + *, + # 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, + ) -> ActionDeleteResponse: + """ + Delete an action + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=ActionDeleteResponse, + ) + + +class AsyncActionsResource(AsyncAPIResource): + @cached_property + def services(self) -> AsyncServicesResource: + return AsyncServicesResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncActionsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncActionsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncActionsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncActionsResourceWithStreamingResponse(self) + + async def create( + self, + *, + catalog_entry_id: str, + name: str, + description: str | Omit = omit, + params: Dict[str, Optional[object]] | 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, + ) -> ActionCreateResponse: + """ + Create an action + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/actions", + body=await async_maybe_transform( + { + "catalog_entry_id": catalog_entry_id, + "name": name, + "description": description, + "params": params, + }, + action_create_params.ActionCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ActionCreateResponse, + ) + + async def retrieve( + self, + action_id: str, + *, + # 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, + ) -> ActionRetrieveResponse: + """ + Get an action + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not action_id: + raise ValueError(f"Expected a non-empty value for `action_id` but received {action_id!r}") + return await self._get( + 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 + ), + cast_to=ActionRetrieveResponse, + ) + + async def update( + self, + action_id: str, + *, + description: str | Omit = omit, + name: str | Omit = omit, + params: Dict[str, Optional[object]] | 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, + ) -> ActionUpdateResponse: + """ + Update an action + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not action_id: + raise ValueError(f"Expected a non-empty value for `action_id` but received {action_id!r}") + return await self._patch( + path_template("/actions/{action_id}", action_id=action_id), + body=await async_maybe_transform( + { + "description": description, + "name": name, + "params": params, + }, + action_update_params.ActionUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ActionUpdateResponse, + ) + + async def list( + self, + *, + order_by: Literal["name", "createdAt", "updatedAt"] | Omit = omit, + order_by_direction: Literal["asc", "desc"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + search: str | Omit = omit, + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] | 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, + ) -> ActionListResponse: + """ + List actions + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._get( + "/actions", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "order_by": order_by, + "order_by_direction": order_by_direction, + "page": page, + "page_size": page_size, + "search": search, + "service": service, + }, + action_list_params.ActionListParams, + ), + ), + cast_to=ActionListResponse, + ) + + async def delete( + self, + action_id: str, + *, + # 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, + ) -> ActionDeleteResponse: + """ + Delete an action + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=ActionDeleteResponse, + ) + + +class ActionsResourceWithRawResponse: + def __init__(self, actions: ActionsResource) -> None: + self._actions = actions + + self.create = to_raw_response_wrapper( + actions.create, + ) + self.retrieve = to_raw_response_wrapper( + actions.retrieve, + ) + self.update = to_raw_response_wrapper( + actions.update, + ) + self.list = to_raw_response_wrapper( + actions.list, + ) + self.delete = to_raw_response_wrapper( + actions.delete, + ) + + @cached_property + def services(self) -> ServicesResourceWithRawResponse: + return ServicesResourceWithRawResponse(self._actions.services) + + +class AsyncActionsResourceWithRawResponse: + def __init__(self, actions: AsyncActionsResource) -> None: + self._actions = actions + + self.create = async_to_raw_response_wrapper( + actions.create, + ) + self.retrieve = async_to_raw_response_wrapper( + actions.retrieve, + ) + self.update = async_to_raw_response_wrapper( + actions.update, + ) + self.list = async_to_raw_response_wrapper( + actions.list, + ) + self.delete = async_to_raw_response_wrapper( + actions.delete, + ) + + @cached_property + def services(self) -> AsyncServicesResourceWithRawResponse: + return AsyncServicesResourceWithRawResponse(self._actions.services) + + +class ActionsResourceWithStreamingResponse: + def __init__(self, actions: ActionsResource) -> None: + self._actions = actions + + self.create = to_streamed_response_wrapper( + actions.create, + ) + self.retrieve = to_streamed_response_wrapper( + actions.retrieve, + ) + self.update = to_streamed_response_wrapper( + actions.update, + ) + self.list = to_streamed_response_wrapper( + actions.list, + ) + self.delete = to_streamed_response_wrapper( + actions.delete, + ) + + @cached_property + def services(self) -> ServicesResourceWithStreamingResponse: + return ServicesResourceWithStreamingResponse(self._actions.services) + + +class AsyncActionsResourceWithStreamingResponse: + def __init__(self, actions: AsyncActionsResource) -> None: + self._actions = actions + + self.create = async_to_streamed_response_wrapper( + actions.create, + ) + self.retrieve = async_to_streamed_response_wrapper( + actions.retrieve, + ) + self.update = async_to_streamed_response_wrapper( + actions.update, + ) + self.list = async_to_streamed_response_wrapper( + actions.list, + ) + self.delete = async_to_streamed_response_wrapper( + actions.delete, + ) + + @cached_property + def services(self) -> AsyncServicesResourceWithStreamingResponse: + return AsyncServicesResourceWithStreamingResponse(self._actions.services) diff --git a/src/mobilerun_sdk/resources/workflows/actions/services.py b/src/mobilerun_sdk/resources/workflows/actions/services.py new file mode 100644 index 0000000..fd46c48 --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/actions/services.py @@ -0,0 +1,215 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._base_client import make_request_options +from ....types.workflows.actions.service_list_response import ServiceListResponse +from ....types.workflows.actions.service_list_methods_response import ServiceListMethodsResponse + +__all__ = ["ServicesResource", "AsyncServicesResource"] + + +class ServicesResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> ServicesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return ServicesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ServicesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return ServicesResourceWithStreamingResponse(self) + + def list( + self, + *, + # 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, + ) -> ServiceListResponse: + """List available services""" + return self._get( + "/actions/services", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ServiceListResponse, + ) + + def list_methods( + self, + service: str, + *, + # 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, + ) -> ServiceListMethodsResponse: + """ + List allowed methods for a service + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not service: + raise ValueError(f"Expected a non-empty value for `service` but received {service!r}") + return self._get( + path_template("/actions/services/{service}/methods", service=service), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ServiceListMethodsResponse, + ) + + +class AsyncServicesResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncServicesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncServicesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncServicesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncServicesResourceWithStreamingResponse(self) + + async def list( + self, + *, + # 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, + ) -> ServiceListResponse: + """List available services""" + return await self._get( + "/actions/services", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ServiceListResponse, + ) + + async def list_methods( + self, + service: str, + *, + # 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, + ) -> ServiceListMethodsResponse: + """ + List allowed methods for a service + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not service: + raise ValueError(f"Expected a non-empty value for `service` but received {service!r}") + return await self._get( + path_template("/actions/services/{service}/methods", service=service), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ServiceListMethodsResponse, + ) + + +class ServicesResourceWithRawResponse: + def __init__(self, services: ServicesResource) -> None: + self._services = services + + self.list = to_raw_response_wrapper( + services.list, + ) + self.list_methods = to_raw_response_wrapper( + services.list_methods, + ) + + +class AsyncServicesResourceWithRawResponse: + def __init__(self, services: AsyncServicesResource) -> None: + self._services = services + + self.list = async_to_raw_response_wrapper( + services.list, + ) + self.list_methods = async_to_raw_response_wrapper( + services.list_methods, + ) + + +class ServicesResourceWithStreamingResponse: + def __init__(self, services: ServicesResource) -> None: + self._services = services + + self.list = to_streamed_response_wrapper( + services.list, + ) + self.list_methods = to_streamed_response_wrapper( + services.list_methods, + ) + + +class AsyncServicesResourceWithStreamingResponse: + def __init__(self, services: AsyncServicesResource) -> None: + self._services = services + + self.list = async_to_streamed_response_wrapper( + services.list, + ) + self.list_methods = async_to_streamed_response_wrapper( + services.list_methods, + ) diff --git a/src/mobilerun_sdk/resources/workflows/events/__init__.py b/src/mobilerun_sdk/resources/workflows/events/__init__.py new file mode 100644 index 0000000..2c1e382 --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/events/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .events import ( + EventsResource, + AsyncEventsResource, + EventsResourceWithRawResponse, + AsyncEventsResourceWithRawResponse, + EventsResourceWithStreamingResponse, + AsyncEventsResourceWithStreamingResponse, +) +from .catalog import ( + CatalogResource, + AsyncCatalogResource, + CatalogResourceWithRawResponse, + AsyncCatalogResourceWithRawResponse, + CatalogResourceWithStreamingResponse, + AsyncCatalogResourceWithStreamingResponse, +) + +__all__ = [ + "CatalogResource", + "AsyncCatalogResource", + "CatalogResourceWithRawResponse", + "AsyncCatalogResourceWithRawResponse", + "CatalogResourceWithStreamingResponse", + "AsyncCatalogResourceWithStreamingResponse", + "EventsResource", + "AsyncEventsResource", + "EventsResourceWithRawResponse", + "AsyncEventsResourceWithRawResponse", + "EventsResourceWithStreamingResponse", + "AsyncEventsResourceWithStreamingResponse", +] diff --git a/src/mobilerun_sdk/resources/workflows/events/catalog.py b/src/mobilerun_sdk/resources/workflows/events/catalog.py new file mode 100644 index 0000000..73c22cc --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/events/catalog.py @@ -0,0 +1,267 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Literal + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._base_client import make_request_options +from ....types.workflows.events import catalog_list_params, catalog_register_params +from ....types.workflows.events.catalog_list_response import CatalogListResponse +from ....types.workflows.events.catalog_register_response import CatalogRegisterResponse + +__all__ = ["CatalogResource", "AsyncCatalogResource"] + + +class CatalogResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> CatalogResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return CatalogResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> CatalogResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return CatalogResourceWithStreamingResponse(self) + + def list( + self, + *, + page: int | Omit = omit, + page_size: int | Omit = omit, + source: Literal["device", "system", "webhook"] | 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, + ) -> CatalogListResponse: + """ + List event catalog + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get( + "/events/catalog", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "page_size": page_size, + "source": source, + }, + catalog_list_params.CatalogListParams, + ), + ), + cast_to=CatalogListResponse, + ) + + def register( + self, + *, + events: Iterable[catalog_register_params.Event], + # 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, + ) -> CatalogRegisterResponse: + """ + Register event types in the catalog + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/events/catalog/register", + body=maybe_transform({"events": events}, catalog_register_params.CatalogRegisterParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CatalogRegisterResponse, + ) + + +class AsyncCatalogResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncCatalogResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncCatalogResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncCatalogResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncCatalogResourceWithStreamingResponse(self) + + async def list( + self, + *, + page: int | Omit = omit, + page_size: int | Omit = omit, + source: Literal["device", "system", "webhook"] | 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, + ) -> CatalogListResponse: + """ + List event catalog + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._get( + "/events/catalog", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "page": page, + "page_size": page_size, + "source": source, + }, + catalog_list_params.CatalogListParams, + ), + ), + cast_to=CatalogListResponse, + ) + + async def register( + self, + *, + events: Iterable[catalog_register_params.Event], + # 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, + ) -> CatalogRegisterResponse: + """ + Register event types in the catalog + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/events/catalog/register", + body=await async_maybe_transform({"events": events}, catalog_register_params.CatalogRegisterParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=CatalogRegisterResponse, + ) + + +class CatalogResourceWithRawResponse: + def __init__(self, catalog: CatalogResource) -> None: + self._catalog = catalog + + self.list = to_raw_response_wrapper( + catalog.list, + ) + self.register = to_raw_response_wrapper( + catalog.register, + ) + + +class AsyncCatalogResourceWithRawResponse: + def __init__(self, catalog: AsyncCatalogResource) -> None: + self._catalog = catalog + + self.list = async_to_raw_response_wrapper( + catalog.list, + ) + self.register = async_to_raw_response_wrapper( + catalog.register, + ) + + +class CatalogResourceWithStreamingResponse: + def __init__(self, catalog: CatalogResource) -> None: + self._catalog = catalog + + self.list = to_streamed_response_wrapper( + catalog.list, + ) + self.register = to_streamed_response_wrapper( + catalog.register, + ) + + +class AsyncCatalogResourceWithStreamingResponse: + def __init__(self, catalog: AsyncCatalogResource) -> None: + self._catalog = catalog + + self.list = async_to_streamed_response_wrapper( + catalog.list, + ) + self.register = async_to_streamed_response_wrapper( + catalog.register, + ) diff --git a/src/mobilerun_sdk/resources/workflows/events/events.py b/src/mobilerun_sdk/resources/workflows/events/events.py new file mode 100644 index 0000000..09d9238 --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/events/events.py @@ -0,0 +1,316 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Optional + +import httpx + +from .catalog import ( + CatalogResource, + AsyncCatalogResource, + CatalogResourceWithRawResponse, + AsyncCatalogResourceWithRawResponse, + CatalogResourceWithStreamingResponse, + AsyncCatalogResourceWithStreamingResponse, +) +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._base_client import make_request_options +from ....types.workflows import event_ingest_params, event_dry_run_params +from ....types.workflows.event_ingest_response import EventIngestResponse +from ....types.workflows.event_dry_run_response import EventDryRunResponse + +__all__ = ["EventsResource", "AsyncEventsResource"] + + +class EventsResource(SyncAPIResource): + @cached_property + def catalog(self) -> CatalogResource: + return CatalogResource(self._client) + + @cached_property + def with_raw_response(self) -> EventsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return EventsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> EventsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return EventsResourceWithStreamingResponse(self) + + def dry_run( + self, + *, + event_type: str, + device_id: str | Omit = omit, + payload: Dict[str, Optional[object]] | 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, + ) -> EventDryRunResponse: + """Simulate an event against all configured flows. + + Returns which flows would match + and what actions would run, without storing the event or enqueuing jobs. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/events/dry-run", + body=maybe_transform( + { + "event_type": event_type, + "device_id": device_id, + "payload": payload, + }, + event_dry_run_params.EventDryRunParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=EventDryRunResponse, + ) + + def ingest( + self, + *, + event_type: str, + device_id: str | Omit = omit, + payload: Dict[str, Optional[object]] | 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, + ) -> EventIngestResponse: + """Ingest an event for trigger evaluation. + + Returns immediately with 202 Accepted. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/events/ingest", + body=maybe_transform( + { + "event_type": event_type, + "device_id": device_id, + "payload": payload, + }, + event_ingest_params.EventIngestParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=EventIngestResponse, + ) + + +class AsyncEventsResource(AsyncAPIResource): + @cached_property + def catalog(self) -> AsyncCatalogResource: + return AsyncCatalogResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncEventsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncEventsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncEventsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncEventsResourceWithStreamingResponse(self) + + async def dry_run( + self, + *, + event_type: str, + device_id: str | Omit = omit, + payload: Dict[str, Optional[object]] | 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, + ) -> EventDryRunResponse: + """Simulate an event against all configured flows. + + Returns which flows would match + and what actions would run, without storing the event or enqueuing jobs. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/events/dry-run", + body=await async_maybe_transform( + { + "event_type": event_type, + "device_id": device_id, + "payload": payload, + }, + event_dry_run_params.EventDryRunParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=EventDryRunResponse, + ) + + async def ingest( + self, + *, + event_type: str, + device_id: str | Omit = omit, + payload: Dict[str, Optional[object]] | 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, + ) -> EventIngestResponse: + """Ingest an event for trigger evaluation. + + Returns immediately with 202 Accepted. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/events/ingest", + body=await async_maybe_transform( + { + "event_type": event_type, + "device_id": device_id, + "payload": payload, + }, + event_ingest_params.EventIngestParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=EventIngestResponse, + ) + + +class EventsResourceWithRawResponse: + def __init__(self, events: EventsResource) -> None: + self._events = events + + self.dry_run = to_raw_response_wrapper( + events.dry_run, + ) + self.ingest = to_raw_response_wrapper( + events.ingest, + ) + + @cached_property + def catalog(self) -> CatalogResourceWithRawResponse: + return CatalogResourceWithRawResponse(self._events.catalog) + + +class AsyncEventsResourceWithRawResponse: + def __init__(self, events: AsyncEventsResource) -> None: + self._events = events + + self.dry_run = async_to_raw_response_wrapper( + events.dry_run, + ) + self.ingest = async_to_raw_response_wrapper( + events.ingest, + ) + + @cached_property + def catalog(self) -> AsyncCatalogResourceWithRawResponse: + return AsyncCatalogResourceWithRawResponse(self._events.catalog) + + +class EventsResourceWithStreamingResponse: + def __init__(self, events: EventsResource) -> None: + self._events = events + + self.dry_run = to_streamed_response_wrapper( + events.dry_run, + ) + self.ingest = to_streamed_response_wrapper( + events.ingest, + ) + + @cached_property + def catalog(self) -> CatalogResourceWithStreamingResponse: + return CatalogResourceWithStreamingResponse(self._events.catalog) + + +class AsyncEventsResourceWithStreamingResponse: + def __init__(self, events: AsyncEventsResource) -> None: + self._events = events + + self.dry_run = async_to_streamed_response_wrapper( + events.dry_run, + ) + self.ingest = async_to_streamed_response_wrapper( + events.ingest, + ) + + @cached_property + def catalog(self) -> AsyncCatalogResourceWithStreamingResponse: + return AsyncCatalogResourceWithStreamingResponse(self._events.catalog) diff --git a/src/mobilerun_sdk/resources/workflows/executions.py b/src/mobilerun_sdk/resources/workflows/executions.py new file mode 100644 index 0000000..cb5a0dd --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/executions.py @@ -0,0 +1,402 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal + +import httpx + +from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ..._utils import path_template, maybe_transform, async_maybe_transform +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._base_client import make_request_options +from ...types.workflows import execution_list_params, execution_get_metrics_params +from ...types.workflows.execution_list_response import ExecutionListResponse +from ...types.workflows.execution_retrieve_response import ExecutionRetrieveResponse +from ...types.workflows.execution_get_metrics_response import ExecutionGetMetricsResponse + +__all__ = ["ExecutionsResource", "AsyncExecutionsResource"] + + +class ExecutionsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> ExecutionsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return ExecutionsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ExecutionsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return ExecutionsResourceWithStreamingResponse(self) + + def retrieve( + self, + execution_id: str, + *, + # 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, + ) -> ExecutionRetrieveResponse: + """ + Get execution details + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not execution_id: + raise ValueError(f"Expected a non-empty value for `execution_id` but received {execution_id!r}") + return self._get( + path_template("/executions/{execution_id}", execution_id=execution_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ExecutionRetrieveResponse, + ) + + def list( + self, + *, + flow_id: str | Omit = omit, + from_: Optional[str] | Omit = omit, + order_by: Literal["startedAt", "finishedAt", "status"] | Omit = omit, + order_by_direction: Literal["asc", "desc"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + search: str | Omit = omit, + status: Literal["pending", "running", "success", "failed"] | Omit = omit, + to: Optional[str] | Omit = omit, + trigger_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, + ) -> ExecutionListResponse: + """ + List flow executions + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get( + "/executions", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "flow_id": flow_id, + "from_": from_, + "order_by": order_by, + "order_by_direction": order_by_direction, + "page": page, + "page_size": page_size, + "search": search, + "status": status, + "to": to, + "trigger_id": trigger_id, + }, + execution_list_params.ExecutionListParams, + ), + ), + cast_to=ExecutionListResponse, + ) + + def get_metrics( + self, + *, + flow_id: str | Omit = omit, + from_: Optional[str] | Omit = omit, + to: Optional[str] | Omit = omit, + trigger_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, + ) -> ExecutionGetMetricsResponse: + """ + Get execution metrics + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get( + "/executions/metrics", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "flow_id": flow_id, + "from_": from_, + "to": to, + "trigger_id": trigger_id, + }, + execution_get_metrics_params.ExecutionGetMetricsParams, + ), + ), + cast_to=ExecutionGetMetricsResponse, + ) + + +class AsyncExecutionsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncExecutionsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncExecutionsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncExecutionsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncExecutionsResourceWithStreamingResponse(self) + + async def retrieve( + self, + execution_id: str, + *, + # 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, + ) -> ExecutionRetrieveResponse: + """ + Get execution details + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not execution_id: + raise ValueError(f"Expected a non-empty value for `execution_id` but received {execution_id!r}") + return await self._get( + path_template("/executions/{execution_id}", execution_id=execution_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ExecutionRetrieveResponse, + ) + + async def list( + self, + *, + flow_id: str | Omit = omit, + from_: Optional[str] | Omit = omit, + order_by: Literal["startedAt", "finishedAt", "status"] | Omit = omit, + order_by_direction: Literal["asc", "desc"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + search: str | Omit = omit, + status: Literal["pending", "running", "success", "failed"] | Omit = omit, + to: Optional[str] | Omit = omit, + trigger_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, + ) -> ExecutionListResponse: + """ + List flow executions + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._get( + "/executions", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "flow_id": flow_id, + "from_": from_, + "order_by": order_by, + "order_by_direction": order_by_direction, + "page": page, + "page_size": page_size, + "search": search, + "status": status, + "to": to, + "trigger_id": trigger_id, + }, + execution_list_params.ExecutionListParams, + ), + ), + cast_to=ExecutionListResponse, + ) + + async def get_metrics( + self, + *, + flow_id: str | Omit = omit, + from_: Optional[str] | Omit = omit, + to: Optional[str] | Omit = omit, + trigger_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, + ) -> ExecutionGetMetricsResponse: + """ + Get execution metrics + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._get( + "/executions/metrics", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "flow_id": flow_id, + "from_": from_, + "to": to, + "trigger_id": trigger_id, + }, + execution_get_metrics_params.ExecutionGetMetricsParams, + ), + ), + cast_to=ExecutionGetMetricsResponse, + ) + + +class ExecutionsResourceWithRawResponse: + def __init__(self, executions: ExecutionsResource) -> None: + self._executions = executions + + self.retrieve = to_raw_response_wrapper( + executions.retrieve, + ) + self.list = to_raw_response_wrapper( + executions.list, + ) + self.get_metrics = to_raw_response_wrapper( + executions.get_metrics, + ) + + +class AsyncExecutionsResourceWithRawResponse: + def __init__(self, executions: AsyncExecutionsResource) -> None: + self._executions = executions + + self.retrieve = async_to_raw_response_wrapper( + executions.retrieve, + ) + self.list = async_to_raw_response_wrapper( + executions.list, + ) + self.get_metrics = async_to_raw_response_wrapper( + executions.get_metrics, + ) + + +class ExecutionsResourceWithStreamingResponse: + def __init__(self, executions: ExecutionsResource) -> None: + self._executions = executions + + self.retrieve = to_streamed_response_wrapper( + executions.retrieve, + ) + self.list = to_streamed_response_wrapper( + executions.list, + ) + self.get_metrics = to_streamed_response_wrapper( + executions.get_metrics, + ) + + +class AsyncExecutionsResourceWithStreamingResponse: + def __init__(self, executions: AsyncExecutionsResource) -> None: + self._executions = executions + + self.retrieve = async_to_streamed_response_wrapper( + executions.retrieve, + ) + self.list = async_to_streamed_response_wrapper( + executions.list, + ) + self.get_metrics = async_to_streamed_response_wrapper( + executions.get_metrics, + ) diff --git a/src/mobilerun_sdk/resources/workflows/flows/__init__.py b/src/mobilerun_sdk/resources/workflows/flows/__init__.py new file mode 100644 index 0000000..bfeb155 --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/flows/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .flows import ( + FlowsResource, + AsyncFlowsResource, + FlowsResourceWithRawResponse, + AsyncFlowsResourceWithRawResponse, + FlowsResourceWithStreamingResponse, + AsyncFlowsResourceWithStreamingResponse, +) +from .actions import ( + ActionsResource, + AsyncActionsResource, + ActionsResourceWithRawResponse, + AsyncActionsResourceWithRawResponse, + ActionsResourceWithStreamingResponse, + AsyncActionsResourceWithStreamingResponse, +) + +__all__ = [ + "ActionsResource", + "AsyncActionsResource", + "ActionsResourceWithRawResponse", + "AsyncActionsResourceWithRawResponse", + "ActionsResourceWithStreamingResponse", + "AsyncActionsResourceWithStreamingResponse", + "FlowsResource", + "AsyncFlowsResource", + "FlowsResourceWithRawResponse", + "AsyncFlowsResourceWithRawResponse", + "FlowsResourceWithStreamingResponse", + "AsyncFlowsResourceWithStreamingResponse", +] diff --git a/src/mobilerun_sdk/resources/workflows/flows/actions.py b/src/mobilerun_sdk/resources/workflows/flows/actions.py new file mode 100644 index 0000000..caea3b8 --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/flows/actions.py @@ -0,0 +1,458 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable, Optional + +import httpx + +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._base_client import make_request_options +from ....types.workflows.flows import action_add_params, action_replace_params +from ....types.workflows.flows.action_add_response import ActionAddResponse +from ....types.workflows.flows.action_list_response import ActionListResponse +from ....types.workflows.flow_action_overrides_param import FlowActionOverridesParam +from ....types.workflows.flows.action_remove_response import ActionRemoveResponse +from ....types.workflows.flow_child_action_input_param import FlowChildActionInputParam +from ....types.workflows.flows.action_replace_response import ActionReplaceResponse + +__all__ = ["ActionsResource", "AsyncActionsResource"] + + +class ActionsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> ActionsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return ActionsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ActionsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return ActionsResourceWithStreamingResponse(self) + + def list( + self, + flow_id: str, + *, + # 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, + ) -> ActionListResponse: + """ + List actions for a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not flow_id: + raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") + return self._get( + path_template("/flows/{flow_id}/actions", flow_id=flow_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ActionListResponse, + ) + + def add( + self, + flow_id: str, + *, + action_id: str, + position: int, + children: Iterable[FlowChildActionInputParam] | Omit = omit, + continue_on_error: bool | Omit = omit, + device_id: str | Omit = omit, + name_override: str | Omit = omit, + overrides: Optional[FlowActionOverridesParam] | Omit = omit, + parent_flow_action_id: Optional[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, + ) -> ActionAddResponse: + """ + Add an action to a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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}/actions", flow_id=flow_id), + body=maybe_transform( + { + "action_id": action_id, + "position": position, + "children": children, + "continue_on_error": continue_on_error, + "device_id": device_id, + "name_override": name_override, + "overrides": overrides, + "parent_flow_action_id": parent_flow_action_id, + }, + action_add_params.ActionAddParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ActionAddResponse, + ) + + def remove( + self, + flow_action_id: str, + *, + flow_id: str, + # 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, + ) -> ActionRemoveResponse: + """ + Remove an action from a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not flow_id: + raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") + if not flow_action_id: + raise ValueError(f"Expected a non-empty value for `flow_action_id` but received {flow_action_id!r}") + 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 + ), + cast_to=ActionRemoveResponse, + ) + + def replace( + self, + flow_id: str, + *, + actions: Iterable[action_replace_params.Action], + # 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, + ) -> ActionReplaceResponse: + """ + Replace all actions for a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not flow_id: + raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") + return self._put( + 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 + ), + cast_to=ActionReplaceResponse, + ) + + +class AsyncActionsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncActionsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncActionsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncActionsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncActionsResourceWithStreamingResponse(self) + + async def list( + self, + flow_id: str, + *, + # 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, + ) -> ActionListResponse: + """ + List actions for a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not flow_id: + raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") + return await self._get( + path_template("/flows/{flow_id}/actions", flow_id=flow_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ActionListResponse, + ) + + async def add( + self, + flow_id: str, + *, + action_id: str, + position: int, + children: Iterable[FlowChildActionInputParam] | Omit = omit, + continue_on_error: bool | Omit = omit, + device_id: str | Omit = omit, + name_override: str | Omit = omit, + overrides: Optional[FlowActionOverridesParam] | Omit = omit, + parent_flow_action_id: Optional[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, + ) -> ActionAddResponse: + """ + Add an action to a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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}/actions", flow_id=flow_id), + body=await async_maybe_transform( + { + "action_id": action_id, + "position": position, + "children": children, + "continue_on_error": continue_on_error, + "device_id": device_id, + "name_override": name_override, + "overrides": overrides, + "parent_flow_action_id": parent_flow_action_id, + }, + action_add_params.ActionAddParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ActionAddResponse, + ) + + async def remove( + self, + flow_action_id: str, + *, + flow_id: str, + # 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, + ) -> ActionRemoveResponse: + """ + Remove an action from a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not flow_id: + raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") + if not flow_action_id: + raise ValueError(f"Expected a non-empty value for `flow_action_id` but received {flow_action_id!r}") + 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 + ), + cast_to=ActionRemoveResponse, + ) + + async def replace( + self, + flow_id: str, + *, + actions: Iterable[action_replace_params.Action], + # 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, + ) -> ActionReplaceResponse: + """ + Replace all actions for a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not flow_id: + raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") + return await self._put( + 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 + ), + cast_to=ActionReplaceResponse, + ) + + +class ActionsResourceWithRawResponse: + def __init__(self, actions: ActionsResource) -> None: + self._actions = actions + + self.list = to_raw_response_wrapper( + actions.list, + ) + self.add = to_raw_response_wrapper( + actions.add, + ) + self.remove = to_raw_response_wrapper( + actions.remove, + ) + self.replace = to_raw_response_wrapper( + actions.replace, + ) + + +class AsyncActionsResourceWithRawResponse: + def __init__(self, actions: AsyncActionsResource) -> None: + self._actions = actions + + self.list = async_to_raw_response_wrapper( + actions.list, + ) + self.add = async_to_raw_response_wrapper( + actions.add, + ) + self.remove = async_to_raw_response_wrapper( + actions.remove, + ) + self.replace = async_to_raw_response_wrapper( + actions.replace, + ) + + +class ActionsResourceWithStreamingResponse: + def __init__(self, actions: ActionsResource) -> None: + self._actions = actions + + self.list = to_streamed_response_wrapper( + actions.list, + ) + self.add = to_streamed_response_wrapper( + actions.add, + ) + self.remove = to_streamed_response_wrapper( + actions.remove, + ) + self.replace = to_streamed_response_wrapper( + actions.replace, + ) + + +class AsyncActionsResourceWithStreamingResponse: + def __init__(self, actions: AsyncActionsResource) -> None: + self._actions = actions + + self.list = async_to_streamed_response_wrapper( + actions.list, + ) + self.add = async_to_streamed_response_wrapper( + actions.add, + ) + self.remove = async_to_streamed_response_wrapper( + actions.remove, + ) + self.replace = async_to_streamed_response_wrapper( + actions.replace, + ) diff --git a/src/mobilerun_sdk/resources/workflows/flows/flows.py b/src/mobilerun_sdk/resources/workflows/flows/flows.py new file mode 100644 index 0000000..0130599 --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/flows/flows.py @@ -0,0 +1,703 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable, Optional +from typing_extensions import Literal + +import httpx + +from .actions import ( + ActionsResource, + AsyncActionsResource, + ActionsResourceWithRawResponse, + AsyncActionsResourceWithRawResponse, + ActionsResourceWithStreamingResponse, + AsyncActionsResourceWithStreamingResponse, +) +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._base_client import make_request_options +from ....types.workflows import flow_list_params, flow_clone_params, flow_create_params, flow_update_params +from ....types.workflows.flow_list_response import FlowListResponse +from ....types.workflows.flow_clone_response import FlowCloneResponse +from ....types.workflows.flow_create_response import FlowCreateResponse +from ....types.workflows.flow_delete_response import FlowDeleteResponse +from ....types.workflows.flow_update_response import FlowUpdateResponse +from ....types.workflows.flow_retrieve_response import FlowRetrieveResponse + +__all__ = ["FlowsResource", "AsyncFlowsResource"] + + +class FlowsResource(SyncAPIResource): + @cached_property + def actions(self) -> ActionsResource: + return ActionsResource(self._client) + + @cached_property + def with_raw_response(self) -> FlowsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return FlowsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> FlowsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return FlowsResourceWithStreamingResponse(self) + + def create( + self, + *, + actions: Iterable[flow_create_params.Action], + name: str, + trigger_id: str, + cooldown_scope: Literal["flow", "device"] | Omit = omit, + cooldown_seconds: Optional[int] | Omit = omit, + description: str | Omit = omit, + enabled: bool | 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, + ) -> FlowCreateResponse: + """ + Create a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/flows", + body=maybe_transform( + { + "actions": actions, + "name": name, + "trigger_id": trigger_id, + "cooldown_scope": cooldown_scope, + "cooldown_seconds": cooldown_seconds, + "description": description, + "enabled": enabled, + }, + flow_create_params.FlowCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FlowCreateResponse, + ) + + def retrieve( + self, + flow_id: str, + *, + # 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, + ) -> FlowRetrieveResponse: + """ + Get a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not flow_id: + raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") + return self._get( + 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 + ), + cast_to=FlowRetrieveResponse, + ) + + def update( + self, + flow_id: str, + *, + cooldown_scope: Literal["flow", "device"] | Omit = omit, + cooldown_seconds: Optional[int] | Omit = omit, + description: str | Omit = omit, + enabled: bool | Omit = omit, + name: str | Omit = omit, + trigger_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, + ) -> FlowUpdateResponse: + """ + Update a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not flow_id: + raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") + return self._patch( + path_template("/flows/{flow_id}", flow_id=flow_id), + body=maybe_transform( + { + "cooldown_scope": cooldown_scope, + "cooldown_seconds": cooldown_seconds, + "description": description, + "enabled": enabled, + "name": name, + "trigger_id": trigger_id, + }, + flow_update_params.FlowUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FlowUpdateResponse, + ) + + def list( + self, + *, + enabled: Optional[bool] | Omit = omit, + order_by: Literal["name", "createdAt", "updatedAt"] | Omit = omit, + order_by_direction: Literal["asc", "desc"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + search: str | Omit = omit, + trigger_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, + ) -> FlowListResponse: + """ + List flows + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get( + "/flows", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "enabled": enabled, + "order_by": order_by, + "order_by_direction": order_by_direction, + "page": page, + "page_size": page_size, + "search": search, + "trigger_id": trigger_id, + }, + flow_list_params.FlowListParams, + ), + ), + cast_to=FlowListResponse, + ) + + def delete( + self, + flow_id: str, + *, + # 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, + ) -> FlowDeleteResponse: + """ + Delete a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=FlowDeleteResponse, + ) + + def clone( + self, + flow_id: str, + *, + 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, + ) -> FlowCloneResponse: + """ + Clone a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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}/clone", flow_id=flow_id), + body=maybe_transform({"name": name}, flow_clone_params.FlowCloneParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FlowCloneResponse, + ) + + +class AsyncFlowsResource(AsyncAPIResource): + @cached_property + def actions(self) -> AsyncActionsResource: + return AsyncActionsResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncFlowsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncFlowsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncFlowsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncFlowsResourceWithStreamingResponse(self) + + async def create( + self, + *, + actions: Iterable[flow_create_params.Action], + name: str, + trigger_id: str, + cooldown_scope: Literal["flow", "device"] | Omit = omit, + cooldown_seconds: Optional[int] | Omit = omit, + description: str | Omit = omit, + enabled: bool | 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, + ) -> FlowCreateResponse: + """ + Create a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/flows", + body=await async_maybe_transform( + { + "actions": actions, + "name": name, + "trigger_id": trigger_id, + "cooldown_scope": cooldown_scope, + "cooldown_seconds": cooldown_seconds, + "description": description, + "enabled": enabled, + }, + flow_create_params.FlowCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FlowCreateResponse, + ) + + async def retrieve( + self, + flow_id: str, + *, + # 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, + ) -> FlowRetrieveResponse: + """ + Get a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not flow_id: + raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") + return await self._get( + 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 + ), + cast_to=FlowRetrieveResponse, + ) + + async def update( + self, + flow_id: str, + *, + cooldown_scope: Literal["flow", "device"] | Omit = omit, + cooldown_seconds: Optional[int] | Omit = omit, + description: str | Omit = omit, + enabled: bool | Omit = omit, + name: str | Omit = omit, + trigger_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, + ) -> FlowUpdateResponse: + """ + Update a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not flow_id: + raise ValueError(f"Expected a non-empty value for `flow_id` but received {flow_id!r}") + return await self._patch( + path_template("/flows/{flow_id}", flow_id=flow_id), + body=await async_maybe_transform( + { + "cooldown_scope": cooldown_scope, + "cooldown_seconds": cooldown_seconds, + "description": description, + "enabled": enabled, + "name": name, + "trigger_id": trigger_id, + }, + flow_update_params.FlowUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FlowUpdateResponse, + ) + + async def list( + self, + *, + enabled: Optional[bool] | Omit = omit, + order_by: Literal["name", "createdAt", "updatedAt"] | Omit = omit, + order_by_direction: Literal["asc", "desc"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + search: str | Omit = omit, + trigger_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, + ) -> FlowListResponse: + """ + List flows + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._get( + "/flows", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "enabled": enabled, + "order_by": order_by, + "order_by_direction": order_by_direction, + "page": page, + "page_size": page_size, + "search": search, + "trigger_id": trigger_id, + }, + flow_list_params.FlowListParams, + ), + ), + cast_to=FlowListResponse, + ) + + async def delete( + self, + flow_id: str, + *, + # 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, + ) -> FlowDeleteResponse: + """ + Delete a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=FlowDeleteResponse, + ) + + async def clone( + self, + flow_id: str, + *, + 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, + ) -> FlowCloneResponse: + """ + Clone a flow + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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}/clone", flow_id=flow_id), + body=await async_maybe_transform({"name": name}, flow_clone_params.FlowCloneParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FlowCloneResponse, + ) + + +class FlowsResourceWithRawResponse: + def __init__(self, flows: FlowsResource) -> None: + self._flows = flows + + self.create = to_raw_response_wrapper( + flows.create, + ) + self.retrieve = to_raw_response_wrapper( + flows.retrieve, + ) + self.update = to_raw_response_wrapper( + flows.update, + ) + self.list = to_raw_response_wrapper( + flows.list, + ) + self.delete = to_raw_response_wrapper( + flows.delete, + ) + self.clone = to_raw_response_wrapper( + flows.clone, + ) + + @cached_property + def actions(self) -> ActionsResourceWithRawResponse: + return ActionsResourceWithRawResponse(self._flows.actions) + + +class AsyncFlowsResourceWithRawResponse: + def __init__(self, flows: AsyncFlowsResource) -> None: + self._flows = flows + + self.create = async_to_raw_response_wrapper( + flows.create, + ) + self.retrieve = async_to_raw_response_wrapper( + flows.retrieve, + ) + self.update = async_to_raw_response_wrapper( + flows.update, + ) + self.list = async_to_raw_response_wrapper( + flows.list, + ) + self.delete = async_to_raw_response_wrapper( + flows.delete, + ) + self.clone = async_to_raw_response_wrapper( + flows.clone, + ) + + @cached_property + def actions(self) -> AsyncActionsResourceWithRawResponse: + return AsyncActionsResourceWithRawResponse(self._flows.actions) + + +class FlowsResourceWithStreamingResponse: + def __init__(self, flows: FlowsResource) -> None: + self._flows = flows + + self.create = to_streamed_response_wrapper( + flows.create, + ) + self.retrieve = to_streamed_response_wrapper( + flows.retrieve, + ) + self.update = to_streamed_response_wrapper( + flows.update, + ) + self.list = to_streamed_response_wrapper( + flows.list, + ) + self.delete = to_streamed_response_wrapper( + flows.delete, + ) + self.clone = to_streamed_response_wrapper( + flows.clone, + ) + + @cached_property + def actions(self) -> ActionsResourceWithStreamingResponse: + return ActionsResourceWithStreamingResponse(self._flows.actions) + + +class AsyncFlowsResourceWithStreamingResponse: + def __init__(self, flows: AsyncFlowsResource) -> None: + self._flows = flows + + self.create = async_to_streamed_response_wrapper( + flows.create, + ) + self.retrieve = async_to_streamed_response_wrapper( + flows.retrieve, + ) + self.update = async_to_streamed_response_wrapper( + flows.update, + ) + self.list = async_to_streamed_response_wrapper( + flows.list, + ) + self.delete = async_to_streamed_response_wrapper( + flows.delete, + ) + self.clone = async_to_streamed_response_wrapper( + flows.clone, + ) + + @cached_property + def actions(self) -> AsyncActionsResourceWithStreamingResponse: + return AsyncActionsResourceWithStreamingResponse(self._flows.actions) diff --git a/src/mobilerun_sdk/resources/workflows/secrets.py b/src/mobilerun_sdk/resources/workflows/secrets.py new file mode 100644 index 0000000..04f2e00 --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/secrets.py @@ -0,0 +1,311 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ..._utils import path_template, maybe_transform, async_maybe_transform +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._base_client import make_request_options +from ...types.workflows import secret_create_params +from ...types.workflows.secret_list_response import SecretListResponse +from ...types.workflows.secret_create_response import SecretCreateResponse +from ...types.workflows.secret_delete_response import SecretDeleteResponse + +__all__ = ["SecretsResource", "AsyncSecretsResource"] + + +class SecretsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> SecretsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return SecretsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> SecretsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return SecretsResourceWithStreamingResponse(self) + + def create( + self, + *, + name: str, + value: str, + description: 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, + ) -> SecretCreateResponse: + """ + Create a user secret (write-only; value cannot be read back) + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/secrets", + body=maybe_transform( + { + "name": name, + "value": value, + "description": description, + }, + secret_create_params.SecretCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SecretCreateResponse, + ) + + def list( + self, + *, + # 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, + ) -> SecretListResponse: + """List user secrets (metadata only — values never returned)""" + return self._get( + "/secrets", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SecretListResponse, + ) + + def delete( + self, + secret_id: str, + *, + # 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, + ) -> SecretDeleteResponse: + """ + Delete a user secret + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not secret_id: + raise ValueError(f"Expected a non-empty value for `secret_id` but received {secret_id!r}") + return self._delete( + path_template("/secrets/{secret_id}", secret_id=secret_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SecretDeleteResponse, + ) + + +class AsyncSecretsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncSecretsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncSecretsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncSecretsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncSecretsResourceWithStreamingResponse(self) + + async def create( + self, + *, + name: str, + value: str, + description: 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, + ) -> SecretCreateResponse: + """ + Create a user secret (write-only; value cannot be read back) + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/secrets", + body=await async_maybe_transform( + { + "name": name, + "value": value, + "description": description, + }, + secret_create_params.SecretCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SecretCreateResponse, + ) + + async def list( + self, + *, + # 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, + ) -> SecretListResponse: + """List user secrets (metadata only — values never returned)""" + return await self._get( + "/secrets", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SecretListResponse, + ) + + async def delete( + self, + secret_id: str, + *, + # 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, + ) -> SecretDeleteResponse: + """ + Delete a user secret + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not secret_id: + raise ValueError(f"Expected a non-empty value for `secret_id` but received {secret_id!r}") + return await self._delete( + path_template("/secrets/{secret_id}", secret_id=secret_id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SecretDeleteResponse, + ) + + +class SecretsResourceWithRawResponse: + def __init__(self, secrets: SecretsResource) -> None: + self._secrets = secrets + + self.create = to_raw_response_wrapper( + secrets.create, + ) + self.list = to_raw_response_wrapper( + secrets.list, + ) + self.delete = to_raw_response_wrapper( + secrets.delete, + ) + + +class AsyncSecretsResourceWithRawResponse: + def __init__(self, secrets: AsyncSecretsResource) -> None: + self._secrets = secrets + + self.create = async_to_raw_response_wrapper( + secrets.create, + ) + self.list = async_to_raw_response_wrapper( + secrets.list, + ) + self.delete = async_to_raw_response_wrapper( + secrets.delete, + ) + + +class SecretsResourceWithStreamingResponse: + def __init__(self, secrets: SecretsResource) -> None: + self._secrets = secrets + + self.create = to_streamed_response_wrapper( + secrets.create, + ) + self.list = to_streamed_response_wrapper( + secrets.list, + ) + self.delete = to_streamed_response_wrapper( + secrets.delete, + ) + + +class AsyncSecretsResourceWithStreamingResponse: + def __init__(self, secrets: AsyncSecretsResource) -> None: + self._secrets = secrets + + self.create = async_to_streamed_response_wrapper( + secrets.create, + ) + self.list = async_to_streamed_response_wrapper( + secrets.list, + ) + self.delete = async_to_streamed_response_wrapper( + secrets.delete, + ) diff --git a/src/mobilerun_sdk/resources/workflows/timezones.py b/src/mobilerun_sdk/resources/workflows/timezones.py new file mode 100644 index 0000000..5b7e797 --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/timezones.py @@ -0,0 +1,135 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ..._types import Body, Query, Headers, NotGiven, not_given +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._base_client import make_request_options +from ...types.workflows.timezone_list_response import TimezoneListResponse + +__all__ = ["TimezonesResource", "AsyncTimezonesResource"] + + +class TimezonesResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> TimezonesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return TimezonesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> TimezonesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return TimezonesResourceWithStreamingResponse(self) + + def list( + self, + *, + # 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, + ) -> TimezoneListResponse: + """List supported IANA timezones""" + return self._get( + "/timezones", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TimezoneListResponse, + ) + + +class AsyncTimezonesResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncTimezonesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncTimezonesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncTimezonesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncTimezonesResourceWithStreamingResponse(self) + + async def list( + self, + *, + # 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, + ) -> TimezoneListResponse: + """List supported IANA timezones""" + return await self._get( + "/timezones", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TimezoneListResponse, + ) + + +class TimezonesResourceWithRawResponse: + def __init__(self, timezones: TimezonesResource) -> None: + self._timezones = timezones + + self.list = to_raw_response_wrapper( + timezones.list, + ) + + +class AsyncTimezonesResourceWithRawResponse: + def __init__(self, timezones: AsyncTimezonesResource) -> None: + self._timezones = timezones + + self.list = async_to_raw_response_wrapper( + timezones.list, + ) + + +class TimezonesResourceWithStreamingResponse: + def __init__(self, timezones: TimezonesResource) -> None: + self._timezones = timezones + + self.list = to_streamed_response_wrapper( + timezones.list, + ) + + +class AsyncTimezonesResourceWithStreamingResponse: + def __init__(self, timezones: AsyncTimezonesResource) -> None: + self._timezones = timezones + + self.list = async_to_streamed_response_wrapper( + timezones.list, + ) diff --git a/src/mobilerun_sdk/resources/workflows/triggers.py b/src/mobilerun_sdk/resources/workflows/triggers.py new file mode 100644 index 0000000..99ed8c3 --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/triggers.py @@ -0,0 +1,753 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Optional +from typing_extensions import Literal + +import httpx + +from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ..._utils import path_template, maybe_transform, async_maybe_transform +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._base_client import make_request_options +from ...types.workflows import trigger_fire_params, trigger_list_params, trigger_create_params, trigger_update_params +from ...types.workflows.trigger_fire_response import TriggerFireResponse +from ...types.workflows.trigger_list_response import TriggerListResponse +from ...types.workflows.trigger_create_response import TriggerCreateResponse +from ...types.workflows.trigger_delete_response import TriggerDeleteResponse +from ...types.workflows.trigger_update_response import TriggerUpdateResponse +from ...types.workflows.trigger_retrieve_response import TriggerRetrieveResponse + +__all__ = ["TriggersResource", "AsyncTriggersResource"] + + +class TriggersResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> TriggersResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return TriggersResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> TriggersResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return TriggersResourceWithStreamingResponse(self) + + def create( + self, + *, + activation: Literal["event", "schedule", "custom"], + name: str, + conditions: trigger_create_params.Conditions | Omit = omit, + custom_payload_schema: Dict[str, object] | Omit = omit, + description: str | Omit = omit, + event_type: str | Omit = omit, + schedule_rule: trigger_create_params.ScheduleRule | Omit = omit, + timezone: 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, + ) -> TriggerCreateResponse: + """ + Create a trigger + + Args: + custom_payload_schema: Optional JSON Schema for validating payloads sent to this custom trigger + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/triggers", + body=maybe_transform( + { + "activation": activation, + "name": name, + "conditions": conditions, + "custom_payload_schema": custom_payload_schema, + "description": description, + "event_type": event_type, + "schedule_rule": schedule_rule, + "timezone": timezone, + }, + trigger_create_params.TriggerCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TriggerCreateResponse, + ) + + def retrieve( + self, + trigger_id: str, + *, + # 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, + ) -> TriggerRetrieveResponse: + """ + Get a trigger + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not trigger_id: + raise ValueError(f"Expected a non-empty value for `trigger_id` but received {trigger_id!r}") + return self._get( + 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 + ), + cast_to=TriggerRetrieveResponse, + ) + + def update( + self, + trigger_id: str, + *, + activation: Literal["event", "schedule", "custom"] | Omit = omit, + conditions: trigger_update_params.Conditions | Omit = omit, + custom_payload_schema: Optional[Dict[str, object]] | Omit = omit, + description: str | Omit = omit, + event_type: str | Omit = omit, + name: str | Omit = omit, + schedule_rule: trigger_update_params.ScheduleRule | Omit = omit, + timezone: Optional[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, + ) -> TriggerUpdateResponse: + """ + Update a trigger + + Args: + custom_payload_schema: Optional JSON Schema for validating payloads sent to this custom trigger + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not trigger_id: + raise ValueError(f"Expected a non-empty value for `trigger_id` but received {trigger_id!r}") + return self._patch( + path_template("/triggers/{trigger_id}", trigger_id=trigger_id), + body=maybe_transform( + { + "activation": activation, + "conditions": conditions, + "custom_payload_schema": custom_payload_schema, + "description": description, + "event_type": event_type, + "name": name, + "schedule_rule": schedule_rule, + "timezone": timezone, + }, + trigger_update_params.TriggerUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TriggerUpdateResponse, + ) + + def list( + self, + *, + activation: Literal["event", "schedule", "custom"] | Omit = omit, + event_type: str | Omit = omit, + order_by: Literal["name", "createdAt", "updatedAt"] | Omit = omit, + order_by_direction: Literal["asc", "desc"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + search: 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, + ) -> TriggerListResponse: + """ + List triggers + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get( + "/triggers", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "activation": activation, + "event_type": event_type, + "order_by": order_by, + "order_by_direction": order_by_direction, + "page": page, + "page_size": page_size, + "search": search, + }, + trigger_list_params.TriggerListParams, + ), + ), + cast_to=TriggerListResponse, + ) + + def delete( + self, + trigger_id: str, + *, + # 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, + ) -> TriggerDeleteResponse: + """ + Delete a trigger + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=TriggerDeleteResponse, + ) + + def fire( + self, + trigger_id: str, + *, + payload: Dict[str, object], + device_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, + ) -> TriggerFireResponse: + """ + Invoke a custom trigger directly with an arbitrary JSON payload. + + Fan-out: a trigger may be referenced by multiple flows (workflows). Firing it + enqueues one execution per enabled, non-deleted flow attached to this trigger, + each receiving the same payload. The `enqueuedCount` in the response reports how + many were enqueued (0 if no flows are attached, or if all matching flows are + gated by a cooldown). + + Payload validation: + + - If the trigger has a `customPayloadSchema`, the payload is validated against + it (JSON Schema via AJV). + - If no schema is configured, the payload only needs to be a JSON object — any + keys and values are accepted. + + Only triggers with `activation = "custom"` can be fired through this endpoint; + event and schedule triggers return 409. + + Args: + payload: Arbitrary JSON object forwarded to every flow attached to this trigger. + Validated against the trigger's customPayloadSchema when one is configured; + otherwise only "must be a JSON object" is enforced. + + device_id: Optional device scope. When supplied, ownership is verified for the calling user + and the value is passed through to each enqueued execution as the default device + context. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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, + "device_id": device_id, + }, + trigger_fire_params.TriggerFireParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TriggerFireResponse, + ) + + +class AsyncTriggersResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncTriggersResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncTriggersResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncTriggersResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncTriggersResourceWithStreamingResponse(self) + + async def create( + self, + *, + activation: Literal["event", "schedule", "custom"], + name: str, + conditions: trigger_create_params.Conditions | Omit = omit, + custom_payload_schema: Dict[str, object] | Omit = omit, + description: str | Omit = omit, + event_type: str | Omit = omit, + schedule_rule: trigger_create_params.ScheduleRule | Omit = omit, + timezone: 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, + ) -> TriggerCreateResponse: + """ + Create a trigger + + Args: + custom_payload_schema: Optional JSON Schema for validating payloads sent to this custom trigger + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/triggers", + body=await async_maybe_transform( + { + "activation": activation, + "name": name, + "conditions": conditions, + "custom_payload_schema": custom_payload_schema, + "description": description, + "event_type": event_type, + "schedule_rule": schedule_rule, + "timezone": timezone, + }, + trigger_create_params.TriggerCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TriggerCreateResponse, + ) + + async def retrieve( + self, + trigger_id: str, + *, + # 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, + ) -> TriggerRetrieveResponse: + """ + Get a trigger + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not trigger_id: + raise ValueError(f"Expected a non-empty value for `trigger_id` but received {trigger_id!r}") + return await self._get( + 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 + ), + cast_to=TriggerRetrieveResponse, + ) + + async def update( + self, + trigger_id: str, + *, + activation: Literal["event", "schedule", "custom"] | Omit = omit, + conditions: trigger_update_params.Conditions | Omit = omit, + custom_payload_schema: Optional[Dict[str, object]] | Omit = omit, + description: str | Omit = omit, + event_type: str | Omit = omit, + name: str | Omit = omit, + schedule_rule: trigger_update_params.ScheduleRule | Omit = omit, + timezone: Optional[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, + ) -> TriggerUpdateResponse: + """ + Update a trigger + + Args: + custom_payload_schema: Optional JSON Schema for validating payloads sent to this custom trigger + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not trigger_id: + raise ValueError(f"Expected a non-empty value for `trigger_id` but received {trigger_id!r}") + return await self._patch( + path_template("/triggers/{trigger_id}", trigger_id=trigger_id), + body=await async_maybe_transform( + { + "activation": activation, + "conditions": conditions, + "custom_payload_schema": custom_payload_schema, + "description": description, + "event_type": event_type, + "name": name, + "schedule_rule": schedule_rule, + "timezone": timezone, + }, + trigger_update_params.TriggerUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TriggerUpdateResponse, + ) + + async def list( + self, + *, + activation: Literal["event", "schedule", "custom"] | Omit = omit, + event_type: str | Omit = omit, + order_by: Literal["name", "createdAt", "updatedAt"] | Omit = omit, + order_by_direction: Literal["asc", "desc"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + search: 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, + ) -> TriggerListResponse: + """ + List triggers + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._get( + "/triggers", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "activation": activation, + "event_type": event_type, + "order_by": order_by, + "order_by_direction": order_by_direction, + "page": page, + "page_size": page_size, + "search": search, + }, + trigger_list_params.TriggerListParams, + ), + ), + cast_to=TriggerListResponse, + ) + + async def delete( + self, + trigger_id: str, + *, + # 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, + ) -> TriggerDeleteResponse: + """ + Delete a trigger + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=TriggerDeleteResponse, + ) + + async def fire( + self, + trigger_id: str, + *, + payload: Dict[str, object], + device_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, + ) -> TriggerFireResponse: + """ + Invoke a custom trigger directly with an arbitrary JSON payload. + + Fan-out: a trigger may be referenced by multiple flows (workflows). Firing it + enqueues one execution per enabled, non-deleted flow attached to this trigger, + each receiving the same payload. The `enqueuedCount` in the response reports how + many were enqueued (0 if no flows are attached, or if all matching flows are + gated by a cooldown). + + Payload validation: + + - If the trigger has a `customPayloadSchema`, the payload is validated against + it (JSON Schema via AJV). + - If no schema is configured, the payload only needs to be a JSON object — any + keys and values are accepted. + + Only triggers with `activation = "custom"` can be fired through this endpoint; + event and schedule triggers return 409. + + Args: + payload: Arbitrary JSON object forwarded to every flow attached to this trigger. + Validated against the trigger's customPayloadSchema when one is configured; + otherwise only "must be a JSON object" is enforced. + + device_id: Optional device scope. When supplied, ownership is verified for the calling user + and the value is passed through to each enqueued execution as the default device + context. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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, + "device_id": device_id, + }, + trigger_fire_params.TriggerFireParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TriggerFireResponse, + ) + + +class TriggersResourceWithRawResponse: + def __init__(self, triggers: TriggersResource) -> None: + self._triggers = triggers + + self.create = to_raw_response_wrapper( + triggers.create, + ) + self.retrieve = to_raw_response_wrapper( + triggers.retrieve, + ) + self.update = to_raw_response_wrapper( + triggers.update, + ) + self.list = to_raw_response_wrapper( + triggers.list, + ) + self.delete = to_raw_response_wrapper( + triggers.delete, + ) + self.fire = to_raw_response_wrapper( + triggers.fire, + ) + + +class AsyncTriggersResourceWithRawResponse: + def __init__(self, triggers: AsyncTriggersResource) -> None: + self._triggers = triggers + + self.create = async_to_raw_response_wrapper( + triggers.create, + ) + self.retrieve = async_to_raw_response_wrapper( + triggers.retrieve, + ) + self.update = async_to_raw_response_wrapper( + triggers.update, + ) + self.list = async_to_raw_response_wrapper( + triggers.list, + ) + self.delete = async_to_raw_response_wrapper( + triggers.delete, + ) + self.fire = async_to_raw_response_wrapper( + triggers.fire, + ) + + +class TriggersResourceWithStreamingResponse: + def __init__(self, triggers: TriggersResource) -> None: + self._triggers = triggers + + self.create = to_streamed_response_wrapper( + triggers.create, + ) + self.retrieve = to_streamed_response_wrapper( + triggers.retrieve, + ) + self.update = to_streamed_response_wrapper( + triggers.update, + ) + self.list = to_streamed_response_wrapper( + triggers.list, + ) + self.delete = to_streamed_response_wrapper( + triggers.delete, + ) + self.fire = to_streamed_response_wrapper( + triggers.fire, + ) + + +class AsyncTriggersResourceWithStreamingResponse: + def __init__(self, triggers: AsyncTriggersResource) -> None: + self._triggers = triggers + + self.create = async_to_streamed_response_wrapper( + triggers.create, + ) + self.retrieve = async_to_streamed_response_wrapper( + triggers.retrieve, + ) + self.update = async_to_streamed_response_wrapper( + triggers.update, + ) + self.list = async_to_streamed_response_wrapper( + triggers.list, + ) + self.delete = async_to_streamed_response_wrapper( + triggers.delete, + ) + self.fire = async_to_streamed_response_wrapper( + triggers.fire, + ) diff --git a/src/mobilerun_sdk/resources/workflows/workflows.py b/src/mobilerun_sdk/resources/workflows/workflows.py new file mode 100644 index 0000000..75a9afa --- /dev/null +++ b/src/mobilerun_sdk/resources/workflows/workflows.py @@ -0,0 +1,326 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .secrets import ( + SecretsResource, + AsyncSecretsResource, + SecretsResourceWithRawResponse, + AsyncSecretsResourceWithRawResponse, + SecretsResourceWithStreamingResponse, + AsyncSecretsResourceWithStreamingResponse, +) +from .triggers import ( + TriggersResource, + AsyncTriggersResource, + TriggersResourceWithRawResponse, + AsyncTriggersResourceWithRawResponse, + TriggersResourceWithStreamingResponse, + AsyncTriggersResourceWithStreamingResponse, +) +from ..._compat import cached_property +from .timezones import ( + TimezonesResource, + AsyncTimezonesResource, + TimezonesResourceWithRawResponse, + AsyncTimezonesResourceWithRawResponse, + TimezonesResourceWithStreamingResponse, + AsyncTimezonesResourceWithStreamingResponse, +) +from .executions import ( + ExecutionsResource, + AsyncExecutionsResource, + ExecutionsResourceWithRawResponse, + AsyncExecutionsResourceWithRawResponse, + ExecutionsResourceWithStreamingResponse, + AsyncExecutionsResourceWithStreamingResponse, +) +from ..._resource import SyncAPIResource, AsyncAPIResource +from .flows.flows import ( + FlowsResource, + AsyncFlowsResource, + FlowsResourceWithRawResponse, + AsyncFlowsResourceWithRawResponse, + FlowsResourceWithStreamingResponse, + AsyncFlowsResourceWithStreamingResponse, +) +from .events.events import ( + EventsResource, + AsyncEventsResource, + EventsResourceWithRawResponse, + AsyncEventsResourceWithRawResponse, + EventsResourceWithStreamingResponse, + AsyncEventsResourceWithStreamingResponse, +) +from .action_catalog import ( + ActionCatalogResource, + AsyncActionCatalogResource, + ActionCatalogResourceWithRawResponse, + AsyncActionCatalogResourceWithRawResponse, + ActionCatalogResourceWithStreamingResponse, + AsyncActionCatalogResourceWithStreamingResponse, +) +from .actions.actions import ( + ActionsResource, + AsyncActionsResource, + ActionsResourceWithRawResponse, + AsyncActionsResourceWithRawResponse, + ActionsResourceWithStreamingResponse, + AsyncActionsResourceWithStreamingResponse, +) + +__all__ = ["WorkflowsResource", "AsyncWorkflowsResource"] + + +class WorkflowsResource(SyncAPIResource): + @cached_property + def triggers(self) -> TriggersResource: + return TriggersResource(self._client) + + @cached_property + def action_catalog(self) -> ActionCatalogResource: + return ActionCatalogResource(self._client) + + @cached_property + def actions(self) -> ActionsResource: + return ActionsResource(self._client) + + @cached_property + def flows(self) -> FlowsResource: + return FlowsResource(self._client) + + @cached_property + def events(self) -> EventsResource: + return EventsResource(self._client) + + @cached_property + def executions(self) -> ExecutionsResource: + return ExecutionsResource(self._client) + + @cached_property + def timezones(self) -> TimezonesResource: + return TimezonesResource(self._client) + + @cached_property + def secrets(self) -> SecretsResource: + return SecretsResource(self._client) + + @cached_property + def with_raw_response(self) -> WorkflowsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return WorkflowsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> WorkflowsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return WorkflowsResourceWithStreamingResponse(self) + + +class AsyncWorkflowsResource(AsyncAPIResource): + @cached_property + def triggers(self) -> AsyncTriggersResource: + return AsyncTriggersResource(self._client) + + @cached_property + def action_catalog(self) -> AsyncActionCatalogResource: + return AsyncActionCatalogResource(self._client) + + @cached_property + def actions(self) -> AsyncActionsResource: + return AsyncActionsResource(self._client) + + @cached_property + def flows(self) -> AsyncFlowsResource: + return AsyncFlowsResource(self._client) + + @cached_property + def events(self) -> AsyncEventsResource: + return AsyncEventsResource(self._client) + + @cached_property + def executions(self) -> AsyncExecutionsResource: + return AsyncExecutionsResource(self._client) + + @cached_property + def timezones(self) -> AsyncTimezonesResource: + return AsyncTimezonesResource(self._client) + + @cached_property + def secrets(self) -> AsyncSecretsResource: + return AsyncSecretsResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncWorkflowsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncWorkflowsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncWorkflowsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncWorkflowsResourceWithStreamingResponse(self) + + +class WorkflowsResourceWithRawResponse: + def __init__(self, workflows: WorkflowsResource) -> None: + self._workflows = workflows + + @cached_property + def triggers(self) -> TriggersResourceWithRawResponse: + return TriggersResourceWithRawResponse(self._workflows.triggers) + + @cached_property + def action_catalog(self) -> ActionCatalogResourceWithRawResponse: + return ActionCatalogResourceWithRawResponse(self._workflows.action_catalog) + + @cached_property + def actions(self) -> ActionsResourceWithRawResponse: + return ActionsResourceWithRawResponse(self._workflows.actions) + + @cached_property + def flows(self) -> FlowsResourceWithRawResponse: + return FlowsResourceWithRawResponse(self._workflows.flows) + + @cached_property + def events(self) -> EventsResourceWithRawResponse: + return EventsResourceWithRawResponse(self._workflows.events) + + @cached_property + def executions(self) -> ExecutionsResourceWithRawResponse: + return ExecutionsResourceWithRawResponse(self._workflows.executions) + + @cached_property + def timezones(self) -> TimezonesResourceWithRawResponse: + return TimezonesResourceWithRawResponse(self._workflows.timezones) + + @cached_property + def secrets(self) -> SecretsResourceWithRawResponse: + return SecretsResourceWithRawResponse(self._workflows.secrets) + + +class AsyncWorkflowsResourceWithRawResponse: + def __init__(self, workflows: AsyncWorkflowsResource) -> None: + self._workflows = workflows + + @cached_property + def triggers(self) -> AsyncTriggersResourceWithRawResponse: + return AsyncTriggersResourceWithRawResponse(self._workflows.triggers) + + @cached_property + def action_catalog(self) -> AsyncActionCatalogResourceWithRawResponse: + return AsyncActionCatalogResourceWithRawResponse(self._workflows.action_catalog) + + @cached_property + def actions(self) -> AsyncActionsResourceWithRawResponse: + return AsyncActionsResourceWithRawResponse(self._workflows.actions) + + @cached_property + def flows(self) -> AsyncFlowsResourceWithRawResponse: + return AsyncFlowsResourceWithRawResponse(self._workflows.flows) + + @cached_property + def events(self) -> AsyncEventsResourceWithRawResponse: + return AsyncEventsResourceWithRawResponse(self._workflows.events) + + @cached_property + def executions(self) -> AsyncExecutionsResourceWithRawResponse: + return AsyncExecutionsResourceWithRawResponse(self._workflows.executions) + + @cached_property + def timezones(self) -> AsyncTimezonesResourceWithRawResponse: + return AsyncTimezonesResourceWithRawResponse(self._workflows.timezones) + + @cached_property + def secrets(self) -> AsyncSecretsResourceWithRawResponse: + return AsyncSecretsResourceWithRawResponse(self._workflows.secrets) + + +class WorkflowsResourceWithStreamingResponse: + def __init__(self, workflows: WorkflowsResource) -> None: + self._workflows = workflows + + @cached_property + def triggers(self) -> TriggersResourceWithStreamingResponse: + return TriggersResourceWithStreamingResponse(self._workflows.triggers) + + @cached_property + def action_catalog(self) -> ActionCatalogResourceWithStreamingResponse: + return ActionCatalogResourceWithStreamingResponse(self._workflows.action_catalog) + + @cached_property + def actions(self) -> ActionsResourceWithStreamingResponse: + return ActionsResourceWithStreamingResponse(self._workflows.actions) + + @cached_property + def flows(self) -> FlowsResourceWithStreamingResponse: + return FlowsResourceWithStreamingResponse(self._workflows.flows) + + @cached_property + def events(self) -> EventsResourceWithStreamingResponse: + return EventsResourceWithStreamingResponse(self._workflows.events) + + @cached_property + def executions(self) -> ExecutionsResourceWithStreamingResponse: + return ExecutionsResourceWithStreamingResponse(self._workflows.executions) + + @cached_property + def timezones(self) -> TimezonesResourceWithStreamingResponse: + return TimezonesResourceWithStreamingResponse(self._workflows.timezones) + + @cached_property + def secrets(self) -> SecretsResourceWithStreamingResponse: + return SecretsResourceWithStreamingResponse(self._workflows.secrets) + + +class AsyncWorkflowsResourceWithStreamingResponse: + def __init__(self, workflows: AsyncWorkflowsResource) -> None: + self._workflows = workflows + + @cached_property + def triggers(self) -> AsyncTriggersResourceWithStreamingResponse: + return AsyncTriggersResourceWithStreamingResponse(self._workflows.triggers) + + @cached_property + def action_catalog(self) -> AsyncActionCatalogResourceWithStreamingResponse: + return AsyncActionCatalogResourceWithStreamingResponse(self._workflows.action_catalog) + + @cached_property + def actions(self) -> AsyncActionsResourceWithStreamingResponse: + return AsyncActionsResourceWithStreamingResponse(self._workflows.actions) + + @cached_property + def flows(self) -> AsyncFlowsResourceWithStreamingResponse: + return AsyncFlowsResourceWithStreamingResponse(self._workflows.flows) + + @cached_property + def events(self) -> AsyncEventsResourceWithStreamingResponse: + return AsyncEventsResourceWithStreamingResponse(self._workflows.events) + + @cached_property + def executions(self) -> AsyncExecutionsResourceWithStreamingResponse: + return AsyncExecutionsResourceWithStreamingResponse(self._workflows.executions) + + @cached_property + def timezones(self) -> AsyncTimezonesResourceWithStreamingResponse: + return AsyncTimezonesResourceWithStreamingResponse(self._workflows.timezones) + + @cached_property + def secrets(self) -> AsyncSecretsResourceWithStreamingResponse: + return AsyncSecretsResourceWithStreamingResponse(self._workflows.secrets) diff --git a/src/mobilerun_sdk/types/__init__.py b/src/mobilerun_sdk/types/__init__.py index abff37b..e2f5b3b 100644 --- a/src/mobilerun_sdk/types/__init__.py +++ b/src/mobilerun_sdk/types/__init__.py @@ -2,6 +2,7 @@ from __future__ import annotations +from .flow import Flow as Flow from .task import Task as Task from .device import Device as Device from .shared import ( diff --git a/src/mobilerun_sdk/types/flow.py b/src/mobilerun_sdk/types/flow.py new file mode 100644 index 0000000..98aad0c --- /dev/null +++ b/src/mobilerun_sdk/types/flow.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["Flow"] + + +class Flow(BaseModel): + id: str + + cooldown_scope: Literal["flow", "device"] = FieldInfo(alias="cooldownScope") + + cooldown_seconds: Optional[int] = FieldInfo(alias="cooldownSeconds", default=None) + + created_at: Optional[str] = FieldInfo(alias="createdAt", default=None) + + description: Optional[str] = None + + enabled: bool + + last_triggered_at: Optional[str] = FieldInfo(alias="lastTriggeredAt", default=None) + + name: str + + trigger_id: str = FieldInfo(alias="triggerId") + + updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) + + user_id: str = FieldInfo(alias="userId") diff --git a/src/mobilerun_sdk/types/workflows/__init__.py b/src/mobilerun_sdk/types/workflows/__init__.py new file mode 100644 index 0000000..85513bc --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/__init__.py @@ -0,0 +1,55 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .action import Action as Action +from .user_secret import UserSecret as UserSecret +from .flow_execution import FlowExecution as FlowExecution +from .flow_list_params import FlowListParams as FlowListParams +from .flow_clone_params import FlowCloneParams as FlowCloneParams +from .action_list_params import ActionListParams as ActionListParams +from .flow_create_params import FlowCreateParams as FlowCreateParams +from .flow_list_response import FlowListResponse as FlowListResponse +from .flow_update_params import FlowUpdateParams as FlowUpdateParams +from .event_ingest_params import EventIngestParams as EventIngestParams +from .flow_clone_response import FlowCloneResponse as FlowCloneResponse +from .trigger_fire_params import TriggerFireParams as TriggerFireParams +from .trigger_list_params import TriggerListParams as TriggerListParams +from .action_catalog_entry import ActionCatalogEntry as ActionCatalogEntry +from .action_create_params import ActionCreateParams as ActionCreateParams +from .action_list_response import ActionListResponse as ActionListResponse +from .action_update_params import ActionUpdateParams as ActionUpdateParams +from .event_dry_run_params import EventDryRunParams as EventDryRunParams +from .flow_create_response import FlowCreateResponse as FlowCreateResponse +from .flow_delete_response import FlowDeleteResponse as FlowDeleteResponse +from .flow_update_response import FlowUpdateResponse as FlowUpdateResponse +from .secret_create_params import SecretCreateParams as SecretCreateParams +from .secret_list_response import SecretListResponse as SecretListResponse +from .event_ingest_response import EventIngestResponse as EventIngestResponse +from .execution_list_params import ExecutionListParams as ExecutionListParams +from .trigger_create_params import TriggerCreateParams as TriggerCreateParams +from .trigger_fire_response import TriggerFireResponse as TriggerFireResponse +from .trigger_list_response import TriggerListResponse as TriggerListResponse +from .trigger_update_params import TriggerUpdateParams as TriggerUpdateParams +from .action_create_response import ActionCreateResponse as ActionCreateResponse +from .action_delete_response import ActionDeleteResponse as ActionDeleteResponse +from .action_update_response import ActionUpdateResponse as ActionUpdateResponse +from .event_dry_run_response import EventDryRunResponse as EventDryRunResponse +from .flow_retrieve_response import FlowRetrieveResponse as FlowRetrieveResponse +from .secret_create_response import SecretCreateResponse as SecretCreateResponse +from .secret_delete_response import SecretDeleteResponse as SecretDeleteResponse +from .timezone_list_response import TimezoneListResponse as TimezoneListResponse +from .execution_list_response import ExecutionListResponse as ExecutionListResponse +from .trigger_create_response import TriggerCreateResponse as TriggerCreateResponse +from .trigger_delete_response import TriggerDeleteResponse as TriggerDeleteResponse +from .trigger_update_response import TriggerUpdateResponse as TriggerUpdateResponse +from .action_retrieve_response import ActionRetrieveResponse as ActionRetrieveResponse +from .trigger_retrieve_response import TriggerRetrieveResponse as TriggerRetrieveResponse +from .action_catalog_list_params import ActionCatalogListParams as ActionCatalogListParams +from .execution_retrieve_response import ExecutionRetrieveResponse as ExecutionRetrieveResponse +from .flow_action_overrides_param import FlowActionOverridesParam as FlowActionOverridesParam +from .action_catalog_list_response import ActionCatalogListResponse as ActionCatalogListResponse +from .execution_get_metrics_params import ExecutionGetMetricsParams as ExecutionGetMetricsParams +from .flow_child_action_input_param import FlowChildActionInputParam as FlowChildActionInputParam +from .execution_get_metrics_response import ExecutionGetMetricsResponse as ExecutionGetMetricsResponse +from .action_catalog_retrieve_response import ActionCatalogRetrieveResponse as ActionCatalogRetrieveResponse diff --git a/src/mobilerun_sdk/types/workflows/action.py b/src/mobilerun_sdk/types/workflows/action.py new file mode 100644 index 0000000..fb111f1 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/action.py @@ -0,0 +1,36 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["Action"] + + +class Action(BaseModel): + id: str + + catalog_entry_id: str = FieldInfo(alias="catalogEntryId") + + created_at: Optional[str] = FieldInfo(alias="createdAt", default=None) + + description: Optional[str] = None + + is_async: bool = FieldInfo(alias="isAsync") + + method: str + + name: str + + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] + + updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) + + user_id: str = FieldInfo(alias="userId") + + params: Optional[object] = None + + params_schema: Optional[object] = FieldInfo(alias="paramsSchema", default=None) diff --git a/src/mobilerun_sdk/types/workflows/action_catalog_entry.py b/src/mobilerun_sdk/types/workflows/action_catalog_entry.py new file mode 100644 index 0000000..4eb711f --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/action_catalog_entry.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["ActionCatalogEntry"] + + +class ActionCatalogEntry(BaseModel): + id: str + + created_at: Optional[str] = FieldInfo(alias="createdAt", default=None) + + description: Optional[str] = None + + is_async: bool = FieldInfo(alias="isAsync") + + method: str + + name: str + + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] + + updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) + + params_schema: Optional[object] = FieldInfo(alias="paramsSchema", default=None) diff --git a/src/mobilerun_sdk/types/workflows/action_catalog_list_params.py b/src/mobilerun_sdk/types/workflows/action_catalog_list_params.py new file mode 100644 index 0000000..4e756a9 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/action_catalog_list_params.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["ActionCatalogListParams"] + + +class ActionCatalogListParams(TypedDict, total=False): + page: int + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] diff --git a/src/mobilerun_sdk/types/workflows/action_catalog_list_response.py b/src/mobilerun_sdk/types/workflows/action_catalog_list_response.py new file mode 100644 index 0000000..967cfd0 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/action_catalog_list_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ..._models import BaseModel +from ..shared.pagination import Pagination +from .action_catalog_entry import ActionCatalogEntry + +__all__ = ["ActionCatalogListResponse"] + + +class ActionCatalogListResponse(BaseModel): + items: List[ActionCatalogEntry] + + pagination: Pagination diff --git a/src/mobilerun_sdk/types/workflows/action_catalog_retrieve_response.py b/src/mobilerun_sdk/types/workflows/action_catalog_retrieve_response.py new file mode 100644 index 0000000..81d1b5f --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/action_catalog_retrieve_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..._models import BaseModel +from .action_catalog_entry import ActionCatalogEntry + +__all__ = ["ActionCatalogRetrieveResponse"] + + +class ActionCatalogRetrieveResponse(BaseModel): + data: ActionCatalogEntry diff --git a/src/mobilerun_sdk/types/workflows/action_create_params.py b/src/mobilerun_sdk/types/workflows/action_create_params.py new file mode 100644 index 0000000..b85ffed --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/action_create_params.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Optional +from typing_extensions import Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["ActionCreateParams"] + + +class ActionCreateParams(TypedDict, total=False): + catalog_entry_id: Required[Annotated[str, PropertyInfo(alias="catalogEntryId")]] + + name: Required[str] + + description: str + + params: Dict[str, Optional[object]] diff --git a/src/mobilerun_sdk/types/workflows/action_create_response.py b/src/mobilerun_sdk/types/workflows/action_create_response.py new file mode 100644 index 0000000..acd7aa5 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/action_create_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .action import Action +from ..._models import BaseModel + +__all__ = ["ActionCreateResponse"] + + +class ActionCreateResponse(BaseModel): + data: Action diff --git a/src/mobilerun_sdk/types/workflows/action_delete_response.py b/src/mobilerun_sdk/types/workflows/action_delete_response.py new file mode 100644 index 0000000..157bb1f --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/action_delete_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..._models import BaseModel + +__all__ = ["ActionDeleteResponse"] + + +class ActionDeleteResponse(BaseModel): + message: str diff --git a/src/mobilerun_sdk/types/workflows/action_list_params.py b/src/mobilerun_sdk/types/workflows/action_list_params.py new file mode 100644 index 0000000..9873843 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/action_list_params.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["ActionListParams"] + + +class ActionListParams(TypedDict, total=False): + order_by: Annotated[Literal["name", "createdAt", "updatedAt"], PropertyInfo(alias="orderBy")] + + order_by_direction: Annotated[Literal["asc", "desc"], PropertyInfo(alias="orderByDirection")] + + page: int + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + + search: str + + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] diff --git a/src/mobilerun_sdk/types/workflows/action_list_response.py b/src/mobilerun_sdk/types/workflows/action_list_response.py new file mode 100644 index 0000000..2d5e996 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/action_list_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from .action import Action +from ..._models import BaseModel +from ..shared.pagination import Pagination + +__all__ = ["ActionListResponse"] + + +class ActionListResponse(BaseModel): + items: List[Action] + + pagination: Pagination diff --git a/src/mobilerun_sdk/types/workflows/action_retrieve_response.py b/src/mobilerun_sdk/types/workflows/action_retrieve_response.py new file mode 100644 index 0000000..7dc33b0 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/action_retrieve_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .action import Action +from ..._models import BaseModel + +__all__ = ["ActionRetrieveResponse"] + + +class ActionRetrieveResponse(BaseModel): + data: Action diff --git a/src/mobilerun_sdk/types/workflows/action_update_params.py b/src/mobilerun_sdk/types/workflows/action_update_params.py new file mode 100644 index 0000000..4644bac --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/action_update_params.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Optional +from typing_extensions import TypedDict + +__all__ = ["ActionUpdateParams"] + + +class ActionUpdateParams(TypedDict, total=False): + description: str + + name: str + + params: Dict[str, Optional[object]] diff --git a/src/mobilerun_sdk/types/workflows/action_update_response.py b/src/mobilerun_sdk/types/workflows/action_update_response.py new file mode 100644 index 0000000..4d6b872 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/action_update_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .action import Action +from ..._models import BaseModel + +__all__ = ["ActionUpdateResponse"] + + +class ActionUpdateResponse(BaseModel): + data: Action diff --git a/src/mobilerun_sdk/types/workflows/actions/__init__.py b/src/mobilerun_sdk/types/workflows/actions/__init__.py new file mode 100644 index 0000000..57284e5 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/actions/__init__.py @@ -0,0 +1,6 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .service_list_response import ServiceListResponse as ServiceListResponse +from .service_list_methods_response import ServiceListMethodsResponse as ServiceListMethodsResponse diff --git a/src/mobilerun_sdk/types/workflows/actions/service_list_methods_response.py b/src/mobilerun_sdk/types/workflows/actions/service_list_methods_response.py new file mode 100644 index 0000000..0ebef39 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/actions/service_list_methods_response.py @@ -0,0 +1,38 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ...._models import BaseModel + +__all__ = ["ServiceListMethodsResponse", "Data", "DataParam"] + + +class DataParam(BaseModel): + description: str + + name: str + + required: bool + + type: Literal["string", "number", "boolean", "object", "array"] + + default: Optional[object] = None + + example: Optional[object] = None + + +class Data(BaseModel): + is_async: bool = FieldInfo(alias="isAsync") + + method: str + + params: List[DataParam] + + requires_target: bool = FieldInfo(alias="requiresTarget") + + +class ServiceListMethodsResponse(BaseModel): + data: List[Data] diff --git a/src/mobilerun_sdk/types/workflows/actions/service_list_response.py b/src/mobilerun_sdk/types/workflows/actions/service_list_response.py new file mode 100644 index 0000000..e8e712c --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/actions/service_list_response.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ...._models import BaseModel + +__all__ = ["ServiceListResponse"] + + +class ServiceListResponse(BaseModel): + data: List[str] diff --git a/src/mobilerun_sdk/types/workflows/event_dry_run_params.py b/src/mobilerun_sdk/types/workflows/event_dry_run_params.py new file mode 100644 index 0000000..c55498e --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/event_dry_run_params.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Optional +from typing_extensions import Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["EventDryRunParams"] + + +class EventDryRunParams(TypedDict, total=False): + event_type: Required[Annotated[str, PropertyInfo(alias="eventType")]] + + device_id: Annotated[str, PropertyInfo(alias="deviceId")] + + payload: Dict[str, Optional[object]] diff --git a/src/mobilerun_sdk/types/workflows/event_dry_run_response.py b/src/mobilerun_sdk/types/workflows/event_dry_run_response.py new file mode 100644 index 0000000..13df857 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/event_dry_run_response.py @@ -0,0 +1,105 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..flow import Flow +from ..._models import BaseModel + +__all__ = [ + "EventDryRunResponse", + "Data", + "DataMatchedFlow", + "DataMatchedFlowAction", + "DataMatchedFlowTrigger", + "DataMatchedFlowTriggerScheduleRule", + "DataValidation", + "DataValidationError", +] + + +class DataMatchedFlowAction(BaseModel): + continue_on_error: bool = FieldInfo(alias="continueOnError") + + method: str + + name: str + + service: Literal["tasks_api", "devices_api", "agents_api", "webhooks"] + + device_id: Optional[str] = FieldInfo(alias="deviceId", default=None) + + params: Optional[Dict[str, Optional[object]]] = None + + +class DataMatchedFlowTriggerScheduleRule(BaseModel): + type: Literal["once", "cron", "recurring"] + + date_time: Optional[str] = FieldInfo(alias="dateTime", default=None) + """ISO 8601 datetime (for type=once)""" + + expression: Optional[str] = None + """Cron expression (for type=cron)""" + + rrule: Optional[str] = None + """RRULE string (for type=recurring)""" + + +class DataMatchedFlowTrigger(BaseModel): + id: str + + activation: Literal["event", "schedule", "custom"] + + created_at: Optional[str] = FieldInfo(alias="createdAt", default=None) + + custom_payload_schema: Optional[Dict[str, object]] = FieldInfo(alias="customPayloadSchema", default=None) + + description: Optional[str] = None + + event_type: Optional[str] = FieldInfo(alias="eventType", default=None) + + name: str + + schedule_rule: Optional[DataMatchedFlowTriggerScheduleRule] = FieldInfo(alias="scheduleRule", default=None) + + timezone: Optional[str] = None + + updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) + + user_id: str = FieldInfo(alias="userId") + + conditions: Optional[object] = None + + next_fire_time: Optional[str] = FieldInfo(alias="nextFireTime", default=None) + + +class DataMatchedFlow(BaseModel): + actions: List[DataMatchedFlowAction] + + flow: Flow + + trigger: DataMatchedFlowTrigger + + +class DataValidationError(BaseModel): + field: str + + message: str + + +class DataValidation(BaseModel): + valid: bool + + errors: Optional[List[DataValidationError]] = None + + +class Data(BaseModel): + matched_flows: List[DataMatchedFlow] = FieldInfo(alias="matchedFlows") + + validation: DataValidation + + +class EventDryRunResponse(BaseModel): + data: Data diff --git a/src/mobilerun_sdk/types/workflows/event_ingest_params.py b/src/mobilerun_sdk/types/workflows/event_ingest_params.py new file mode 100644 index 0000000..d8edf19 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/event_ingest_params.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Optional +from typing_extensions import Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["EventIngestParams"] + + +class EventIngestParams(TypedDict, total=False): + event_type: Required[Annotated[str, PropertyInfo(alias="eventType")]] + + device_id: Annotated[str, PropertyInfo(alias="deviceId")] + + payload: Dict[str, Optional[object]] diff --git a/src/mobilerun_sdk/types/workflows/event_ingest_response.py b/src/mobilerun_sdk/types/workflows/event_ingest_response.py new file mode 100644 index 0000000..6136565 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/event_ingest_response.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["EventIngestResponse"] + + +class EventIngestResponse(BaseModel): + event_id: str = FieldInfo(alias="eventId") diff --git a/src/mobilerun_sdk/types/workflows/events/__init__.py b/src/mobilerun_sdk/types/workflows/events/__init__.py new file mode 100644 index 0000000..32807f2 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/events/__init__.py @@ -0,0 +1,8 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .catalog_list_params import CatalogListParams as CatalogListParams +from .catalog_list_response import CatalogListResponse as CatalogListResponse +from .catalog_register_params import CatalogRegisterParams as CatalogRegisterParams +from .catalog_register_response import CatalogRegisterResponse as CatalogRegisterResponse diff --git a/src/mobilerun_sdk/types/workflows/events/catalog_list_params.py b/src/mobilerun_sdk/types/workflows/events/catalog_list_params.py new file mode 100644 index 0000000..ca0def1 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/events/catalog_list_params.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["CatalogListParams"] + + +class CatalogListParams(TypedDict, total=False): + page: int + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + + source: Literal["device", "system", "webhook"] diff --git a/src/mobilerun_sdk/types/workflows/events/catalog_list_response.py b/src/mobilerun_sdk/types/workflows/events/catalog_list_response.py new file mode 100644 index 0000000..86c96b2 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/events/catalog_list_response.py @@ -0,0 +1,32 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from ...._models import BaseModel +from ...shared.pagination import Pagination + +__all__ = ["CatalogListResponse", "Item"] + + +class Item(BaseModel): + created_at: Optional[str] = FieldInfo(alias="createdAt", default=None) + + description: Optional[str] = None + + event_type: str = FieldInfo(alias="eventType") + + label: str + + source: Optional[str] = None + + updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) + + payload_schema: Optional[object] = FieldInfo(alias="payloadSchema", default=None) + + +class CatalogListResponse(BaseModel): + items: List[Item] + + pagination: Pagination diff --git a/src/mobilerun_sdk/types/workflows/events/catalog_register_params.py b/src/mobilerun_sdk/types/workflows/events/catalog_register_params.py new file mode 100644 index 0000000..da648c3 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/events/catalog_register_params.py @@ -0,0 +1,26 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Iterable, Optional +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["CatalogRegisterParams", "Event"] + + +class CatalogRegisterParams(TypedDict, total=False): + events: Required[Iterable[Event]] + + +class Event(TypedDict, total=False): + event_type: Required[Annotated[str, PropertyInfo(alias="eventType")]] + + label: Required[str] + + description: str + + payload_schema: Annotated[Dict[str, Optional[object]], PropertyInfo(alias="payloadSchema")] + + source: Literal["device", "system", "webhook"] diff --git a/src/mobilerun_sdk/types/workflows/events/catalog_register_response.py b/src/mobilerun_sdk/types/workflows/events/catalog_register_response.py new file mode 100644 index 0000000..116b6cc --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/events/catalog_register_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["CatalogRegisterResponse"] + + +class CatalogRegisterResponse(BaseModel): + message: str diff --git a/src/mobilerun_sdk/types/workflows/execution_get_metrics_params.py b/src/mobilerun_sdk/types/workflows/execution_get_metrics_params.py new file mode 100644 index 0000000..b5d8cda --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/execution_get_metrics_params.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["ExecutionGetMetricsParams"] + + +class ExecutionGetMetricsParams(TypedDict, total=False): + flow_id: Annotated[str, PropertyInfo(alias="flowId")] + + from_: Annotated[Optional[str], PropertyInfo(alias="from")] + + to: Optional[str] + + trigger_id: Annotated[str, PropertyInfo(alias="triggerId")] diff --git a/src/mobilerun_sdk/types/workflows/execution_get_metrics_response.py b/src/mobilerun_sdk/types/workflows/execution_get_metrics_response.py new file mode 100644 index 0000000..774f398 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/execution_get_metrics_response.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["ExecutionGetMetricsResponse", "Data", "DataByStatus"] + + +class DataByStatus(BaseModel): + failed: int + + pending: int + + running: int + + success: int + + +class Data(BaseModel): + avg_duration_ms: Optional[float] = FieldInfo(alias="avgDurationMs", default=None) + + by_status: DataByStatus = FieldInfo(alias="byStatus") + + last_execution_at: Optional[str] = FieldInfo(alias="lastExecutionAt", default=None) + + total: int + + +class ExecutionGetMetricsResponse(BaseModel): + data: Data diff --git a/src/mobilerun_sdk/types/workflows/execution_list_params.py b/src/mobilerun_sdk/types/workflows/execution_list_params.py new file mode 100644 index 0000000..2ffa5c9 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/execution_list_params.py @@ -0,0 +1,32 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["ExecutionListParams"] + + +class ExecutionListParams(TypedDict, total=False): + flow_id: Annotated[str, PropertyInfo(alias="flowId")] + + from_: Annotated[Optional[str], PropertyInfo(alias="from")] + + order_by: Annotated[Literal["startedAt", "finishedAt", "status"], PropertyInfo(alias="orderBy")] + + order_by_direction: Annotated[Literal["asc", "desc"], PropertyInfo(alias="orderByDirection")] + + page: int + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + + search: str + + status: Literal["pending", "running", "success", "failed"] + + to: Optional[str] + + trigger_id: Annotated[str, PropertyInfo(alias="triggerId")] diff --git a/src/mobilerun_sdk/types/workflows/execution_list_response.py b/src/mobilerun_sdk/types/workflows/execution_list_response.py new file mode 100644 index 0000000..eddf7b3 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/execution_list_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ..._models import BaseModel +from .flow_execution import FlowExecution +from ..shared.pagination import Pagination + +__all__ = ["ExecutionListResponse"] + + +class ExecutionListResponse(BaseModel): + items: List[FlowExecution] + + pagination: Pagination diff --git a/src/mobilerun_sdk/types/workflows/execution_retrieve_response.py b/src/mobilerun_sdk/types/workflows/execution_retrieve_response.py new file mode 100644 index 0000000..6892a2e --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/execution_retrieve_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..._models import BaseModel +from .flow_execution import FlowExecution + +__all__ = ["ExecutionRetrieveResponse"] + + +class ExecutionRetrieveResponse(BaseModel): + data: FlowExecution diff --git a/src/mobilerun_sdk/types/workflows/flow_action_overrides_param.py b/src/mobilerun_sdk/types/workflows/flow_action_overrides_param.py new file mode 100644 index 0000000..5f03d3a --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flow_action_overrides_param.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Optional +from typing_extensions import TypedDict + +__all__ = ["FlowActionOverridesParam"] + + +class FlowActionOverridesParam(TypedDict, total=False): + params: Dict[str, Optional[object]] diff --git a/src/mobilerun_sdk/types/workflows/flow_child_action_input_param.py b/src/mobilerun_sdk/types/workflows/flow_child_action_input_param.py new file mode 100644 index 0000000..9c883c4 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flow_child_action_input_param.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Required, Annotated, TypedDict + +from ..._utils import PropertyInfo +from .flow_action_overrides_param import FlowActionOverridesParam + +__all__ = ["FlowChildActionInputParam"] + + +class FlowChildActionInputParam(TypedDict, total=False): + action_id: Required[Annotated[str, PropertyInfo(alias="actionId")]] + + position: Required[int] + + continue_on_error: Annotated[bool, PropertyInfo(alias="continueOnError")] + + device_id: Annotated[str, PropertyInfo(alias="deviceId")] + + name_override: Annotated[str, PropertyInfo(alias="nameOverride")] + + overrides: Optional[FlowActionOverridesParam] diff --git a/src/mobilerun_sdk/types/workflows/flow_clone_params.py b/src/mobilerun_sdk/types/workflows/flow_clone_params.py new file mode 100644 index 0000000..e513de2 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flow_clone_params.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import TypedDict + +__all__ = ["FlowCloneParams"] + + +class FlowCloneParams(TypedDict, total=False): + name: str diff --git a/src/mobilerun_sdk/types/workflows/flow_clone_response.py b/src/mobilerun_sdk/types/workflows/flow_clone_response.py new file mode 100644 index 0000000..57a8637 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flow_clone_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..flow import Flow +from ..._models import BaseModel + +__all__ = ["FlowCloneResponse"] + + +class FlowCloneResponse(BaseModel): + data: Flow diff --git a/src/mobilerun_sdk/types/workflows/flow_create_params.py b/src/mobilerun_sdk/types/workflows/flow_create_params.py new file mode 100644 index 0000000..1dcdd12 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flow_create_params.py @@ -0,0 +1,44 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable, Optional +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ..._utils import PropertyInfo +from .flow_action_overrides_param import FlowActionOverridesParam +from .flow_child_action_input_param import FlowChildActionInputParam + +__all__ = ["FlowCreateParams", "Action"] + + +class FlowCreateParams(TypedDict, total=False): + actions: Required[Iterable[Action]] + + name: Required[str] + + trigger_id: Required[Annotated[str, PropertyInfo(alias="triggerId")]] + + cooldown_scope: Annotated[Literal["flow", "device"], PropertyInfo(alias="cooldownScope")] + + cooldown_seconds: Annotated[Optional[int], PropertyInfo(alias="cooldownSeconds")] + + description: str + + enabled: bool + + +class Action(TypedDict, total=False): + action_id: Required[Annotated[str, PropertyInfo(alias="actionId")]] + + position: Required[int] + + children: Iterable[FlowChildActionInputParam] + + continue_on_error: Annotated[bool, PropertyInfo(alias="continueOnError")] + + device_id: Annotated[str, PropertyInfo(alias="deviceId")] + + name_override: Annotated[str, PropertyInfo(alias="nameOverride")] + + overrides: Optional[FlowActionOverridesParam] diff --git a/src/mobilerun_sdk/types/workflows/flow_create_response.py b/src/mobilerun_sdk/types/workflows/flow_create_response.py new file mode 100644 index 0000000..f9c5fea --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flow_create_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..flow import Flow +from ..._models import BaseModel + +__all__ = ["FlowCreateResponse"] + + +class FlowCreateResponse(BaseModel): + data: Flow diff --git a/src/mobilerun_sdk/types/workflows/flow_delete_response.py b/src/mobilerun_sdk/types/workflows/flow_delete_response.py new file mode 100644 index 0000000..a6243e6 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flow_delete_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..._models import BaseModel + +__all__ = ["FlowDeleteResponse"] + + +class FlowDeleteResponse(BaseModel): + message: str diff --git a/src/mobilerun_sdk/types/workflows/flow_execution.py b/src/mobilerun_sdk/types/workflows/flow_execution.py new file mode 100644 index 0000000..ba28012 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flow_execution.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["FlowExecution"] + + +class FlowExecution(BaseModel): + id: str + + error: Optional[str] = None + + event_id: Optional[str] = FieldInfo(alias="eventId", default=None) + + finished_at: Optional[str] = FieldInfo(alias="finishedAt", default=None) + + flow_id: str = FieldInfo(alias="flowId") + + flow_name: Optional[str] = FieldInfo(alias="flowName", default=None) + + started_at: Optional[str] = FieldInfo(alias="startedAt", default=None) + + status: Optional[Literal["pending", "running", "success", "failed"]] = None + + trigger_id: str = FieldInfo(alias="triggerId") + + trigger_name: Optional[str] = FieldInfo(alias="triggerName", default=None) + + result: Optional[object] = None diff --git a/src/mobilerun_sdk/types/workflows/flow_list_params.py b/src/mobilerun_sdk/types/workflows/flow_list_params.py new file mode 100644 index 0000000..c8310db --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flow_list_params.py @@ -0,0 +1,26 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["FlowListParams"] + + +class FlowListParams(TypedDict, total=False): + enabled: Optional[bool] + + order_by: Annotated[Literal["name", "createdAt", "updatedAt"], PropertyInfo(alias="orderBy")] + + order_by_direction: Annotated[Literal["asc", "desc"], PropertyInfo(alias="orderByDirection")] + + page: int + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + + search: str + + trigger_id: Annotated[str, PropertyInfo(alias="triggerId")] diff --git a/src/mobilerun_sdk/types/workflows/flow_list_response.py b/src/mobilerun_sdk/types/workflows/flow_list_response.py new file mode 100644 index 0000000..ff0feb8 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flow_list_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ..flow import Flow +from ..._models import BaseModel +from ..shared.pagination import Pagination + +__all__ = ["FlowListResponse"] + + +class FlowListResponse(BaseModel): + items: List[Flow] + + pagination: Pagination diff --git a/src/mobilerun_sdk/types/workflows/flow_retrieve_response.py b/src/mobilerun_sdk/types/workflows/flow_retrieve_response.py new file mode 100644 index 0000000..0a002a6 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flow_retrieve_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..flow import Flow +from ..._models import BaseModel + +__all__ = ["FlowRetrieveResponse"] + + +class FlowRetrieveResponse(BaseModel): + data: Flow diff --git a/src/mobilerun_sdk/types/workflows/flow_update_params.py b/src/mobilerun_sdk/types/workflows/flow_update_params.py new file mode 100644 index 0000000..8b29afd --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flow_update_params.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["FlowUpdateParams"] + + +class FlowUpdateParams(TypedDict, total=False): + cooldown_scope: Annotated[Literal["flow", "device"], PropertyInfo(alias="cooldownScope")] + + cooldown_seconds: Annotated[Optional[int], PropertyInfo(alias="cooldownSeconds")] + + description: str + + enabled: bool + + name: str + + trigger_id: Annotated[str, PropertyInfo(alias="triggerId")] diff --git a/src/mobilerun_sdk/types/workflows/flow_update_response.py b/src/mobilerun_sdk/types/workflows/flow_update_response.py new file mode 100644 index 0000000..8725080 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flow_update_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..flow import Flow +from ..._models import BaseModel + +__all__ = ["FlowUpdateResponse"] + + +class FlowUpdateResponse(BaseModel): + data: Flow diff --git a/src/mobilerun_sdk/types/workflows/flows/__init__.py b/src/mobilerun_sdk/types/workflows/flows/__init__.py new file mode 100644 index 0000000..fa77a33 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flows/__init__.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .flow_action import FlowAction as FlowAction +from .action_add_params import ActionAddParams as ActionAddParams +from .action_add_response import ActionAddResponse as ActionAddResponse +from .action_list_response import ActionListResponse as ActionListResponse +from .action_replace_params import ActionReplaceParams as ActionReplaceParams +from .action_remove_response import ActionRemoveResponse as ActionRemoveResponse +from .action_replace_response import ActionReplaceResponse as ActionReplaceResponse diff --git a/src/mobilerun_sdk/types/workflows/flows/action_add_params.py b/src/mobilerun_sdk/types/workflows/flows/action_add_params.py new file mode 100644 index 0000000..7d71e72 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flows/action_add_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable, Optional +from typing_extensions import Required, Annotated, TypedDict + +from ...._utils import PropertyInfo +from ..flow_action_overrides_param import FlowActionOverridesParam +from ..flow_child_action_input_param import FlowChildActionInputParam + +__all__ = ["ActionAddParams"] + + +class ActionAddParams(TypedDict, total=False): + action_id: Required[Annotated[str, PropertyInfo(alias="actionId")]] + + position: Required[int] + + children: Iterable[FlowChildActionInputParam] + + continue_on_error: Annotated[bool, PropertyInfo(alias="continueOnError")] + + device_id: Annotated[str, PropertyInfo(alias="deviceId")] + + name_override: Annotated[str, PropertyInfo(alias="nameOverride")] + + overrides: Optional[FlowActionOverridesParam] + + parent_flow_action_id: Annotated[Optional[str], PropertyInfo(alias="parentFlowActionId")] diff --git a/src/mobilerun_sdk/types/workflows/flows/action_add_response.py b/src/mobilerun_sdk/types/workflows/flows/action_add_response.py new file mode 100644 index 0000000..03d4e31 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flows/action_add_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel +from .flow_action import FlowAction + +__all__ = ["ActionAddResponse"] + + +class ActionAddResponse(BaseModel): + data: FlowAction diff --git a/src/mobilerun_sdk/types/workflows/flows/action_list_response.py b/src/mobilerun_sdk/types/workflows/flows/action_list_response.py new file mode 100644 index 0000000..7f6bd53 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flows/action_list_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ...._models import BaseModel +from .flow_action import FlowAction + +__all__ = ["ActionListResponse"] + + +class ActionListResponse(BaseModel): + data: List[FlowAction] diff --git a/src/mobilerun_sdk/types/workflows/flows/action_remove_response.py b/src/mobilerun_sdk/types/workflows/flows/action_remove_response.py new file mode 100644 index 0000000..a200db1 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flows/action_remove_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["ActionRemoveResponse"] + + +class ActionRemoveResponse(BaseModel): + message: str diff --git a/src/mobilerun_sdk/types/workflows/flows/action_replace_params.py b/src/mobilerun_sdk/types/workflows/flows/action_replace_params.py new file mode 100644 index 0000000..2ae1e95 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flows/action_replace_params.py @@ -0,0 +1,32 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable, Optional +from typing_extensions import Required, Annotated, TypedDict + +from ...._utils import PropertyInfo +from ..flow_action_overrides_param import FlowActionOverridesParam +from ..flow_child_action_input_param import FlowChildActionInputParam + +__all__ = ["ActionReplaceParams", "Action"] + + +class ActionReplaceParams(TypedDict, total=False): + actions: Required[Iterable[Action]] + + +class Action(TypedDict, total=False): + action_id: Required[Annotated[str, PropertyInfo(alias="actionId")]] + + position: Required[int] + + children: Iterable[FlowChildActionInputParam] + + continue_on_error: Annotated[bool, PropertyInfo(alias="continueOnError")] + + device_id: Annotated[str, PropertyInfo(alias="deviceId")] + + name_override: Annotated[str, PropertyInfo(alias="nameOverride")] + + overrides: Optional[FlowActionOverridesParam] diff --git a/src/mobilerun_sdk/types/workflows/flows/action_replace_response.py b/src/mobilerun_sdk/types/workflows/flows/action_replace_response.py new file mode 100644 index 0000000..2914bfa --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flows/action_replace_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ...._models import BaseModel +from .flow_action import FlowAction + +__all__ = ["ActionReplaceResponse"] + + +class ActionReplaceResponse(BaseModel): + data: List[FlowAction] diff --git a/src/mobilerun_sdk/types/workflows/flows/flow_action.py b/src/mobilerun_sdk/types/workflows/flows/flow_action.py new file mode 100644 index 0000000..cf83cb4 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flows/flow_action.py @@ -0,0 +1,35 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, Optional + +from pydantic import Field as FieldInfo + +from ...._models import BaseModel + +__all__ = ["FlowAction", "Overrides"] + + +class Overrides(BaseModel): + params: Optional[Dict[str, Optional[object]]] = None + + +class FlowAction(BaseModel): + id: str + + action_id: str = FieldInfo(alias="actionId") + + continue_on_error: bool = FieldInfo(alias="continueOnError") + + created_at: Optional[str] = FieldInfo(alias="createdAt", default=None) + + device_id: Optional[str] = FieldInfo(alias="deviceId", default=None) + + flow_id: str = FieldInfo(alias="flowId") + + name_override: Optional[str] = FieldInfo(alias="nameOverride", default=None) + + overrides: Optional[Overrides] = None + + parent_flow_action_id: Optional[str] = FieldInfo(alias="parentFlowActionId", default=None) + + position: int diff --git a/src/mobilerun_sdk/types/workflows/secret_create_params.py b/src/mobilerun_sdk/types/workflows/secret_create_params.py new file mode 100644 index 0000000..88e54de --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/secret_create_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["SecretCreateParams"] + + +class SecretCreateParams(TypedDict, total=False): + name: Required[str] + + value: Required[str] + + description: str diff --git a/src/mobilerun_sdk/types/workflows/secret_create_response.py b/src/mobilerun_sdk/types/workflows/secret_create_response.py new file mode 100644 index 0000000..a05805f --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/secret_create_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..._models import BaseModel +from .user_secret import UserSecret + +__all__ = ["SecretCreateResponse"] + + +class SecretCreateResponse(BaseModel): + data: UserSecret diff --git a/src/mobilerun_sdk/types/workflows/secret_delete_response.py b/src/mobilerun_sdk/types/workflows/secret_delete_response.py new file mode 100644 index 0000000..16ec787 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/secret_delete_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..._models import BaseModel + +__all__ = ["SecretDeleteResponse"] + + +class SecretDeleteResponse(BaseModel): + message: str diff --git a/src/mobilerun_sdk/types/workflows/secret_list_response.py b/src/mobilerun_sdk/types/workflows/secret_list_response.py new file mode 100644 index 0000000..5e661ee --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/secret_list_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ..._models import BaseModel +from .user_secret import UserSecret + +__all__ = ["SecretListResponse"] + + +class SecretListResponse(BaseModel): + data: List[UserSecret] diff --git a/src/mobilerun_sdk/types/workflows/timezone_list_response.py b/src/mobilerun_sdk/types/workflows/timezone_list_response.py new file mode 100644 index 0000000..6e49c63 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/timezone_list_response.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ..._models import BaseModel + +__all__ = ["TimezoneListResponse"] + + +class TimezoneListResponse(BaseModel): + data: List[str] diff --git a/src/mobilerun_sdk/types/workflows/trigger_create_params.py b/src/mobilerun_sdk/types/workflows/trigger_create_params.py new file mode 100644 index 0000000..7d8c4b8 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/trigger_create_params.py @@ -0,0 +1,48 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Iterable +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["TriggerCreateParams", "Conditions", "ScheduleRule"] + + +class TriggerCreateParams(TypedDict, total=False): + activation: Required[Literal["event", "schedule", "custom"]] + + name: Required[str] + + conditions: Conditions + + custom_payload_schema: Annotated[Dict[str, object], PropertyInfo(alias="customPayloadSchema")] + """Optional JSON Schema for validating payloads sent to this custom trigger""" + + description: str + + event_type: Annotated[str, PropertyInfo(alias="eventType")] + + schedule_rule: Annotated[ScheduleRule, PropertyInfo(alias="scheduleRule")] + + timezone: str + + +class Conditions(TypedDict, total=False): + all: Iterable[object] + + any: Iterable[object] + + +class ScheduleRule(TypedDict, total=False): + type: Required[Literal["once", "cron", "recurring"]] + + date_time: Annotated[str, PropertyInfo(alias="dateTime")] + """ISO 8601 datetime (for type=once)""" + + expression: str + """Cron expression (for type=cron)""" + + rrule: str + """RRULE string (for type=recurring)""" diff --git a/src/mobilerun_sdk/types/workflows/trigger_create_response.py b/src/mobilerun_sdk/types/workflows/trigger_create_response.py new file mode 100644 index 0000000..b2073b1 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/trigger_create_response.py @@ -0,0 +1,55 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["TriggerCreateResponse", "Data", "DataScheduleRule"] + + +class DataScheduleRule(BaseModel): + type: Literal["once", "cron", "recurring"] + + date_time: Optional[str] = FieldInfo(alias="dateTime", default=None) + """ISO 8601 datetime (for type=once)""" + + expression: Optional[str] = None + """Cron expression (for type=cron)""" + + rrule: Optional[str] = None + """RRULE string (for type=recurring)""" + + +class Data(BaseModel): + id: str + + activation: Literal["event", "schedule", "custom"] + + created_at: Optional[str] = FieldInfo(alias="createdAt", default=None) + + custom_payload_schema: Optional[Dict[str, Optional[object]]] = FieldInfo(alias="customPayloadSchema", default=None) + + description: Optional[str] = None + + event_type: Optional[str] = FieldInfo(alias="eventType", default=None) + + name: str + + schedule_rule: DataScheduleRule = FieldInfo(alias="scheduleRule") + + timezone: Optional[str] = None + + updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) + + user_id: str = FieldInfo(alias="userId") + + conditions: Optional[object] = None + + next_fire_time: Optional[str] = FieldInfo(alias="nextFireTime", default=None) + + +class TriggerCreateResponse(BaseModel): + data: Data diff --git a/src/mobilerun_sdk/types/workflows/trigger_delete_response.py b/src/mobilerun_sdk/types/workflows/trigger_delete_response.py new file mode 100644 index 0000000..5a4cf92 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/trigger_delete_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..._models import BaseModel + +__all__ = ["TriggerDeleteResponse"] + + +class TriggerDeleteResponse(BaseModel): + message: str diff --git a/src/mobilerun_sdk/types/workflows/trigger_fire_params.py b/src/mobilerun_sdk/types/workflows/trigger_fire_params.py new file mode 100644 index 0000000..756af49 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/trigger_fire_params.py @@ -0,0 +1,26 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict +from typing_extensions import Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["TriggerFireParams"] + + +class TriggerFireParams(TypedDict, total=False): + payload: Required[Dict[str, object]] + """Arbitrary JSON object forwarded to every flow attached to this trigger. + + Validated against the trigger's customPayloadSchema when one is configured; + otherwise only "must be a JSON object" is enforced. + """ + + device_id: Annotated[str, PropertyInfo(alias="deviceId")] + """Optional device scope. + + When supplied, ownership is verified for the calling user and the value is + passed through to each enqueued execution as the default device context. + """ diff --git a/src/mobilerun_sdk/types/workflows/trigger_fire_response.py b/src/mobilerun_sdk/types/workflows/trigger_fire_response.py new file mode 100644 index 0000000..b0b4951 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/trigger_fire_response.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["TriggerFireResponse"] + + +class TriggerFireResponse(BaseModel): + enqueued_count: int = FieldInfo(alias="enqueuedCount") + """Number of flow executions enqueued. + + May be 0 if no flows are attached to this trigger, or if all attached flows are + currently in cooldown. + """ + + invocation_id: str = FieldInfo(alias="invocationId") + """Unique ID for this fire invocation. + + Job IDs in the execution queue are derived from it (one per enqueued flow). + """ diff --git a/src/mobilerun_sdk/types/workflows/trigger_list_params.py b/src/mobilerun_sdk/types/workflows/trigger_list_params.py new file mode 100644 index 0000000..dad1a5f --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/trigger_list_params.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["TriggerListParams"] + + +class TriggerListParams(TypedDict, total=False): + activation: Literal["event", "schedule", "custom"] + + event_type: Annotated[str, PropertyInfo(alias="eventType")] + + order_by: Annotated[Literal["name", "createdAt", "updatedAt"], PropertyInfo(alias="orderBy")] + + order_by_direction: Annotated[Literal["asc", "desc"], PropertyInfo(alias="orderByDirection")] + + page: int + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + + search: str diff --git a/src/mobilerun_sdk/types/workflows/trigger_list_response.py b/src/mobilerun_sdk/types/workflows/trigger_list_response.py new file mode 100644 index 0000000..703fd4c --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/trigger_list_response.py @@ -0,0 +1,58 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel +from ..shared.pagination import Pagination + +__all__ = ["TriggerListResponse", "Item", "ItemScheduleRule"] + + +class ItemScheduleRule(BaseModel): + type: Literal["once", "cron", "recurring"] + + date_time: Optional[str] = FieldInfo(alias="dateTime", default=None) + """ISO 8601 datetime (for type=once)""" + + expression: Optional[str] = None + """Cron expression (for type=cron)""" + + rrule: Optional[str] = None + """RRULE string (for type=recurring)""" + + +class Item(BaseModel): + id: str + + activation: Literal["event", "schedule", "custom"] + + created_at: Optional[str] = FieldInfo(alias="createdAt", default=None) + + custom_payload_schema: Optional[Dict[str, object]] = FieldInfo(alias="customPayloadSchema", default=None) + + description: Optional[str] = None + + event_type: Optional[str] = FieldInfo(alias="eventType", default=None) + + name: str + + schedule_rule: Optional[ItemScheduleRule] = FieldInfo(alias="scheduleRule", default=None) + + timezone: Optional[str] = None + + updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) + + user_id: str = FieldInfo(alias="userId") + + conditions: Optional[object] = None + + next_fire_time: Optional[str] = FieldInfo(alias="nextFireTime", default=None) + + +class TriggerListResponse(BaseModel): + items: List[Item] + + pagination: Pagination diff --git a/src/mobilerun_sdk/types/workflows/trigger_retrieve_response.py b/src/mobilerun_sdk/types/workflows/trigger_retrieve_response.py new file mode 100644 index 0000000..fc48aa4 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/trigger_retrieve_response.py @@ -0,0 +1,55 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["TriggerRetrieveResponse", "Data", "DataScheduleRule"] + + +class DataScheduleRule(BaseModel): + type: Literal["once", "cron", "recurring"] + + date_time: Optional[str] = FieldInfo(alias="dateTime", default=None) + """ISO 8601 datetime (for type=once)""" + + expression: Optional[str] = None + """Cron expression (for type=cron)""" + + rrule: Optional[str] = None + """RRULE string (for type=recurring)""" + + +class Data(BaseModel): + id: str + + activation: Literal["event", "schedule", "custom"] + + created_at: Optional[str] = FieldInfo(alias="createdAt", default=None) + + custom_payload_schema: Optional[Dict[str, object]] = FieldInfo(alias="customPayloadSchema", default=None) + + description: Optional[str] = None + + event_type: Optional[str] = FieldInfo(alias="eventType", default=None) + + name: str + + schedule_rule: Optional[DataScheduleRule] = FieldInfo(alias="scheduleRule", default=None) + + timezone: Optional[str] = None + + updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) + + user_id: str = FieldInfo(alias="userId") + + conditions: Optional[object] = None + + next_fire_time: Optional[str] = FieldInfo(alias="nextFireTime", default=None) + + +class TriggerRetrieveResponse(BaseModel): + data: Data diff --git a/src/mobilerun_sdk/types/workflows/trigger_update_params.py b/src/mobilerun_sdk/types/workflows/trigger_update_params.py new file mode 100644 index 0000000..ecf86b7 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/trigger_update_params.py @@ -0,0 +1,48 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Iterable, Optional +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["TriggerUpdateParams", "Conditions", "ScheduleRule"] + + +class TriggerUpdateParams(TypedDict, total=False): + activation: Literal["event", "schedule", "custom"] + + conditions: Conditions + + custom_payload_schema: Annotated[Optional[Dict[str, object]], PropertyInfo(alias="customPayloadSchema")] + """Optional JSON Schema for validating payloads sent to this custom trigger""" + + description: str + + event_type: Annotated[str, PropertyInfo(alias="eventType")] + + name: str + + schedule_rule: Annotated[ScheduleRule, PropertyInfo(alias="scheduleRule")] + + timezone: Optional[str] + + +class Conditions(TypedDict, total=False): + all: Iterable[object] + + any: Iterable[object] + + +class ScheduleRule(TypedDict, total=False): + type: Required[Literal["once", "cron", "recurring"]] + + date_time: Annotated[str, PropertyInfo(alias="dateTime")] + """ISO 8601 datetime (for type=once)""" + + expression: str + """Cron expression (for type=cron)""" + + rrule: str + """RRULE string (for type=recurring)""" diff --git a/src/mobilerun_sdk/types/workflows/trigger_update_response.py b/src/mobilerun_sdk/types/workflows/trigger_update_response.py new file mode 100644 index 0000000..a5a9418 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/trigger_update_response.py @@ -0,0 +1,55 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["TriggerUpdateResponse", "Data", "DataScheduleRule"] + + +class DataScheduleRule(BaseModel): + type: Literal["once", "cron", "recurring"] + + date_time: Optional[str] = FieldInfo(alias="dateTime", default=None) + """ISO 8601 datetime (for type=once)""" + + expression: Optional[str] = None + """Cron expression (for type=cron)""" + + rrule: Optional[str] = None + """RRULE string (for type=recurring)""" + + +class Data(BaseModel): + id: str + + activation: Literal["event", "schedule", "custom"] + + created_at: Optional[str] = FieldInfo(alias="createdAt", default=None) + + custom_payload_schema: Optional[Dict[str, object]] = FieldInfo(alias="customPayloadSchema", default=None) + + description: Optional[str] = None + + event_type: Optional[str] = FieldInfo(alias="eventType", default=None) + + name: str + + schedule_rule: Optional[DataScheduleRule] = FieldInfo(alias="scheduleRule", default=None) + + timezone: Optional[str] = None + + updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) + + user_id: str = FieldInfo(alias="userId") + + conditions: Optional[object] = None + + next_fire_time: Optional[str] = FieldInfo(alias="nextFireTime", default=None) + + +class TriggerUpdateResponse(BaseModel): + data: Data diff --git a/src/mobilerun_sdk/types/workflows/user_secret.py b/src/mobilerun_sdk/types/workflows/user_secret.py new file mode 100644 index 0000000..a33cade --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/user_secret.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["UserSecret"] + + +class UserSecret(BaseModel): + id: str + + created_at: Optional[str] = FieldInfo(alias="createdAt", default=None) + + description: Optional[str] = None + + name: str + + updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) diff --git a/tests/api_resources/workflows/__init__.py b/tests/api_resources/workflows/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/workflows/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/workflows/actions/__init__.py b/tests/api_resources/workflows/actions/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/workflows/actions/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/workflows/actions/test_services.py b/tests/api_resources/workflows/actions/test_services.py new file mode 100644 index 0000000..442a3bd --- /dev/null +++ b/tests/api_resources/workflows/actions/test_services.py @@ -0,0 +1,164 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.workflows.actions import ServiceListResponse, ServiceListMethodsResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestServices: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + service = client.workflows.actions.services.list() + assert_matches_type(ServiceListResponse, service, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.workflows.actions.services.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + service = response.parse() + assert_matches_type(ServiceListResponse, service, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.workflows.actions.services.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + service = response.parse() + assert_matches_type(ServiceListResponse, service, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_methods(self, client: Mobilerun) -> None: + service = client.workflows.actions.services.list_methods( + "x", + ) + assert_matches_type(ServiceListMethodsResponse, service, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list_methods(self, client: Mobilerun) -> None: + response = client.workflows.actions.services.with_raw_response.list_methods( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + service = response.parse() + assert_matches_type(ServiceListMethodsResponse, service, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list_methods(self, client: Mobilerun) -> None: + with client.workflows.actions.services.with_streaming_response.list_methods( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + service = response.parse() + assert_matches_type(ServiceListMethodsResponse, service, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_list_methods(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `service` but received ''"): + client.workflows.actions.services.with_raw_response.list_methods( + "", + ) + + +class TestAsyncServices: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + service = await async_client.workflows.actions.services.list() + assert_matches_type(ServiceListResponse, service, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.actions.services.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + service = await response.parse() + assert_matches_type(ServiceListResponse, service, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.actions.services.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + service = await response.parse() + assert_matches_type(ServiceListResponse, service, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_methods(self, async_client: AsyncMobilerun) -> None: + service = await async_client.workflows.actions.services.list_methods( + "x", + ) + assert_matches_type(ServiceListMethodsResponse, service, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list_methods(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.actions.services.with_raw_response.list_methods( + "x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + service = await response.parse() + assert_matches_type(ServiceListMethodsResponse, service, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list_methods(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.actions.services.with_streaming_response.list_methods( + "x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + service = await response.parse() + assert_matches_type(ServiceListMethodsResponse, service, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_list_methods(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `service` but received ''"): + await async_client.workflows.actions.services.with_raw_response.list_methods( + "", + ) diff --git a/tests/api_resources/workflows/events/__init__.py b/tests/api_resources/workflows/events/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/workflows/events/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/workflows/events/test_catalog.py b/tests/api_resources/workflows/events/test_catalog.py new file mode 100644 index 0000000..df97792 --- /dev/null +++ b/tests/api_resources/workflows/events/test_catalog.py @@ -0,0 +1,201 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.workflows.events import ( + CatalogListResponse, + CatalogRegisterResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestCatalog: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + catalog = client.workflows.events.catalog.list() + assert_matches_type(CatalogListResponse, catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Mobilerun) -> None: + catalog = client.workflows.events.catalog.list( + page=1, + page_size=1, + source="device", + ) + assert_matches_type(CatalogListResponse, catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.workflows.events.catalog.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + catalog = response.parse() + assert_matches_type(CatalogListResponse, catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.workflows.events.catalog.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + catalog = response.parse() + assert_matches_type(CatalogListResponse, catalog, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_register(self, client: Mobilerun) -> None: + catalog = client.workflows.events.catalog.register( + events=[ + { + "event_type": "x", + "label": "x", + } + ], + ) + assert_matches_type(CatalogRegisterResponse, catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_register(self, client: Mobilerun) -> None: + response = client.workflows.events.catalog.with_raw_response.register( + events=[ + { + "event_type": "x", + "label": "x", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + catalog = response.parse() + assert_matches_type(CatalogRegisterResponse, catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_register(self, client: Mobilerun) -> None: + with client.workflows.events.catalog.with_streaming_response.register( + events=[ + { + "event_type": "x", + "label": "x", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + catalog = response.parse() + assert_matches_type(CatalogRegisterResponse, catalog, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncCatalog: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + catalog = await async_client.workflows.events.catalog.list() + assert_matches_type(CatalogListResponse, catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: + catalog = await async_client.workflows.events.catalog.list( + page=1, + page_size=1, + source="device", + ) + assert_matches_type(CatalogListResponse, catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.events.catalog.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + catalog = await response.parse() + assert_matches_type(CatalogListResponse, catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.events.catalog.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + catalog = await response.parse() + assert_matches_type(CatalogListResponse, catalog, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_register(self, async_client: AsyncMobilerun) -> None: + catalog = await async_client.workflows.events.catalog.register( + events=[ + { + "event_type": "x", + "label": "x", + } + ], + ) + assert_matches_type(CatalogRegisterResponse, catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_register(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.events.catalog.with_raw_response.register( + events=[ + { + "event_type": "x", + "label": "x", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + catalog = await response.parse() + assert_matches_type(CatalogRegisterResponse, catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_register(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.events.catalog.with_streaming_response.register( + events=[ + { + "event_type": "x", + "label": "x", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + catalog = await response.parse() + assert_matches_type(CatalogRegisterResponse, catalog, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/workflows/flows/__init__.py b/tests/api_resources/workflows/flows/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/workflows/flows/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/workflows/flows/test_actions.py b/tests/api_resources/workflows/flows/test_actions.py new file mode 100644 index 0000000..0343316 --- /dev/null +++ b/tests/api_resources/workflows/flows/test_actions.py @@ -0,0 +1,499 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.workflows.flows import ( + ActionAddResponse, + ActionListResponse, + ActionRemoveResponse, + ActionReplaceResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestActions: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + action = client.workflows.flows.actions.list( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ActionListResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.workflows.flows.actions.with_raw_response.list( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = response.parse() + assert_matches_type(ActionListResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.workflows.flows.actions.with_streaming_response.list( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = response.parse() + assert_matches_type(ActionListResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_list(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + client.workflows.flows.actions.with_raw_response.list( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_add(self, client: Mobilerun) -> None: + action = client.workflows.flows.actions.add( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + position=0, + ) + assert_matches_type(ActionAddResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_add_with_all_params(self, client: Mobilerun) -> None: + action = client.workflows.flows.actions.add( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + position=0, + children=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + "continue_on_error": True, + "device_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "name_override": "x", + "overrides": {"params": {"foo": "bar"}}, + } + ], + continue_on_error=True, + device_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + name_override="x", + overrides={"params": {"foo": "bar"}}, + parent_flow_action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ActionAddResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_add(self, client: Mobilerun) -> None: + response = client.workflows.flows.actions.with_raw_response.add( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + position=0, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = response.parse() + assert_matches_type(ActionAddResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_add(self, client: Mobilerun) -> None: + with client.workflows.flows.actions.with_streaming_response.add( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + position=0, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = response.parse() + assert_matches_type(ActionAddResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_add(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + client.workflows.flows.actions.with_raw_response.add( + flow_id="", + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + position=0, + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_remove(self, client: Mobilerun) -> None: + action = client.workflows.flows.actions.remove( + flow_action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ActionRemoveResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_remove(self, client: Mobilerun) -> None: + response = client.workflows.flows.actions.with_raw_response.remove( + flow_action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = response.parse() + assert_matches_type(ActionRemoveResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_remove(self, client: Mobilerun) -> None: + with client.workflows.flows.actions.with_streaming_response.remove( + flow_action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = response.parse() + assert_matches_type(ActionRemoveResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_remove(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + client.workflows.flows.actions.with_raw_response.remove( + flow_action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + flow_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_action_id` but received ''"): + client.workflows.flows.actions.with_raw_response.remove( + flow_action_id="", + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_replace(self, client: Mobilerun) -> None: + action = client.workflows.flows.actions.replace( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + } + ], + ) + assert_matches_type(ActionReplaceResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_replace(self, client: Mobilerun) -> None: + response = client.workflows.flows.actions.with_raw_response.replace( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = response.parse() + assert_matches_type(ActionReplaceResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_replace(self, client: Mobilerun) -> None: + with client.workflows.flows.actions.with_streaming_response.replace( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = response.parse() + assert_matches_type(ActionReplaceResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_replace(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + client.workflows.flows.actions.with_raw_response.replace( + flow_id="", + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + } + ], + ) + + +class TestAsyncActions: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + action = await async_client.workflows.flows.actions.list( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ActionListResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.flows.actions.with_raw_response.list( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = await response.parse() + assert_matches_type(ActionListResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.flows.actions.with_streaming_response.list( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = await response.parse() + assert_matches_type(ActionListResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_list(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + await async_client.workflows.flows.actions.with_raw_response.list( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_add(self, async_client: AsyncMobilerun) -> None: + action = await async_client.workflows.flows.actions.add( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + position=0, + ) + assert_matches_type(ActionAddResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_add_with_all_params(self, async_client: AsyncMobilerun) -> None: + action = await async_client.workflows.flows.actions.add( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + position=0, + children=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + "continue_on_error": True, + "device_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "name_override": "x", + "overrides": {"params": {"foo": "bar"}}, + } + ], + continue_on_error=True, + device_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + name_override="x", + overrides={"params": {"foo": "bar"}}, + parent_flow_action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ActionAddResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_add(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.flows.actions.with_raw_response.add( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + position=0, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = await response.parse() + assert_matches_type(ActionAddResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_add(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.flows.actions.with_streaming_response.add( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + position=0, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = await response.parse() + assert_matches_type(ActionAddResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_add(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + await async_client.workflows.flows.actions.with_raw_response.add( + flow_id="", + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + position=0, + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_remove(self, async_client: AsyncMobilerun) -> None: + action = await async_client.workflows.flows.actions.remove( + flow_action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ActionRemoveResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_remove(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.flows.actions.with_raw_response.remove( + flow_action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = await response.parse() + assert_matches_type(ActionRemoveResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_remove(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.flows.actions.with_streaming_response.remove( + flow_action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = await response.parse() + assert_matches_type(ActionRemoveResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_remove(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + await async_client.workflows.flows.actions.with_raw_response.remove( + flow_action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + flow_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_action_id` but received ''"): + await async_client.workflows.flows.actions.with_raw_response.remove( + flow_action_id="", + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_replace(self, async_client: AsyncMobilerun) -> None: + action = await async_client.workflows.flows.actions.replace( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + } + ], + ) + assert_matches_type(ActionReplaceResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_replace(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.flows.actions.with_raw_response.replace( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = await response.parse() + assert_matches_type(ActionReplaceResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_replace(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.flows.actions.with_streaming_response.replace( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = await response.parse() + assert_matches_type(ActionReplaceResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_replace(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + await async_client.workflows.flows.actions.with_raw_response.replace( + flow_id="", + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + } + ], + ) diff --git a/tests/api_resources/workflows/test_action_catalog.py b/tests/api_resources/workflows/test_action_catalog.py new file mode 100644 index 0000000..9f228db --- /dev/null +++ b/tests/api_resources/workflows/test_action_catalog.py @@ -0,0 +1,187 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.workflows import ( + ActionCatalogListResponse, + ActionCatalogRetrieveResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestActionCatalog: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve(self, client: Mobilerun) -> None: + action_catalog = client.workflows.action_catalog.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ActionCatalogRetrieveResponse, action_catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve(self, client: Mobilerun) -> None: + response = client.workflows.action_catalog.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action_catalog = response.parse() + assert_matches_type(ActionCatalogRetrieveResponse, action_catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve(self, client: Mobilerun) -> None: + with client.workflows.action_catalog.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action_catalog = response.parse() + assert_matches_type(ActionCatalogRetrieveResponse, action_catalog, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_retrieve(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `catalog_entry_id` but received ''"): + client.workflows.action_catalog.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + action_catalog = client.workflows.action_catalog.list() + assert_matches_type(ActionCatalogListResponse, action_catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Mobilerun) -> None: + action_catalog = client.workflows.action_catalog.list( + page=1, + page_size=1, + service="tasks_api", + ) + assert_matches_type(ActionCatalogListResponse, action_catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.workflows.action_catalog.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action_catalog = response.parse() + assert_matches_type(ActionCatalogListResponse, action_catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.workflows.action_catalog.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action_catalog = response.parse() + assert_matches_type(ActionCatalogListResponse, action_catalog, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncActionCatalog: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve(self, async_client: AsyncMobilerun) -> None: + action_catalog = await async_client.workflows.action_catalog.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ActionCatalogRetrieveResponse, action_catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.action_catalog.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action_catalog = await response.parse() + assert_matches_type(ActionCatalogRetrieveResponse, action_catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.action_catalog.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action_catalog = await response.parse() + assert_matches_type(ActionCatalogRetrieveResponse, action_catalog, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `catalog_entry_id` but received ''"): + await async_client.workflows.action_catalog.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + action_catalog = await async_client.workflows.action_catalog.list() + assert_matches_type(ActionCatalogListResponse, action_catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: + action_catalog = await async_client.workflows.action_catalog.list( + page=1, + page_size=1, + service="tasks_api", + ) + assert_matches_type(ActionCatalogListResponse, action_catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.action_catalog.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action_catalog = await response.parse() + assert_matches_type(ActionCatalogListResponse, action_catalog, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.action_catalog.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action_catalog = await response.parse() + assert_matches_type(ActionCatalogListResponse, action_catalog, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/workflows/test_actions.py b/tests/api_resources/workflows/test_actions.py new file mode 100644 index 0000000..9533759 --- /dev/null +++ b/tests/api_resources/workflows/test_actions.py @@ -0,0 +1,482 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.workflows import ( + ActionListResponse, + ActionCreateResponse, + ActionDeleteResponse, + ActionUpdateResponse, + ActionRetrieveResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestActions: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create(self, client: Mobilerun) -> None: + action = client.workflows.actions.create( + catalog_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + name="x", + ) + assert_matches_type(ActionCreateResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_with_all_params(self, client: Mobilerun) -> None: + action = client.workflows.actions.create( + catalog_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + name="x", + description="description", + params={"foo": "bar"}, + ) + assert_matches_type(ActionCreateResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: Mobilerun) -> None: + response = client.workflows.actions.with_raw_response.create( + catalog_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = response.parse() + assert_matches_type(ActionCreateResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: Mobilerun) -> None: + with client.workflows.actions.with_streaming_response.create( + catalog_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = response.parse() + assert_matches_type(ActionCreateResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve(self, client: Mobilerun) -> None: + action = client.workflows.actions.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ActionRetrieveResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve(self, client: Mobilerun) -> None: + response = client.workflows.actions.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = response.parse() + assert_matches_type(ActionRetrieveResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve(self, client: Mobilerun) -> None: + with client.workflows.actions.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = response.parse() + assert_matches_type(ActionRetrieveResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_retrieve(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `action_id` but received ''"): + client.workflows.actions.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update(self, client: Mobilerun) -> None: + action = client.workflows.actions.update( + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ActionUpdateResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update_with_all_params(self, client: Mobilerun) -> None: + action = client.workflows.actions.update( + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + description="description", + name="x", + params={"foo": "bar"}, + ) + assert_matches_type(ActionUpdateResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_update(self, client: Mobilerun) -> None: + response = client.workflows.actions.with_raw_response.update( + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = response.parse() + assert_matches_type(ActionUpdateResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_update(self, client: Mobilerun) -> None: + with client.workflows.actions.with_streaming_response.update( + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = response.parse() + assert_matches_type(ActionUpdateResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_update(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `action_id` but received ''"): + client.workflows.actions.with_raw_response.update( + action_id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + action = client.workflows.actions.list() + assert_matches_type(ActionListResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Mobilerun) -> None: + action = client.workflows.actions.list( + order_by="name", + order_by_direction="asc", + page=1, + page_size=1, + search="search", + service="tasks_api", + ) + assert_matches_type(ActionListResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.workflows.actions.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = response.parse() + assert_matches_type(ActionListResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.workflows.actions.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = response.parse() + assert_matches_type(ActionListResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete(self, client: Mobilerun) -> None: + action = client.workflows.actions.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ActionDeleteResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete(self, client: Mobilerun) -> None: + response = client.workflows.actions.with_raw_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = response.parse() + assert_matches_type(ActionDeleteResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete(self, client: Mobilerun) -> None: + with client.workflows.actions.with_streaming_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = response.parse() + assert_matches_type(ActionDeleteResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_delete(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `action_id` but received ''"): + client.workflows.actions.with_raw_response.delete( + "", + ) + + +class TestAsyncActions: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create(self, async_client: AsyncMobilerun) -> None: + action = await async_client.workflows.actions.create( + catalog_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + name="x", + ) + assert_matches_type(ActionCreateResponse, action, 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: + action = await async_client.workflows.actions.create( + catalog_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + name="x", + description="description", + params={"foo": "bar"}, + ) + assert_matches_type(ActionCreateResponse, action, path=["response"]) + + @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.workflows.actions.with_raw_response.create( + catalog_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = await response.parse() + assert_matches_type(ActionCreateResponse, action, path=["response"]) + + @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.workflows.actions.with_streaming_response.create( + catalog_entry_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = await response.parse() + assert_matches_type(ActionCreateResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve(self, async_client: AsyncMobilerun) -> None: + action = await async_client.workflows.actions.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ActionRetrieveResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.actions.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = await response.parse() + assert_matches_type(ActionRetrieveResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.actions.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = await response.parse() + assert_matches_type(ActionRetrieveResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `action_id` but received ''"): + await async_client.workflows.actions.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update(self, async_client: AsyncMobilerun) -> None: + action = await async_client.workflows.actions.update( + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ActionUpdateResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncMobilerun) -> None: + action = await async_client.workflows.actions.update( + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + description="description", + name="x", + params={"foo": "bar"}, + ) + assert_matches_type(ActionUpdateResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_update(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.actions.with_raw_response.update( + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = await response.parse() + assert_matches_type(ActionUpdateResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_update(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.actions.with_streaming_response.update( + action_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = await response.parse() + assert_matches_type(ActionUpdateResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_update(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `action_id` but received ''"): + await async_client.workflows.actions.with_raw_response.update( + action_id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + action = await async_client.workflows.actions.list() + assert_matches_type(ActionListResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: + action = await async_client.workflows.actions.list( + order_by="name", + order_by_direction="asc", + page=1, + page_size=1, + search="search", + service="tasks_api", + ) + assert_matches_type(ActionListResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.actions.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = await response.parse() + assert_matches_type(ActionListResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.actions.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = await response.parse() + assert_matches_type(ActionListResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete(self, async_client: AsyncMobilerun) -> None: + action = await async_client.workflows.actions.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ActionDeleteResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.actions.with_raw_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + action = await response.parse() + assert_matches_type(ActionDeleteResponse, action, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.actions.with_streaming_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + action = await response.parse() + assert_matches_type(ActionDeleteResponse, action, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_delete(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `action_id` but received ''"): + await async_client.workflows.actions.with_raw_response.delete( + "", + ) diff --git a/tests/api_resources/workflows/test_events.py b/tests/api_resources/workflows/test_events.py new file mode 100644 index 0000000..8ca70fa --- /dev/null +++ b/tests/api_resources/workflows/test_events.py @@ -0,0 +1,203 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.workflows import ( + EventDryRunResponse, + EventIngestResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestEvents: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_dry_run(self, client: Mobilerun) -> None: + event = client.workflows.events.dry_run( + event_type="x", + ) + assert_matches_type(EventDryRunResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_dry_run_with_all_params(self, client: Mobilerun) -> None: + event = client.workflows.events.dry_run( + event_type="x", + device_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payload={"foo": "bar"}, + ) + assert_matches_type(EventDryRunResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_dry_run(self, client: Mobilerun) -> None: + response = client.workflows.events.with_raw_response.dry_run( + event_type="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + event = response.parse() + assert_matches_type(EventDryRunResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_dry_run(self, client: Mobilerun) -> None: + with client.workflows.events.with_streaming_response.dry_run( + event_type="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + event = response.parse() + assert_matches_type(EventDryRunResponse, event, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_ingest(self, client: Mobilerun) -> None: + event = client.workflows.events.ingest( + event_type="x", + ) + assert_matches_type(EventIngestResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_ingest_with_all_params(self, client: Mobilerun) -> None: + event = client.workflows.events.ingest( + event_type="x", + device_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payload={"foo": "bar"}, + ) + assert_matches_type(EventIngestResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_ingest(self, client: Mobilerun) -> None: + response = client.workflows.events.with_raw_response.ingest( + event_type="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + event = response.parse() + assert_matches_type(EventIngestResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_ingest(self, client: Mobilerun) -> None: + with client.workflows.events.with_streaming_response.ingest( + event_type="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + event = response.parse() + assert_matches_type(EventIngestResponse, event, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncEvents: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_dry_run(self, async_client: AsyncMobilerun) -> None: + event = await async_client.workflows.events.dry_run( + event_type="x", + ) + assert_matches_type(EventDryRunResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_dry_run_with_all_params(self, async_client: AsyncMobilerun) -> None: + event = await async_client.workflows.events.dry_run( + event_type="x", + device_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payload={"foo": "bar"}, + ) + assert_matches_type(EventDryRunResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_dry_run(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.events.with_raw_response.dry_run( + event_type="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + event = await response.parse() + assert_matches_type(EventDryRunResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_dry_run(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.events.with_streaming_response.dry_run( + event_type="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + event = await response.parse() + assert_matches_type(EventDryRunResponse, event, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_ingest(self, async_client: AsyncMobilerun) -> None: + event = await async_client.workflows.events.ingest( + event_type="x", + ) + assert_matches_type(EventIngestResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_ingest_with_all_params(self, async_client: AsyncMobilerun) -> None: + event = await async_client.workflows.events.ingest( + event_type="x", + device_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payload={"foo": "bar"}, + ) + assert_matches_type(EventIngestResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_ingest(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.events.with_raw_response.ingest( + event_type="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + event = await response.parse() + assert_matches_type(EventIngestResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_ingest(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.events.with_streaming_response.ingest( + event_type="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + event = await response.parse() + assert_matches_type(EventIngestResponse, event, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/workflows/test_executions.py b/tests/api_resources/workflows/test_executions.py new file mode 100644 index 0000000..891bd9b --- /dev/null +++ b/tests/api_resources/workflows/test_executions.py @@ -0,0 +1,280 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.workflows import ( + ExecutionListResponse, + ExecutionRetrieveResponse, + ExecutionGetMetricsResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestExecutions: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve(self, client: Mobilerun) -> None: + execution = client.workflows.executions.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ExecutionRetrieveResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve(self, client: Mobilerun) -> None: + response = client.workflows.executions.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + execution = response.parse() + assert_matches_type(ExecutionRetrieveResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve(self, client: Mobilerun) -> None: + with client.workflows.executions.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + execution = response.parse() + assert_matches_type(ExecutionRetrieveResponse, execution, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_retrieve(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `execution_id` but received ''"): + client.workflows.executions.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + execution = client.workflows.executions.list() + assert_matches_type(ExecutionListResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Mobilerun) -> None: + execution = client.workflows.executions.list( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + from_="from", + order_by="startedAt", + order_by_direction="asc", + page=1, + page_size=1, + search="search", + status="pending", + to="to", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ExecutionListResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.workflows.executions.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + execution = response.parse() + assert_matches_type(ExecutionListResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.workflows.executions.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + execution = response.parse() + assert_matches_type(ExecutionListResponse, execution, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_metrics(self, client: Mobilerun) -> None: + execution = client.workflows.executions.get_metrics() + assert_matches_type(ExecutionGetMetricsResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_metrics_with_all_params(self, client: Mobilerun) -> None: + execution = client.workflows.executions.get_metrics( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + from_="from", + to="to", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ExecutionGetMetricsResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_metrics(self, client: Mobilerun) -> None: + response = client.workflows.executions.with_raw_response.get_metrics() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + execution = response.parse() + assert_matches_type(ExecutionGetMetricsResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_metrics(self, client: Mobilerun) -> None: + with client.workflows.executions.with_streaming_response.get_metrics() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + execution = response.parse() + assert_matches_type(ExecutionGetMetricsResponse, execution, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncExecutions: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve(self, async_client: AsyncMobilerun) -> None: + execution = await async_client.workflows.executions.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ExecutionRetrieveResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.executions.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + execution = await response.parse() + assert_matches_type(ExecutionRetrieveResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.executions.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + execution = await response.parse() + assert_matches_type(ExecutionRetrieveResponse, execution, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `execution_id` but received ''"): + await async_client.workflows.executions.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + execution = await async_client.workflows.executions.list() + assert_matches_type(ExecutionListResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: + execution = await async_client.workflows.executions.list( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + from_="from", + order_by="startedAt", + order_by_direction="asc", + page=1, + page_size=1, + search="search", + status="pending", + to="to", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ExecutionListResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.executions.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + execution = await response.parse() + assert_matches_type(ExecutionListResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.executions.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + execution = await response.parse() + assert_matches_type(ExecutionListResponse, execution, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_metrics(self, async_client: AsyncMobilerun) -> None: + execution = await async_client.workflows.executions.get_metrics() + assert_matches_type(ExecutionGetMetricsResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_metrics_with_all_params(self, async_client: AsyncMobilerun) -> None: + execution = await async_client.workflows.executions.get_metrics( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + from_="from", + to="to", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ExecutionGetMetricsResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_metrics(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.executions.with_raw_response.get_metrics() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + execution = await response.parse() + assert_matches_type(ExecutionGetMetricsResponse, execution, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_metrics(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.executions.with_streaming_response.get_metrics() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + execution = await response.parse() + assert_matches_type(ExecutionGetMetricsResponse, execution, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/workflows/test_flows.py b/tests/api_resources/workflows/test_flows.py new file mode 100644 index 0000000..9eaee1d --- /dev/null +++ b/tests/api_resources/workflows/test_flows.py @@ -0,0 +1,673 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.workflows import ( + FlowListResponse, + FlowCloneResponse, + FlowCreateResponse, + FlowDeleteResponse, + FlowUpdateResponse, + FlowRetrieveResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestFlows: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create(self, client: Mobilerun) -> None: + flow = client.workflows.flows.create( + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + } + ], + name="x", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowCreateResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_with_all_params(self, client: Mobilerun) -> None: + flow = client.workflows.flows.create( + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + "children": [ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + "continue_on_error": True, + "device_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "name_override": "x", + "overrides": {"params": {"foo": "bar"}}, + } + ], + "continue_on_error": True, + "device_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "name_override": "x", + "overrides": {"params": {"foo": "bar"}}, + } + ], + name="x", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + cooldown_scope="flow", + cooldown_seconds=0, + description="description", + enabled=True, + ) + assert_matches_type(FlowCreateResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: Mobilerun) -> None: + response = client.workflows.flows.with_raw_response.create( + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + } + ], + name="x", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + flow = response.parse() + assert_matches_type(FlowCreateResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: Mobilerun) -> None: + with client.workflows.flows.with_streaming_response.create( + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + } + ], + name="x", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + flow = response.parse() + assert_matches_type(FlowCreateResponse, flow, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve(self, client: Mobilerun) -> None: + flow = client.workflows.flows.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowRetrieveResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve(self, client: Mobilerun) -> None: + response = client.workflows.flows.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + flow = response.parse() + assert_matches_type(FlowRetrieveResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve(self, client: Mobilerun) -> None: + with client.workflows.flows.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + flow = response.parse() + assert_matches_type(FlowRetrieveResponse, flow, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_retrieve(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + client.workflows.flows.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update(self, client: Mobilerun) -> None: + flow = client.workflows.flows.update( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowUpdateResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update_with_all_params(self, client: Mobilerun) -> None: + flow = client.workflows.flows.update( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + cooldown_scope="flow", + cooldown_seconds=0, + description="description", + enabled=True, + name="x", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowUpdateResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_update(self, client: Mobilerun) -> None: + response = client.workflows.flows.with_raw_response.update( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + flow = response.parse() + assert_matches_type(FlowUpdateResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_update(self, client: Mobilerun) -> None: + with client.workflows.flows.with_streaming_response.update( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + flow = response.parse() + assert_matches_type(FlowUpdateResponse, flow, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_update(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + client.workflows.flows.with_raw_response.update( + flow_id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + flow = client.workflows.flows.list() + assert_matches_type(FlowListResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Mobilerun) -> None: + flow = client.workflows.flows.list( + enabled=True, + order_by="name", + order_by_direction="asc", + page=1, + page_size=1, + search="search", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowListResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.workflows.flows.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + flow = response.parse() + assert_matches_type(FlowListResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.workflows.flows.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + flow = response.parse() + assert_matches_type(FlowListResponse, flow, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete(self, client: Mobilerun) -> None: + flow = client.workflows.flows.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowDeleteResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete(self, client: Mobilerun) -> None: + response = client.workflows.flows.with_raw_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + flow = response.parse() + assert_matches_type(FlowDeleteResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete(self, client: Mobilerun) -> None: + with client.workflows.flows.with_streaming_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + flow = response.parse() + assert_matches_type(FlowDeleteResponse, flow, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_delete(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + client.workflows.flows.with_raw_response.delete( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_clone(self, client: Mobilerun) -> None: + flow = client.workflows.flows.clone( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowCloneResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_clone_with_all_params(self, client: Mobilerun) -> None: + flow = client.workflows.flows.clone( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + name="x", + ) + assert_matches_type(FlowCloneResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_clone(self, client: Mobilerun) -> None: + response = client.workflows.flows.with_raw_response.clone( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + flow = response.parse() + assert_matches_type(FlowCloneResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_clone(self, client: Mobilerun) -> None: + with client.workflows.flows.with_streaming_response.clone( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + flow = response.parse() + assert_matches_type(FlowCloneResponse, flow, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_clone(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + client.workflows.flows.with_raw_response.clone( + flow_id="", + ) + + +class TestAsyncFlows: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create(self, async_client: AsyncMobilerun) -> None: + flow = await async_client.workflows.flows.create( + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + } + ], + name="x", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowCreateResponse, flow, 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: + flow = await async_client.workflows.flows.create( + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + "children": [ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + "continue_on_error": True, + "device_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "name_override": "x", + "overrides": {"params": {"foo": "bar"}}, + } + ], + "continue_on_error": True, + "device_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "name_override": "x", + "overrides": {"params": {"foo": "bar"}}, + } + ], + name="x", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + cooldown_scope="flow", + cooldown_seconds=0, + description="description", + enabled=True, + ) + assert_matches_type(FlowCreateResponse, flow, path=["response"]) + + @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.workflows.flows.with_raw_response.create( + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + } + ], + name="x", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + flow = await response.parse() + assert_matches_type(FlowCreateResponse, flow, path=["response"]) + + @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.workflows.flows.with_streaming_response.create( + actions=[ + { + "action_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "position": 0, + } + ], + name="x", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + flow = await response.parse() + assert_matches_type(FlowCreateResponse, flow, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve(self, async_client: AsyncMobilerun) -> None: + flow = await async_client.workflows.flows.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowRetrieveResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.flows.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + flow = await response.parse() + assert_matches_type(FlowRetrieveResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.flows.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + flow = await response.parse() + assert_matches_type(FlowRetrieveResponse, flow, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + await async_client.workflows.flows.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update(self, async_client: AsyncMobilerun) -> None: + flow = await async_client.workflows.flows.update( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowUpdateResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncMobilerun) -> None: + flow = await async_client.workflows.flows.update( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + cooldown_scope="flow", + cooldown_seconds=0, + description="description", + enabled=True, + name="x", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowUpdateResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_update(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.flows.with_raw_response.update( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + flow = await response.parse() + assert_matches_type(FlowUpdateResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_update(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.flows.with_streaming_response.update( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + flow = await response.parse() + assert_matches_type(FlowUpdateResponse, flow, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_update(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + await async_client.workflows.flows.with_raw_response.update( + flow_id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + flow = await async_client.workflows.flows.list() + assert_matches_type(FlowListResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: + flow = await async_client.workflows.flows.list( + enabled=True, + order_by="name", + order_by_direction="asc", + page=1, + page_size=1, + search="search", + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowListResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.flows.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + flow = await response.parse() + assert_matches_type(FlowListResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.flows.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + flow = await response.parse() + assert_matches_type(FlowListResponse, flow, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete(self, async_client: AsyncMobilerun) -> None: + flow = await async_client.workflows.flows.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowDeleteResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.flows.with_raw_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + flow = await response.parse() + assert_matches_type(FlowDeleteResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.flows.with_streaming_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + flow = await response.parse() + assert_matches_type(FlowDeleteResponse, flow, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_delete(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + await async_client.workflows.flows.with_raw_response.delete( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_clone(self, async_client: AsyncMobilerun) -> None: + flow = await async_client.workflows.flows.clone( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowCloneResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_clone_with_all_params(self, async_client: AsyncMobilerun) -> None: + flow = await async_client.workflows.flows.clone( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + name="x", + ) + assert_matches_type(FlowCloneResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_clone(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.flows.with_raw_response.clone( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + flow = await response.parse() + assert_matches_type(FlowCloneResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_clone(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.flows.with_streaming_response.clone( + flow_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + flow = await response.parse() + assert_matches_type(FlowCloneResponse, flow, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_clone(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + await async_client.workflows.flows.with_raw_response.clone( + flow_id="", + ) diff --git a/tests/api_resources/workflows/test_secrets.py b/tests/api_resources/workflows/test_secrets.py new file mode 100644 index 0000000..6d98cae --- /dev/null +++ b/tests/api_resources/workflows/test_secrets.py @@ -0,0 +1,262 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.workflows import ( + SecretListResponse, + SecretCreateResponse, + SecretDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestSecrets: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create(self, client: Mobilerun) -> None: + secret = client.workflows.secrets.create( + name="name", + value="x", + ) + assert_matches_type(SecretCreateResponse, secret, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_with_all_params(self, client: Mobilerun) -> None: + secret = client.workflows.secrets.create( + name="name", + value="x", + description="description", + ) + assert_matches_type(SecretCreateResponse, secret, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: Mobilerun) -> None: + response = client.workflows.secrets.with_raw_response.create( + name="name", + value="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + secret = response.parse() + assert_matches_type(SecretCreateResponse, secret, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: Mobilerun) -> None: + with client.workflows.secrets.with_streaming_response.create( + name="name", + value="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + secret = response.parse() + assert_matches_type(SecretCreateResponse, secret, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + secret = client.workflows.secrets.list() + assert_matches_type(SecretListResponse, secret, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.workflows.secrets.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + secret = response.parse() + assert_matches_type(SecretListResponse, secret, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.workflows.secrets.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + secret = response.parse() + assert_matches_type(SecretListResponse, secret, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete(self, client: Mobilerun) -> None: + secret = client.workflows.secrets.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(SecretDeleteResponse, secret, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete(self, client: Mobilerun) -> None: + response = client.workflows.secrets.with_raw_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + secret = response.parse() + assert_matches_type(SecretDeleteResponse, secret, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete(self, client: Mobilerun) -> None: + with client.workflows.secrets.with_streaming_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + secret = response.parse() + assert_matches_type(SecretDeleteResponse, secret, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_delete(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `secret_id` but received ''"): + client.workflows.secrets.with_raw_response.delete( + "", + ) + + +class TestAsyncSecrets: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create(self, async_client: AsyncMobilerun) -> None: + secret = await async_client.workflows.secrets.create( + name="name", + value="x", + ) + assert_matches_type(SecretCreateResponse, secret, 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: + secret = await async_client.workflows.secrets.create( + name="name", + value="x", + description="description", + ) + assert_matches_type(SecretCreateResponse, secret, path=["response"]) + + @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.workflows.secrets.with_raw_response.create( + name="name", + value="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + secret = await response.parse() + assert_matches_type(SecretCreateResponse, secret, path=["response"]) + + @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.workflows.secrets.with_streaming_response.create( + name="name", + value="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + secret = await response.parse() + assert_matches_type(SecretCreateResponse, secret, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + secret = await async_client.workflows.secrets.list() + assert_matches_type(SecretListResponse, secret, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.secrets.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + secret = await response.parse() + assert_matches_type(SecretListResponse, secret, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.secrets.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + secret = await response.parse() + assert_matches_type(SecretListResponse, secret, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete(self, async_client: AsyncMobilerun) -> None: + secret = await async_client.workflows.secrets.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(SecretDeleteResponse, secret, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.secrets.with_raw_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + secret = await response.parse() + assert_matches_type(SecretDeleteResponse, secret, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.secrets.with_streaming_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + secret = await response.parse() + assert_matches_type(SecretDeleteResponse, secret, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_delete(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `secret_id` but received ''"): + await async_client.workflows.secrets.with_raw_response.delete( + "", + ) diff --git a/tests/api_resources/workflows/test_timezones.py b/tests/api_resources/workflows/test_timezones.py new file mode 100644 index 0000000..fab060b --- /dev/null +++ b/tests/api_resources/workflows/test_timezones.py @@ -0,0 +1,80 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.workflows import TimezoneListResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestTimezones: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + timezone = client.workflows.timezones.list() + assert_matches_type(TimezoneListResponse, timezone, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.workflows.timezones.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + timezone = response.parse() + assert_matches_type(TimezoneListResponse, timezone, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.workflows.timezones.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + timezone = response.parse() + assert_matches_type(TimezoneListResponse, timezone, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncTimezones: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + timezone = await async_client.workflows.timezones.list() + assert_matches_type(TimezoneListResponse, timezone, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.timezones.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + timezone = await response.parse() + assert_matches_type(TimezoneListResponse, timezone, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.timezones.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + timezone = await response.parse() + assert_matches_type(TimezoneListResponse, timezone, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/workflows/test_triggers.py b/tests/api_resources/workflows/test_triggers.py new file mode 100644 index 0000000..9a71326 --- /dev/null +++ b/tests/api_resources/workflows/test_triggers.py @@ -0,0 +1,647 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.workflows import ( + TriggerFireResponse, + TriggerListResponse, + TriggerCreateResponse, + TriggerDeleteResponse, + TriggerUpdateResponse, + TriggerRetrieveResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestTriggers: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create(self, client: Mobilerun) -> None: + trigger = client.workflows.triggers.create( + activation="event", + name="x", + ) + assert_matches_type(TriggerCreateResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_with_all_params(self, client: Mobilerun) -> None: + trigger = client.workflows.triggers.create( + activation="event", + name="x", + conditions={ + "all": [{}], + "any": [{}], + }, + custom_payload_schema={"foo": "bar"}, + description="description", + event_type="eventType", + schedule_rule={ + "type": "once", + "date_time": "dateTime", + "expression": "expression", + "rrule": "rrule", + }, + timezone="timezone", + ) + assert_matches_type(TriggerCreateResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: Mobilerun) -> None: + response = client.workflows.triggers.with_raw_response.create( + activation="event", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + trigger = response.parse() + assert_matches_type(TriggerCreateResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: Mobilerun) -> None: + with client.workflows.triggers.with_streaming_response.create( + activation="event", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + trigger = response.parse() + assert_matches_type(TriggerCreateResponse, trigger, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve(self, client: Mobilerun) -> None: + trigger = client.workflows.triggers.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(TriggerRetrieveResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve(self, client: Mobilerun) -> None: + response = client.workflows.triggers.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + trigger = response.parse() + assert_matches_type(TriggerRetrieveResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve(self, client: Mobilerun) -> None: + with client.workflows.triggers.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + trigger = response.parse() + assert_matches_type(TriggerRetrieveResponse, trigger, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_retrieve(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `trigger_id` but received ''"): + client.workflows.triggers.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update(self, client: Mobilerun) -> None: + trigger = client.workflows.triggers.update( + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(TriggerUpdateResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update_with_all_params(self, client: Mobilerun) -> None: + trigger = client.workflows.triggers.update( + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + activation="event", + conditions={ + "all": [{}], + "any": [{}], + }, + custom_payload_schema={"foo": "bar"}, + description="description", + event_type="eventType", + name="x", + schedule_rule={ + "type": "once", + "date_time": "dateTime", + "expression": "expression", + "rrule": "rrule", + }, + timezone="timezone", + ) + assert_matches_type(TriggerUpdateResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_update(self, client: Mobilerun) -> None: + response = client.workflows.triggers.with_raw_response.update( + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + trigger = response.parse() + assert_matches_type(TriggerUpdateResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_update(self, client: Mobilerun) -> None: + with client.workflows.triggers.with_streaming_response.update( + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + trigger = response.parse() + assert_matches_type(TriggerUpdateResponse, trigger, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_update(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `trigger_id` but received ''"): + client.workflows.triggers.with_raw_response.update( + trigger_id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + trigger = client.workflows.triggers.list() + assert_matches_type(TriggerListResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Mobilerun) -> None: + trigger = client.workflows.triggers.list( + activation="event", + event_type="eventType", + order_by="name", + order_by_direction="asc", + page=1, + page_size=1, + search="search", + ) + assert_matches_type(TriggerListResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.workflows.triggers.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + trigger = response.parse() + assert_matches_type(TriggerListResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.workflows.triggers.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + trigger = response.parse() + assert_matches_type(TriggerListResponse, trigger, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete(self, client: Mobilerun) -> None: + trigger = client.workflows.triggers.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(TriggerDeleteResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete(self, client: Mobilerun) -> None: + response = client.workflows.triggers.with_raw_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + trigger = response.parse() + assert_matches_type(TriggerDeleteResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete(self, client: Mobilerun) -> None: + with client.workflows.triggers.with_streaming_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + trigger = response.parse() + assert_matches_type(TriggerDeleteResponse, trigger, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_delete(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `trigger_id` but received ''"): + client.workflows.triggers.with_raw_response.delete( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_fire(self, client: Mobilerun) -> None: + trigger = client.workflows.triggers.fire( + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payload={"foo": "bar"}, + ) + 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"}, + device_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: + response = client.workflows.triggers.with_raw_response.fire( + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payload={"foo": "bar"}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + trigger = response.parse() + assert_matches_type(TriggerFireResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_fire(self, client: Mobilerun) -> None: + with client.workflows.triggers.with_streaming_response.fire( + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payload={"foo": "bar"}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + trigger = response.parse() + assert_matches_type(TriggerFireResponse, trigger, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_fire(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `trigger_id` but received ''"): + client.workflows.triggers.with_raw_response.fire( + trigger_id="", + payload={"foo": "bar"}, + ) + + +class TestAsyncTriggers: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create(self, async_client: AsyncMobilerun) -> None: + trigger = await async_client.workflows.triggers.create( + activation="event", + name="x", + ) + assert_matches_type(TriggerCreateResponse, trigger, 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: + trigger = await async_client.workflows.triggers.create( + activation="event", + name="x", + conditions={ + "all": [{}], + "any": [{}], + }, + custom_payload_schema={"foo": "bar"}, + description="description", + event_type="eventType", + schedule_rule={ + "type": "once", + "date_time": "dateTime", + "expression": "expression", + "rrule": "rrule", + }, + timezone="timezone", + ) + assert_matches_type(TriggerCreateResponse, trigger, path=["response"]) + + @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.workflows.triggers.with_raw_response.create( + activation="event", + name="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + trigger = await response.parse() + assert_matches_type(TriggerCreateResponse, trigger, path=["response"]) + + @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.workflows.triggers.with_streaming_response.create( + activation="event", + name="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + trigger = await response.parse() + assert_matches_type(TriggerCreateResponse, trigger, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve(self, async_client: AsyncMobilerun) -> None: + trigger = await async_client.workflows.triggers.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(TriggerRetrieveResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.triggers.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + trigger = await response.parse() + assert_matches_type(TriggerRetrieveResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.triggers.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + trigger = await response.parse() + assert_matches_type(TriggerRetrieveResponse, trigger, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `trigger_id` but received ''"): + await async_client.workflows.triggers.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update(self, async_client: AsyncMobilerun) -> None: + trigger = await async_client.workflows.triggers.update( + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(TriggerUpdateResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncMobilerun) -> None: + trigger = await async_client.workflows.triggers.update( + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + activation="event", + conditions={ + "all": [{}], + "any": [{}], + }, + custom_payload_schema={"foo": "bar"}, + description="description", + event_type="eventType", + name="x", + schedule_rule={ + "type": "once", + "date_time": "dateTime", + "expression": "expression", + "rrule": "rrule", + }, + timezone="timezone", + ) + assert_matches_type(TriggerUpdateResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_update(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.triggers.with_raw_response.update( + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + trigger = await response.parse() + assert_matches_type(TriggerUpdateResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_update(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.triggers.with_streaming_response.update( + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + trigger = await response.parse() + assert_matches_type(TriggerUpdateResponse, trigger, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_update(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `trigger_id` but received ''"): + await async_client.workflows.triggers.with_raw_response.update( + trigger_id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + trigger = await async_client.workflows.triggers.list() + assert_matches_type(TriggerListResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: + trigger = await async_client.workflows.triggers.list( + activation="event", + event_type="eventType", + order_by="name", + order_by_direction="asc", + page=1, + page_size=1, + search="search", + ) + assert_matches_type(TriggerListResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.triggers.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + trigger = await response.parse() + assert_matches_type(TriggerListResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.triggers.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + trigger = await response.parse() + assert_matches_type(TriggerListResponse, trigger, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete(self, async_client: AsyncMobilerun) -> None: + trigger = await async_client.workflows.triggers.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(TriggerDeleteResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.triggers.with_raw_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + trigger = await response.parse() + assert_matches_type(TriggerDeleteResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.triggers.with_streaming_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + trigger = await response.parse() + assert_matches_type(TriggerDeleteResponse, trigger, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_delete(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `trigger_id` but received ''"): + await async_client.workflows.triggers.with_raw_response.delete( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_fire(self, async_client: AsyncMobilerun) -> None: + trigger = await async_client.workflows.triggers.fire( + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payload={"foo": "bar"}, + ) + 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"}, + device_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: + response = await async_client.workflows.triggers.with_raw_response.fire( + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payload={"foo": "bar"}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + trigger = await response.parse() + assert_matches_type(TriggerFireResponse, trigger, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_fire(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.triggers.with_streaming_response.fire( + trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payload={"foo": "bar"}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + trigger = await response.parse() + assert_matches_type(TriggerFireResponse, trigger, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_fire(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `trigger_id` but received ''"): + await async_client.workflows.triggers.with_raw_response.fire( + trigger_id="", + payload={"foo": "bar"}, + ) From 1a4d40df9fc939af3fc0c1cd7885b450821b7ce2 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 09:58:42 +0000 Subject: [PATCH 10/21] feat(api): manual updates --- .stats.yml | 4 +- api.md | 1 + src/mobilerun_sdk/types/__init__.py | 13 +++ src/mobilerun_sdk/types/devices/__init__.py | 1 + src/mobilerun_sdk/types/devices/a11_y_node.py | 57 ++++++++++ .../types/devices/state_ui_response.py | 107 ++---------------- 6 files changed, 82 insertions(+), 101 deletions(-) create mode 100644 src/mobilerun_sdk/types/devices/a11_y_node.py diff --git a/.stats.yml b/.stats.yml index 68ccaa5..18aefa3 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 143 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-69e013739016ee44f75587844c51a010330e3a22c0e7e2cd0a43c3194753ce33.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-29b2aedbd6d3e74988cec63ba7404df2183a229e895764bd46faf497882ce267.yml openapi_spec_hash: f4c5ba7f704b9a2c5257a629118511af -config_hash: ca9f428d668195546c3a4e1f5faf1abc +config_hash: f78cc66571fe684b918fdab0f4cdf6a7 diff --git a/api.md b/api.md index f4c61d4..50be192 100644 --- a/api.md +++ b/api.md @@ -295,6 +295,7 @@ Types: ```python from mobilerun_sdk.types.devices import ( + A11YNode, Rect, StateScreenshotResponse, StateTimeResponse, diff --git a/src/mobilerun_sdk/types/__init__.py b/src/mobilerun_sdk/types/__init__.py index e2f5b3b..e641405 100644 --- a/src/mobilerun_sdk/types/__init__.py +++ b/src/mobilerun_sdk/types/__init__.py @@ -2,6 +2,8 @@ from __future__ import annotations +from . import devices +from .. import _compat from .flow import Flow as Flow from .task import Task as Task from .device import Device as Device @@ -91,3 +93,14 @@ from .hook_get_sample_data_response import HookGetSampleDataResponse as HookGetSampleDataResponse from .app_create_signed_upload_url_params import AppCreateSignedUploadURLParams as AppCreateSignedUploadURLParams from .app_create_signed_upload_url_response import AppCreateSignedUploadURLResponse as AppCreateSignedUploadURLResponse + +# Rebuild cyclical models only after all modules are imported. +# This ensures that, when building the deferred (due to cyclical references) model schema, +# Pydantic can resolve the necessary references. +# See: https://github.com/pydantic/pydantic/issues/11250 for more context. +if _compat.PYDANTIC_V1: + devices.a11_y_node.A11YNode.update_forward_refs() # type: ignore + devices.state_ui_response.StateUiResponse.update_forward_refs() # type: ignore +else: + devices.a11_y_node.A11YNode.model_rebuild(_parent_namespace_depth=0) + devices.state_ui_response.StateUiResponse.model_rebuild(_parent_namespace_depth=0) diff --git a/src/mobilerun_sdk/types/devices/__init__.py b/src/mobilerun_sdk/types/devices/__init__.py index ea98848..8d4f005 100644 --- a/src/mobilerun_sdk/types/devices/__init__.py +++ b/src/mobilerun_sdk/types/devices/__init__.py @@ -4,6 +4,7 @@ from .rect import Rect as Rect from .file_info import FileInfo as FileInfo +from .a11_y_node import A11YNode as A11YNode from .app_list_params import AppListParams as AppListParams from .state_ui_params import StateUiParams as StateUiParams from .app_start_params import AppStartParams as AppStartParams diff --git a/src/mobilerun_sdk/types/devices/a11_y_node.py b/src/mobilerun_sdk/types/devices/a11_y_node.py new file mode 100644 index 0000000..aa4eb12 --- /dev/null +++ b/src/mobilerun_sdk/types/devices/a11_y_node.py @@ -0,0 +1,57 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["A11YNode", "BoundsInScreen"] + + +class BoundsInScreen(BaseModel): + bottom: int + + left: int + + right: int + + top: int + + +class A11YNode(BaseModel): + bounds_in_screen: BoundsInScreen = FieldInfo(alias="boundsInScreen") + + children: Optional[List["A11YNode"]] = None + + class_name: str = FieldInfo(alias="className") + + content_description: str = FieldInfo(alias="contentDescription") + + is_checkable: bool = FieldInfo(alias="isCheckable") + + is_checked: bool = FieldInfo(alias="isChecked") + + is_clickable: bool = FieldInfo(alias="isClickable") + + is_enabled: bool = FieldInfo(alias="isEnabled") + + is_focusable: bool = FieldInfo(alias="isFocusable") + + is_focused: bool = FieldInfo(alias="isFocused") + + is_long_clickable: bool = FieldInfo(alias="isLongClickable") + + is_password: bool = FieldInfo(alias="isPassword") + + is_scrollable: bool = FieldInfo(alias="isScrollable") + + is_selected: bool = FieldInfo(alias="isSelected") + + package_name: str = FieldInfo(alias="packageName") + + resource_id: str = FieldInfo(alias="resourceId") + + text: str diff --git a/src/mobilerun_sdk/types/devices/state_ui_response.py b/src/mobilerun_sdk/types/devices/state_ui_response.py index 80cbe44..54fa0bc 100644 --- a/src/mobilerun_sdk/types/devices/state_ui_response.py +++ b/src/mobilerun_sdk/types/devices/state_ui_response.py @@ -1,6 +1,8 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from __future__ import annotations + +from typing import Optional from pydantic import Field as FieldInfo @@ -9,64 +11,14 @@ __all__ = [ "StateUiResponse", - "A11yTree", - "A11yTreeBoundsInScreen", "DeviceContext", "DeviceContextDisplayMetrics", "DeviceContextFilteringParams", - "ImeTree", - "ImeTreeBoundsInScreen", "PhoneState", "PhoneStateFocusedElement", ] -class A11yTreeBoundsInScreen(BaseModel): - bottom: int - - left: int - - right: int - - top: int - - -class A11yTree(BaseModel): - bounds_in_screen: A11yTreeBoundsInScreen = FieldInfo(alias="boundsInScreen") - - children: Optional[List[object]] = None - - class_name: str = FieldInfo(alias="className") - - content_description: str = FieldInfo(alias="contentDescription") - - is_checkable: bool = FieldInfo(alias="isCheckable") - - is_checked: bool = FieldInfo(alias="isChecked") - - is_clickable: bool = FieldInfo(alias="isClickable") - - is_enabled: bool = FieldInfo(alias="isEnabled") - - is_focusable: bool = FieldInfo(alias="isFocusable") - - is_focused: bool = FieldInfo(alias="isFocused") - - is_long_clickable: bool = FieldInfo(alias="isLongClickable") - - is_password: bool = FieldInfo(alias="isPassword") - - is_scrollable: bool = FieldInfo(alias="isScrollable") - - is_selected: bool = FieldInfo(alias="isSelected") - - package_name: str = FieldInfo(alias="packageName") - - resource_id: str = FieldInfo(alias="resourceId") - - text: str - - class DeviceContextDisplayMetrics(BaseModel): density: float @@ -93,52 +45,6 @@ class DeviceContext(BaseModel): screen_bounds: Rect -class ImeTreeBoundsInScreen(BaseModel): - bottom: int - - left: int - - right: int - - top: int - - -class ImeTree(BaseModel): - bounds_in_screen: ImeTreeBoundsInScreen = FieldInfo(alias="boundsInScreen") - - children: Optional[List[object]] = None - - class_name: str = FieldInfo(alias="className") - - content_description: str = FieldInfo(alias="contentDescription") - - is_checkable: bool = FieldInfo(alias="isCheckable") - - is_checked: bool = FieldInfo(alias="isChecked") - - is_clickable: bool = FieldInfo(alias="isClickable") - - is_enabled: bool = FieldInfo(alias="isEnabled") - - is_focusable: bool = FieldInfo(alias="isFocusable") - - is_focused: bool = FieldInfo(alias="isFocused") - - is_long_clickable: bool = FieldInfo(alias="isLongClickable") - - is_password: bool = FieldInfo(alias="isPassword") - - is_scrollable: bool = FieldInfo(alias="isScrollable") - - is_selected: bool = FieldInfo(alias="isSelected") - - package_name: str = FieldInfo(alias="packageName") - - resource_id: str = FieldInfo(alias="resourceId") - - text: str - - class PhoneStateFocusedElement(BaseModel): class_name: Optional[str] = FieldInfo(alias="className", default=None) @@ -162,13 +68,16 @@ class PhoneState(BaseModel): class StateUiResponse(BaseModel): - a11y_tree: A11yTree + a11y_tree: "A11YNode" device_context: DeviceContext - ime_tree: ImeTree + ime_tree: "A11YNode" phone_state: PhoneState schema_: Optional[str] = FieldInfo(alias="$schema", default=None) """A URL to the JSON Schema for this object.""" + + +from .a11_y_node import A11YNode From 080b0a8a668e792ddfc8f2ceacb30ca59ac0f45a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 17:14:27 +0000 Subject: [PATCH 11/21] feat(api): api update --- .stats.yml | 4 ++-- src/mobilerun_sdk/resources/workflows/flows/flows.py | 6 +++++- src/mobilerun_sdk/types/flow.py | 12 ++++++++++++ .../types/workflows/flow_list_params.py | 4 +++- tests/api_resources/workflows/test_flows.py | 2 ++ 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index 18aefa3..09b7cac 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 143 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-29b2aedbd6d3e74988cec63ba7404df2183a229e895764bd46faf497882ce267.yml -openapi_spec_hash: f4c5ba7f704b9a2c5257a629118511af +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-51306d6750b156a1d224698900dee021afc17d1409eebdf68224bbf67771734b.yml +openapi_spec_hash: a24ee8b1052dda1a219a4358e76cf40e config_hash: f78cc66571fe684b918fdab0f4cdf6a7 diff --git a/src/mobilerun_sdk/resources/workflows/flows/flows.py b/src/mobilerun_sdk/resources/workflows/flows/flows.py index 0130599..0458a01 100644 --- a/src/mobilerun_sdk/resources/workflows/flows/flows.py +++ b/src/mobilerun_sdk/resources/workflows/flows/flows.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Iterable, Optional +from typing import List, Iterable, Optional from typing_extensions import Literal import httpx @@ -202,6 +202,7 @@ def list( page: int | Omit = omit, page_size: int | Omit = omit, search: str | Omit = omit, + status: List[Literal["healthy", "failing", "blocked"]] | Omit = omit, trigger_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. @@ -237,6 +238,7 @@ def list( "page": page, "page_size": page_size, "search": search, + "status": status, "trigger_id": trigger_id, }, flow_list_params.FlowListParams, @@ -479,6 +481,7 @@ async def list( page: int | Omit = omit, page_size: int | Omit = omit, search: str | Omit = omit, + status: List[Literal["healthy", "failing", "blocked"]] | Omit = omit, trigger_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. @@ -514,6 +517,7 @@ async def list( "page": page, "page_size": page_size, "search": search, + "status": status, "trigger_id": trigger_id, }, flow_list_params.FlowListParams, diff --git a/src/mobilerun_sdk/types/flow.py b/src/mobilerun_sdk/types/flow.py index 98aad0c..908b874 100644 --- a/src/mobilerun_sdk/types/flow.py +++ b/src/mobilerun_sdk/types/flow.py @@ -13,6 +13,10 @@ class Flow(BaseModel): id: str + blocked_at: Optional[str] = FieldInfo(alias="blockedAt", default=None) + + consecutive_failures: int = FieldInfo(alias="consecutiveFailures") + cooldown_scope: Literal["flow", "device"] = FieldInfo(alias="cooldownScope") cooldown_seconds: Optional[int] = FieldInfo(alias="cooldownSeconds", default=None) @@ -23,10 +27,18 @@ class Flow(BaseModel): enabled: bool + last_failure_at: Optional[str] = FieldInfo(alias="lastFailureAt", default=None) + + last_failure_code: Optional[ + Literal["device_not_found", "permission_denied", "client_error", "transient", "logic"] + ] = FieldInfo(alias="lastFailureCode", default=None) + last_triggered_at: Optional[str] = FieldInfo(alias="lastTriggeredAt", default=None) name: str + status: Literal["healthy", "failing", "blocked"] + trigger_id: str = FieldInfo(alias="triggerId") updated_at: Optional[str] = FieldInfo(alias="updatedAt", default=None) diff --git a/src/mobilerun_sdk/types/workflows/flow_list_params.py b/src/mobilerun_sdk/types/workflows/flow_list_params.py index c8310db..8f00af0 100644 --- a/src/mobilerun_sdk/types/workflows/flow_list_params.py +++ b/src/mobilerun_sdk/types/workflows/flow_list_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Optional +from typing import List, Optional from typing_extensions import Literal, Annotated, TypedDict from ..._utils import PropertyInfo @@ -23,4 +23,6 @@ class FlowListParams(TypedDict, total=False): search: str + status: List[Literal["healthy", "failing", "blocked"]] + trigger_id: Annotated[str, PropertyInfo(alias="triggerId")] diff --git a/tests/api_resources/workflows/test_flows.py b/tests/api_resources/workflows/test_flows.py index 9eaee1d..d4ba063 100644 --- a/tests/api_resources/workflows/test_flows.py +++ b/tests/api_resources/workflows/test_flows.py @@ -226,6 +226,7 @@ def test_method_list_with_all_params(self, client: Mobilerun) -> None: page=1, page_size=1, search="search", + status=["healthy"], trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(FlowListResponse, flow, path=["response"]) @@ -553,6 +554,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) - page=1, page_size=1, search="search", + status=["healthy"], trigger_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert_matches_type(FlowListResponse, flow, path=["response"]) From d6eca19415416f1f7a51bf4af1dbde598f40bccf Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 06:13:33 +0000 Subject: [PATCH 12/21] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 09b7cac..ecb23ce 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 143 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-51306d6750b156a1d224698900dee021afc17d1409eebdf68224bbf67771734b.yml -openapi_spec_hash: a24ee8b1052dda1a219a4358e76cf40e +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-32f435913b809c57b9bc17838c7ff7721d29f307b8b589f9c1b15141f736f54a.yml +openapi_spec_hash: 29b62d198d5699a230afd5397359cecb config_hash: f78cc66571fe684b918fdab0f4cdf6a7 From ec80ec35e333e302f8b09cd8ddf81d69d297f027 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 06:21:32 +0000 Subject: [PATCH 13/21] feat(api): add agents-api --- .stats.yml | 6 +- api.md | 76 +++- src/mobilerun_sdk/_client.py | 8 +- src/mobilerun_sdk/resources/agents.py | 139 ------ .../resources/agents/__init__.py | 47 ++ src/mobilerun_sdk/resources/agents/agents.py | 134 ++++++ .../resources/agents/chat/__init__.py | 47 ++ .../resources/agents/chat/abort.py | 194 +++++++++ .../resources/agents/chat/chat.py | 406 ++++++++++++++++++ .../resources/agents/chat/question.py | 264 ++++++++++++ .../resources/agents/files/__init__.py | 33 ++ .../resources/agents/files/file_id.py | 398 +++++++++++++++++ .../resources/agents/files/files.py | 306 +++++++++++++ .../resources/workflows/flows/flows.py | 83 ++++ src/mobilerun_sdk/types/__init__.py | 1 - .../types/agent_list_response.py | 33 -- src/mobilerun_sdk/types/agents/__init__.py | 13 + .../types/agents/chat/__init__.py | 10 + .../agents/chat/abort_force_clear_response.py | 13 + .../agents/chat/abort_perform_response.py | 11 + .../chat/question_deliver_answer_params.py | 27 ++ .../chat/question_deliver_answer_response.py | 11 + .../agents/chat/question_dismiss_params.py | 13 + .../agents/chat/question_dismiss_response.py | 11 + .../agents/chat_deliver_permission_params.py | 15 + .../chat_deliver_permission_response.py | 11 + .../agents/chat_get_chat_state_response.py | 15 + .../chat_list_slash_commands_response.py | 25 ++ .../agents/chat_rehydrate_chat_response.py | 44 ++ .../types/agents/file_list_files_params.py | 11 + .../types/agents/file_list_files_response.py | 43 ++ .../agents/file_mint_upload_url_params.py | 21 + .../agents/file_mint_upload_url_response.py | 17 + .../types/agents/files/__init__.py | 11 + .../file_id_cancel_pending_upload_response.py | 9 + .../files/file_id_confirm_upload_response.py | 35 ++ .../files/file_id_delete_file_response.py | 11 + .../files/file_id_update_metadata_params.py | 16 + .../files/file_id_update_metadata_response.py | 31 ++ src/mobilerun_sdk/types/workflows/__init__.py | 1 + .../types/workflows/flow_unblock_response.py | 10 + tests/api_resources/agents/__init__.py | 1 + tests/api_resources/agents/chat/__init__.py | 1 + tests/api_resources/agents/chat/test_abort.py | 136 ++++++ .../agents/chat/test_question.py | 169 ++++++++ tests/api_resources/agents/files/__init__.py | 1 + .../agents/files/test_file_id.py | 327 ++++++++++++++ tests/api_resources/agents/test_chat.py | 271 ++++++++++++ tests/api_resources/agents/test_files.py | 203 +++++++++ tests/api_resources/test_agents.py | 80 ---- tests/api_resources/workflows/test_flows.py | 85 ++++ 51 files changed, 3619 insertions(+), 265 deletions(-) delete mode 100644 src/mobilerun_sdk/resources/agents.py create mode 100644 src/mobilerun_sdk/resources/agents/__init__.py create mode 100644 src/mobilerun_sdk/resources/agents/agents.py create mode 100644 src/mobilerun_sdk/resources/agents/chat/__init__.py create mode 100644 src/mobilerun_sdk/resources/agents/chat/abort.py create mode 100644 src/mobilerun_sdk/resources/agents/chat/chat.py create mode 100644 src/mobilerun_sdk/resources/agents/chat/question.py create mode 100644 src/mobilerun_sdk/resources/agents/files/__init__.py create mode 100644 src/mobilerun_sdk/resources/agents/files/file_id.py create mode 100644 src/mobilerun_sdk/resources/agents/files/files.py delete mode 100644 src/mobilerun_sdk/types/agent_list_response.py create mode 100644 src/mobilerun_sdk/types/agents/__init__.py create mode 100644 src/mobilerun_sdk/types/agents/chat/__init__.py create mode 100644 src/mobilerun_sdk/types/agents/chat/abort_force_clear_response.py create mode 100644 src/mobilerun_sdk/types/agents/chat/abort_perform_response.py create mode 100644 src/mobilerun_sdk/types/agents/chat/question_deliver_answer_params.py create mode 100644 src/mobilerun_sdk/types/agents/chat/question_deliver_answer_response.py create mode 100644 src/mobilerun_sdk/types/agents/chat/question_dismiss_params.py create mode 100644 src/mobilerun_sdk/types/agents/chat/question_dismiss_response.py create mode 100644 src/mobilerun_sdk/types/agents/chat_deliver_permission_params.py create mode 100644 src/mobilerun_sdk/types/agents/chat_deliver_permission_response.py create mode 100644 src/mobilerun_sdk/types/agents/chat_get_chat_state_response.py create mode 100644 src/mobilerun_sdk/types/agents/chat_list_slash_commands_response.py create mode 100644 src/mobilerun_sdk/types/agents/chat_rehydrate_chat_response.py create mode 100644 src/mobilerun_sdk/types/agents/file_list_files_params.py create mode 100644 src/mobilerun_sdk/types/agents/file_list_files_response.py create mode 100644 src/mobilerun_sdk/types/agents/file_mint_upload_url_params.py create mode 100644 src/mobilerun_sdk/types/agents/file_mint_upload_url_response.py create mode 100644 src/mobilerun_sdk/types/agents/files/__init__.py create mode 100644 src/mobilerun_sdk/types/agents/files/file_id_cancel_pending_upload_response.py create mode 100644 src/mobilerun_sdk/types/agents/files/file_id_confirm_upload_response.py create mode 100644 src/mobilerun_sdk/types/agents/files/file_id_delete_file_response.py create mode 100644 src/mobilerun_sdk/types/agents/files/file_id_update_metadata_params.py create mode 100644 src/mobilerun_sdk/types/agents/files/file_id_update_metadata_response.py create mode 100644 src/mobilerun_sdk/types/workflows/flow_unblock_response.py create mode 100644 tests/api_resources/agents/__init__.py create mode 100644 tests/api_resources/agents/chat/__init__.py create mode 100644 tests/api_resources/agents/chat/test_abort.py create mode 100644 tests/api_resources/agents/chat/test_question.py create mode 100644 tests/api_resources/agents/files/__init__.py create mode 100644 tests/api_resources/agents/files/test_file_id.py create mode 100644 tests/api_resources/agents/test_chat.py create mode 100644 tests/api_resources/agents/test_files.py delete mode 100644 tests/api_resources/test_agents.py diff --git a/.stats.yml b/.stats.yml index ecb23ce..fc53991 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 143 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-32f435913b809c57b9bc17838c7ff7721d29f307b8b589f9c1b15141f736f54a.yml +configured_endpoints: 158 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-af9a32a09b514040aa7da0199ecd9c2084733f81afdccad87bdf48b7c63756d6.yml openapi_spec_hash: 29b62d198d5699a230afd5397359cecb -config_hash: f78cc66571fe684b918fdab0f4cdf6a7 +config_hash: fc0353d3ca4f3676121e9780c20f0490 diff --git a/api.md b/api.md index 50be192..c364f55 100644 --- a/api.md +++ b/api.md @@ -16,15 +16,85 @@ from mobilerun_sdk.types import ( # Agents +## Chat + +Types: + +```python +from mobilerun_sdk.types.agents import ( + ChatDeliverPermissionResponse, + ChatGetChatStateResponse, + ChatListSlashCommandsResponse, + ChatRehydrateChatResponse, +) +``` + +Methods: + +- client.agents.chat.deliver_permission(\*\*params) -> ChatDeliverPermissionResponse +- client.agents.chat.get_chat_state() -> ChatGetChatStateResponse +- client.agents.chat.list_slash_commands() -> ChatListSlashCommandsResponse +- client.agents.chat.rehydrate_chat() -> ChatRehydrateChatResponse + +### Abort + +Types: + +```python +from mobilerun_sdk.types.agents.chat import AbortForceClearResponse, AbortPerformResponse +``` + +Methods: + +- client.agents.chat.abort.force_clear() -> AbortForceClearResponse +- client.agents.chat.abort.perform() -> AbortPerformResponse + +### Question + Types: ```python -from mobilerun_sdk.types import AgentListResponse +from mobilerun_sdk.types.agents.chat import QuestionDeliverAnswerResponse, QuestionDismissResponse +``` + +Methods: + +- client.agents.chat.question.deliver_answer(\*\*params) -> QuestionDeliverAnswerResponse +- client.agents.chat.question.dismiss(\*\*params) -> QuestionDismissResponse + +## Files + +Types: + +```python +from mobilerun_sdk.types.agents import FileListFilesResponse, FileMintUploadURLResponse +``` + +Methods: + +- client.agents.files.list_files(\*\*params) -> FileListFilesResponse +- client.agents.files.mint_upload_url(\*\*params) -> FileMintUploadURLResponse + +### FileID + +Types: + +```python +from mobilerun_sdk.types.agents.files import ( + FileIDCancelPendingUploadResponse, + FileIDConfirmUploadResponse, + FileIDDeleteFileResponse, + FileIDUpdateMetadataResponse, +) ``` Methods: -- client.agents.list() -> AgentListResponse +- client.agents.files.file_id.cancel_pending_upload() -> FileIDCancelPendingUploadResponse +- client.agents.files.file_id.confirm_upload() -> FileIDConfirmUploadResponse +- client.agents.files.file_id.delete_file() -> FileIDDeleteFileResponse +- client.agents.files.file_id.download_file() -> None +- client.agents.files.file_id.update_metadata(\*\*params) -> FileIDUpdateMetadataResponse # Apps @@ -585,6 +655,7 @@ from mobilerun_sdk.types.workflows import ( FlowListResponse, FlowDeleteResponse, FlowCloneResponse, + FlowUnblockResponse, ) ``` @@ -596,6 +667,7 @@ Methods: - client.workflows.flows.list(\*\*params) -> FlowListResponse - client.workflows.flows.delete(flow_id) -> FlowDeleteResponse - client.workflows.flows.clone(flow_id, \*\*params) -> FlowCloneResponse +- client.workflows.flows.unblock(flow_id) -> FlowUnblockResponse ### Actions diff --git a/src/mobilerun_sdk/_client.py b/src/mobilerun_sdk/_client.py index b4f4f87..569a208 100644 --- a/src/mobilerun_sdk/_client.py +++ b/src/mobilerun_sdk/_client.py @@ -51,12 +51,12 @@ ) from .resources.apps import AppsResource, AsyncAppsResource from .resources.hooks import HooksResource, AsyncHooksResource - from .resources.agents import AgentsResource, AsyncAgentsResource from .resources.models import ModelsResource, AsyncModelsResource from .resources.proxies import ProxiesResource, AsyncProxiesResource from .resources.carriers import CarriersResource, AsyncCarriersResource from .resources.profiles import ProfilesResource, AsyncProfilesResource from .resources.tasks.tasks import TasksResource, AsyncTasksResource + from .resources.agents.agents import AgentsResource, AsyncAgentsResource from .resources.devices.devices import DevicesResource, AsyncDevicesResource from .resources.workflows.workflows import WorkflowsResource, AsyncWorkflowsResource from .resources.credentials.credentials import CredentialsResource, AsyncCredentialsResource @@ -135,7 +135,6 @@ def __init__( @cached_property def agents(self) -> AgentsResource: - """Agents API""" from .resources.agents import AgentsResource return AgentsResource(self) @@ -392,7 +391,6 @@ def __init__( @cached_property def agents(self) -> AsyncAgentsResource: - """Agents API""" from .resources.agents import AsyncAgentsResource return AsyncAgentsResource(self) @@ -595,7 +593,6 @@ def __init__(self, client: Mobilerun) -> None: @cached_property def agents(self) -> agents.AgentsResourceWithRawResponse: - """Agents API""" from .resources.agents import AgentsResourceWithRawResponse return AgentsResourceWithRawResponse(self._client.agents) @@ -675,7 +672,6 @@ def __init__(self, client: AsyncMobilerun) -> None: @cached_property def agents(self) -> agents.AsyncAgentsResourceWithRawResponse: - """Agents API""" from .resources.agents import AsyncAgentsResourceWithRawResponse return AsyncAgentsResourceWithRawResponse(self._client.agents) @@ -755,7 +751,6 @@ def __init__(self, client: Mobilerun) -> None: @cached_property def agents(self) -> agents.AgentsResourceWithStreamingResponse: - """Agents API""" from .resources.agents import AgentsResourceWithStreamingResponse return AgentsResourceWithStreamingResponse(self._client.agents) @@ -835,7 +830,6 @@ def __init__(self, client: AsyncMobilerun) -> None: @cached_property def agents(self) -> agents.AsyncAgentsResourceWithStreamingResponse: - """Agents API""" from .resources.agents import AsyncAgentsResourceWithStreamingResponse return AsyncAgentsResourceWithStreamingResponse(self._client.agents) diff --git a/src/mobilerun_sdk/resources/agents.py b/src/mobilerun_sdk/resources/agents.py deleted file mode 100644 index bbe316c..0000000 --- a/src/mobilerun_sdk/resources/agents.py +++ /dev/null @@ -1,139 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import httpx - -from .._types import Body, Query, Headers, NotGiven, not_given -from .._compat import cached_property -from .._resource import SyncAPIResource, AsyncAPIResource -from .._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from .._base_client import make_request_options -from ..types.agent_list_response import AgentListResponse - -__all__ = ["AgentsResource", "AsyncAgentsResource"] - - -class AgentsResource(SyncAPIResource): - """Agents API""" - - @cached_property - def with_raw_response(self) -> AgentsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return AgentsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AgentsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return AgentsResourceWithStreamingResponse(self) - - def list( - self, - *, - # 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, - ) -> AgentListResponse: - """List all available agents with their default configurations.""" - return self._get( - "/agents", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=AgentListResponse, - ) - - -class AsyncAgentsResource(AsyncAPIResource): - """Agents API""" - - @cached_property - def with_raw_response(self) -> AsyncAgentsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return AsyncAgentsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncAgentsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return AsyncAgentsResourceWithStreamingResponse(self) - - async def list( - self, - *, - # 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, - ) -> AgentListResponse: - """List all available agents with their default configurations.""" - return await self._get( - "/agents", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=AgentListResponse, - ) - - -class AgentsResourceWithRawResponse: - def __init__(self, agents: AgentsResource) -> None: - self._agents = agents - - self.list = to_raw_response_wrapper( - agents.list, - ) - - -class AsyncAgentsResourceWithRawResponse: - def __init__(self, agents: AsyncAgentsResource) -> None: - self._agents = agents - - self.list = async_to_raw_response_wrapper( - agents.list, - ) - - -class AgentsResourceWithStreamingResponse: - def __init__(self, agents: AgentsResource) -> None: - self._agents = agents - - self.list = to_streamed_response_wrapper( - agents.list, - ) - - -class AsyncAgentsResourceWithStreamingResponse: - def __init__(self, agents: AsyncAgentsResource) -> None: - self._agents = agents - - self.list = async_to_streamed_response_wrapper( - agents.list, - ) diff --git a/src/mobilerun_sdk/resources/agents/__init__.py b/src/mobilerun_sdk/resources/agents/__init__.py new file mode 100644 index 0000000..8cd1035 --- /dev/null +++ b/src/mobilerun_sdk/resources/agents/__init__.py @@ -0,0 +1,47 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .chat import ( + ChatResource, + AsyncChatResource, + ChatResourceWithRawResponse, + AsyncChatResourceWithRawResponse, + ChatResourceWithStreamingResponse, + AsyncChatResourceWithStreamingResponse, +) +from .files import ( + FilesResource, + AsyncFilesResource, + FilesResourceWithRawResponse, + AsyncFilesResourceWithRawResponse, + FilesResourceWithStreamingResponse, + AsyncFilesResourceWithStreamingResponse, +) +from .agents import ( + AgentsResource, + AsyncAgentsResource, + AgentsResourceWithRawResponse, + AsyncAgentsResourceWithRawResponse, + AgentsResourceWithStreamingResponse, + AsyncAgentsResourceWithStreamingResponse, +) + +__all__ = [ + "ChatResource", + "AsyncChatResource", + "ChatResourceWithRawResponse", + "AsyncChatResourceWithRawResponse", + "ChatResourceWithStreamingResponse", + "AsyncChatResourceWithStreamingResponse", + "FilesResource", + "AsyncFilesResource", + "FilesResourceWithRawResponse", + "AsyncFilesResourceWithRawResponse", + "FilesResourceWithStreamingResponse", + "AsyncFilesResourceWithStreamingResponse", + "AgentsResource", + "AsyncAgentsResource", + "AgentsResourceWithRawResponse", + "AsyncAgentsResourceWithRawResponse", + "AgentsResourceWithStreamingResponse", + "AsyncAgentsResourceWithStreamingResponse", +] diff --git a/src/mobilerun_sdk/resources/agents/agents.py b/src/mobilerun_sdk/resources/agents/agents.py new file mode 100644 index 0000000..1d6053a --- /dev/null +++ b/src/mobilerun_sdk/resources/agents/agents.py @@ -0,0 +1,134 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from ..._compat import cached_property +from .chat.chat import ( + ChatResource, + AsyncChatResource, + ChatResourceWithRawResponse, + AsyncChatResourceWithRawResponse, + ChatResourceWithStreamingResponse, + AsyncChatResourceWithStreamingResponse, +) +from ..._resource import SyncAPIResource, AsyncAPIResource +from .files.files import ( + FilesResource, + AsyncFilesResource, + FilesResourceWithRawResponse, + AsyncFilesResourceWithRawResponse, + FilesResourceWithStreamingResponse, + AsyncFilesResourceWithStreamingResponse, +) + +__all__ = ["AgentsResource", "AsyncAgentsResource"] + + +class AgentsResource(SyncAPIResource): + @cached_property + def chat(self) -> ChatResource: + return ChatResource(self._client) + + @cached_property + def files(self) -> FilesResource: + return FilesResource(self._client) + + @cached_property + def with_raw_response(self) -> AgentsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AgentsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AgentsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AgentsResourceWithStreamingResponse(self) + + +class AsyncAgentsResource(AsyncAPIResource): + @cached_property + def chat(self) -> AsyncChatResource: + return AsyncChatResource(self._client) + + @cached_property + def files(self) -> AsyncFilesResource: + return AsyncFilesResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncAgentsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncAgentsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAgentsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncAgentsResourceWithStreamingResponse(self) + + +class AgentsResourceWithRawResponse: + def __init__(self, agents: AgentsResource) -> None: + self._agents = agents + + @cached_property + def chat(self) -> ChatResourceWithRawResponse: + return ChatResourceWithRawResponse(self._agents.chat) + + @cached_property + def files(self) -> FilesResourceWithRawResponse: + return FilesResourceWithRawResponse(self._agents.files) + + +class AsyncAgentsResourceWithRawResponse: + def __init__(self, agents: AsyncAgentsResource) -> None: + self._agents = agents + + @cached_property + def chat(self) -> AsyncChatResourceWithRawResponse: + return AsyncChatResourceWithRawResponse(self._agents.chat) + + @cached_property + def files(self) -> AsyncFilesResourceWithRawResponse: + return AsyncFilesResourceWithRawResponse(self._agents.files) + + +class AgentsResourceWithStreamingResponse: + def __init__(self, agents: AgentsResource) -> None: + self._agents = agents + + @cached_property + def chat(self) -> ChatResourceWithStreamingResponse: + return ChatResourceWithStreamingResponse(self._agents.chat) + + @cached_property + def files(self) -> FilesResourceWithStreamingResponse: + return FilesResourceWithStreamingResponse(self._agents.files) + + +class AsyncAgentsResourceWithStreamingResponse: + def __init__(self, agents: AsyncAgentsResource) -> None: + self._agents = agents + + @cached_property + def chat(self) -> AsyncChatResourceWithStreamingResponse: + return AsyncChatResourceWithStreamingResponse(self._agents.chat) + + @cached_property + def files(self) -> AsyncFilesResourceWithStreamingResponse: + return AsyncFilesResourceWithStreamingResponse(self._agents.files) diff --git a/src/mobilerun_sdk/resources/agents/chat/__init__.py b/src/mobilerun_sdk/resources/agents/chat/__init__.py new file mode 100644 index 0000000..3541671 --- /dev/null +++ b/src/mobilerun_sdk/resources/agents/chat/__init__.py @@ -0,0 +1,47 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .chat import ( + ChatResource, + AsyncChatResource, + ChatResourceWithRawResponse, + AsyncChatResourceWithRawResponse, + ChatResourceWithStreamingResponse, + AsyncChatResourceWithStreamingResponse, +) +from .abort import ( + AbortResource, + AsyncAbortResource, + AbortResourceWithRawResponse, + AsyncAbortResourceWithRawResponse, + AbortResourceWithStreamingResponse, + AsyncAbortResourceWithStreamingResponse, +) +from .question import ( + QuestionResource, + AsyncQuestionResource, + QuestionResourceWithRawResponse, + AsyncQuestionResourceWithRawResponse, + QuestionResourceWithStreamingResponse, + AsyncQuestionResourceWithStreamingResponse, +) + +__all__ = [ + "AbortResource", + "AsyncAbortResource", + "AbortResourceWithRawResponse", + "AsyncAbortResourceWithRawResponse", + "AbortResourceWithStreamingResponse", + "AsyncAbortResourceWithStreamingResponse", + "QuestionResource", + "AsyncQuestionResource", + "QuestionResourceWithRawResponse", + "AsyncQuestionResourceWithRawResponse", + "QuestionResourceWithStreamingResponse", + "AsyncQuestionResourceWithStreamingResponse", + "ChatResource", + "AsyncChatResource", + "ChatResourceWithRawResponse", + "AsyncChatResourceWithRawResponse", + "ChatResourceWithStreamingResponse", + "AsyncChatResourceWithStreamingResponse", +] diff --git a/src/mobilerun_sdk/resources/agents/chat/abort.py b/src/mobilerun_sdk/resources/agents/chat/abort.py new file mode 100644 index 0000000..5d6829b --- /dev/null +++ b/src/mobilerun_sdk/resources/agents/chat/abort.py @@ -0,0 +1,194 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._base_client import make_request_options +from ....types.agents.chat.abort_perform_response import AbortPerformResponse +from ....types.agents.chat.abort_force_clear_response import AbortForceClearResponse + +__all__ = ["AbortResource", "AsyncAbortResource"] + + +class AbortResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> AbortResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AbortResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AbortResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AbortResourceWithStreamingResponse(self) + + def force_clear( + self, + *, + # 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, + ) -> AbortForceClearResponse: + """Unconditionally clears the in-flight chat state for the caller. + + Idempotent + escape hatch when /chat/abort cannot settle. + """ + return self._post( + "/agents/chat/abort/force", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AbortForceClearResponse, + ) + + def perform( + self, + *, + # 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, + ) -> AbortPerformResponse: + """Abort the in-flight chat turn. Idempotent.""" + return self._post( + "/agents/chat/abort", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AbortPerformResponse, + ) + + +class AsyncAbortResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncAbortResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncAbortResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAbortResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncAbortResourceWithStreamingResponse(self) + + async def force_clear( + self, + *, + # 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, + ) -> AbortForceClearResponse: + """Unconditionally clears the in-flight chat state for the caller. + + Idempotent + escape hatch when /chat/abort cannot settle. + """ + return await self._post( + "/agents/chat/abort/force", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AbortForceClearResponse, + ) + + async def perform( + self, + *, + # 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, + ) -> AbortPerformResponse: + """Abort the in-flight chat turn. Idempotent.""" + return await self._post( + "/agents/chat/abort", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AbortPerformResponse, + ) + + +class AbortResourceWithRawResponse: + def __init__(self, abort: AbortResource) -> None: + self._abort = abort + + self.force_clear = to_raw_response_wrapper( + abort.force_clear, + ) + self.perform = to_raw_response_wrapper( + abort.perform, + ) + + +class AsyncAbortResourceWithRawResponse: + def __init__(self, abort: AsyncAbortResource) -> None: + self._abort = abort + + self.force_clear = async_to_raw_response_wrapper( + abort.force_clear, + ) + self.perform = async_to_raw_response_wrapper( + abort.perform, + ) + + +class AbortResourceWithStreamingResponse: + def __init__(self, abort: AbortResource) -> None: + self._abort = abort + + self.force_clear = to_streamed_response_wrapper( + abort.force_clear, + ) + self.perform = to_streamed_response_wrapper( + abort.perform, + ) + + +class AsyncAbortResourceWithStreamingResponse: + def __init__(self, abort: AsyncAbortResource) -> None: + self._abort = abort + + self.force_clear = async_to_streamed_response_wrapper( + abort.force_clear, + ) + self.perform = async_to_streamed_response_wrapper( + abort.perform, + ) diff --git a/src/mobilerun_sdk/resources/agents/chat/chat.py b/src/mobilerun_sdk/resources/agents/chat/chat.py new file mode 100644 index 0000000..ed91b94 --- /dev/null +++ b/src/mobilerun_sdk/resources/agents/chat/chat.py @@ -0,0 +1,406 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal + +import httpx + +from .abort import ( + AbortResource, + AsyncAbortResource, + AbortResourceWithRawResponse, + AsyncAbortResourceWithRawResponse, + AbortResourceWithStreamingResponse, + AsyncAbortResourceWithStreamingResponse, +) +from .question import ( + QuestionResource, + AsyncQuestionResource, + QuestionResourceWithRawResponse, + AsyncQuestionResourceWithRawResponse, + QuestionResourceWithStreamingResponse, + AsyncQuestionResourceWithStreamingResponse, +) +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._base_client import make_request_options +from ....types.agents import chat_deliver_permission_params +from ....types.agents.chat_get_chat_state_response import ChatGetChatStateResponse +from ....types.agents.chat_rehydrate_chat_response import ChatRehydrateChatResponse +from ....types.agents.chat_deliver_permission_response import ChatDeliverPermissionResponse +from ....types.agents.chat_list_slash_commands_response import ChatListSlashCommandsResponse + +__all__ = ["ChatResource", "AsyncChatResource"] + + +class ChatResource(SyncAPIResource): + @cached_property + def abort(self) -> AbortResource: + return AbortResource(self._client) + + @cached_property + def question(self) -> QuestionResource: + return QuestionResource(self._client) + + @cached_property + def with_raw_response(self) -> ChatResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return ChatResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ChatResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return ChatResourceWithStreamingResponse(self) + + def deliver_permission( + self, + *, + permission_id: str, + response: Literal["once", "always", "reject"], + # 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, + ) -> ChatDeliverPermissionResponse: + """ + Deliver a HITL approval/rejection for an in-flight turn. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/agents/chat/permission", + body=maybe_transform( + { + "permission_id": permission_id, + "response": response, + }, + chat_deliver_permission_params.ChatDeliverPermissionParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ChatDeliverPermissionResponse, + ) + + def get_chat_state( + self, + *, + # 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, + ) -> ChatGetChatStateResponse: + """Advisory snapshot of in-flight activity for the caller. + + Returns boolean flags + for an interactive chat turn, a background workflow run, and a pending graceful + abort. Intended for FE UI before deciding to invoke /chat/abort/force. + """ + return self._get( + "/agents/chat/state", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ChatGetChatStateResponse, + ) + + def list_slash_commands( + self, + *, + # 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, + ) -> ChatListSlashCommandsResponse: + """List the chat slash-command catalog.""" + return self._get( + "/agents/chat/slash-commands", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ChatListSlashCommandsResponse, + ) + + def rehydrate_chat( + self, + *, + # 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, + ) -> ChatRehydrateChatResponse: + """Rehydrate the user's chat history. Does not wake a hibernated machine.""" + return self._get( + "/agents/chat/messages", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ChatRehydrateChatResponse, + ) + + +class AsyncChatResource(AsyncAPIResource): + @cached_property + def abort(self) -> AsyncAbortResource: + return AsyncAbortResource(self._client) + + @cached_property + def question(self) -> AsyncQuestionResource: + return AsyncQuestionResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncChatResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncChatResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncChatResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncChatResourceWithStreamingResponse(self) + + async def deliver_permission( + self, + *, + permission_id: str, + response: Literal["once", "always", "reject"], + # 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, + ) -> ChatDeliverPermissionResponse: + """ + Deliver a HITL approval/rejection for an in-flight turn. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/agents/chat/permission", + body=await async_maybe_transform( + { + "permission_id": permission_id, + "response": response, + }, + chat_deliver_permission_params.ChatDeliverPermissionParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ChatDeliverPermissionResponse, + ) + + async def get_chat_state( + self, + *, + # 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, + ) -> ChatGetChatStateResponse: + """Advisory snapshot of in-flight activity for the caller. + + Returns boolean flags + for an interactive chat turn, a background workflow run, and a pending graceful + abort. Intended for FE UI before deciding to invoke /chat/abort/force. + """ + return await self._get( + "/agents/chat/state", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ChatGetChatStateResponse, + ) + + async def list_slash_commands( + self, + *, + # 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, + ) -> ChatListSlashCommandsResponse: + """List the chat slash-command catalog.""" + return await self._get( + "/agents/chat/slash-commands", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ChatListSlashCommandsResponse, + ) + + async def rehydrate_chat( + self, + *, + # 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, + ) -> ChatRehydrateChatResponse: + """Rehydrate the user's chat history. Does not wake a hibernated machine.""" + return await self._get( + "/agents/chat/messages", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ChatRehydrateChatResponse, + ) + + +class ChatResourceWithRawResponse: + def __init__(self, chat: ChatResource) -> None: + self._chat = chat + + self.deliver_permission = to_raw_response_wrapper( + chat.deliver_permission, + ) + self.get_chat_state = to_raw_response_wrapper( + chat.get_chat_state, + ) + self.list_slash_commands = to_raw_response_wrapper( + chat.list_slash_commands, + ) + self.rehydrate_chat = to_raw_response_wrapper( + chat.rehydrate_chat, + ) + + @cached_property + def abort(self) -> AbortResourceWithRawResponse: + return AbortResourceWithRawResponse(self._chat.abort) + + @cached_property + def question(self) -> QuestionResourceWithRawResponse: + return QuestionResourceWithRawResponse(self._chat.question) + + +class AsyncChatResourceWithRawResponse: + def __init__(self, chat: AsyncChatResource) -> None: + self._chat = chat + + self.deliver_permission = async_to_raw_response_wrapper( + chat.deliver_permission, + ) + self.get_chat_state = async_to_raw_response_wrapper( + chat.get_chat_state, + ) + self.list_slash_commands = async_to_raw_response_wrapper( + chat.list_slash_commands, + ) + self.rehydrate_chat = async_to_raw_response_wrapper( + chat.rehydrate_chat, + ) + + @cached_property + def abort(self) -> AsyncAbortResourceWithRawResponse: + return AsyncAbortResourceWithRawResponse(self._chat.abort) + + @cached_property + def question(self) -> AsyncQuestionResourceWithRawResponse: + return AsyncQuestionResourceWithRawResponse(self._chat.question) + + +class ChatResourceWithStreamingResponse: + def __init__(self, chat: ChatResource) -> None: + self._chat = chat + + self.deliver_permission = to_streamed_response_wrapper( + chat.deliver_permission, + ) + self.get_chat_state = to_streamed_response_wrapper( + chat.get_chat_state, + ) + self.list_slash_commands = to_streamed_response_wrapper( + chat.list_slash_commands, + ) + self.rehydrate_chat = to_streamed_response_wrapper( + chat.rehydrate_chat, + ) + + @cached_property + def abort(self) -> AbortResourceWithStreamingResponse: + return AbortResourceWithStreamingResponse(self._chat.abort) + + @cached_property + def question(self) -> QuestionResourceWithStreamingResponse: + return QuestionResourceWithStreamingResponse(self._chat.question) + + +class AsyncChatResourceWithStreamingResponse: + def __init__(self, chat: AsyncChatResource) -> None: + self._chat = chat + + self.deliver_permission = async_to_streamed_response_wrapper( + chat.deliver_permission, + ) + self.get_chat_state = async_to_streamed_response_wrapper( + chat.get_chat_state, + ) + self.list_slash_commands = async_to_streamed_response_wrapper( + chat.list_slash_commands, + ) + self.rehydrate_chat = async_to_streamed_response_wrapper( + chat.rehydrate_chat, + ) + + @cached_property + def abort(self) -> AsyncAbortResourceWithStreamingResponse: + return AsyncAbortResourceWithStreamingResponse(self._chat.abort) + + @cached_property + def question(self) -> AsyncQuestionResourceWithStreamingResponse: + return AsyncQuestionResourceWithStreamingResponse(self._chat.question) diff --git a/src/mobilerun_sdk/resources/agents/chat/question.py b/src/mobilerun_sdk/resources/agents/chat/question.py new file mode 100644 index 0000000..31cd897 --- /dev/null +++ b/src/mobilerun_sdk/resources/agents/chat/question.py @@ -0,0 +1,264 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable + +import httpx + +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._base_client import make_request_options +from ....types.agents.chat import question_dismiss_params, question_deliver_answer_params +from ....types.agents.chat.question_dismiss_response import QuestionDismissResponse +from ....types.agents.chat.question_deliver_answer_response import QuestionDeliverAnswerResponse + +__all__ = ["QuestionResource", "AsyncQuestionResource"] + + +class QuestionResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> QuestionResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return QuestionResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> QuestionResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return QuestionResourceWithStreamingResponse(self) + + def deliver_answer( + self, + *, + answers: Iterable[Iterable[question_deliver_answer_params.Answer]], + question_id: str, + # 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, + ) -> QuestionDeliverAnswerResponse: + """ + Forward the user's answers to kilo's `/question/{id}/reply` for an in-flight + turn. Idempotent via the `idempotency-key` header. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/agents/chat/question", + body=maybe_transform( + { + "answers": answers, + "question_id": question_id, + }, + question_deliver_answer_params.QuestionDeliverAnswerParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=QuestionDeliverAnswerResponse, + ) + + def dismiss( + self, + *, + question_id: str, + # 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, + ) -> QuestionDismissResponse: + """Forward a reject to kilo's `/question/{id}/reject`. + + Already-resolved questions + return 200 (no-op) so multi-tab dismiss stays idempotent. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/agents/chat/question/reject", + body=maybe_transform({"question_id": question_id}, question_dismiss_params.QuestionDismissParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=QuestionDismissResponse, + ) + + +class AsyncQuestionResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncQuestionResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncQuestionResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncQuestionResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncQuestionResourceWithStreamingResponse(self) + + async def deliver_answer( + self, + *, + answers: Iterable[Iterable[question_deliver_answer_params.Answer]], + question_id: str, + # 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, + ) -> QuestionDeliverAnswerResponse: + """ + Forward the user's answers to kilo's `/question/{id}/reply` for an in-flight + turn. Idempotent via the `idempotency-key` header. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/agents/chat/question", + body=await async_maybe_transform( + { + "answers": answers, + "question_id": question_id, + }, + question_deliver_answer_params.QuestionDeliverAnswerParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=QuestionDeliverAnswerResponse, + ) + + async def dismiss( + self, + *, + question_id: str, + # 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, + ) -> QuestionDismissResponse: + """Forward a reject to kilo's `/question/{id}/reject`. + + Already-resolved questions + return 200 (no-op) so multi-tab dismiss stays idempotent. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/agents/chat/question/reject", + body=await async_maybe_transform( + {"question_id": question_id}, question_dismiss_params.QuestionDismissParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=QuestionDismissResponse, + ) + + +class QuestionResourceWithRawResponse: + def __init__(self, question: QuestionResource) -> None: + self._question = question + + self.deliver_answer = to_raw_response_wrapper( + question.deliver_answer, + ) + self.dismiss = to_raw_response_wrapper( + question.dismiss, + ) + + +class AsyncQuestionResourceWithRawResponse: + def __init__(self, question: AsyncQuestionResource) -> None: + self._question = question + + self.deliver_answer = async_to_raw_response_wrapper( + question.deliver_answer, + ) + self.dismiss = async_to_raw_response_wrapper( + question.dismiss, + ) + + +class QuestionResourceWithStreamingResponse: + def __init__(self, question: QuestionResource) -> None: + self._question = question + + self.deliver_answer = to_streamed_response_wrapper( + question.deliver_answer, + ) + self.dismiss = to_streamed_response_wrapper( + question.dismiss, + ) + + +class AsyncQuestionResourceWithStreamingResponse: + def __init__(self, question: AsyncQuestionResource) -> None: + self._question = question + + self.deliver_answer = async_to_streamed_response_wrapper( + question.deliver_answer, + ) + self.dismiss = async_to_streamed_response_wrapper( + question.dismiss, + ) diff --git a/src/mobilerun_sdk/resources/agents/files/__init__.py b/src/mobilerun_sdk/resources/agents/files/__init__.py new file mode 100644 index 0000000..6fbc8bc --- /dev/null +++ b/src/mobilerun_sdk/resources/agents/files/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .files import ( + FilesResource, + AsyncFilesResource, + FilesResourceWithRawResponse, + AsyncFilesResourceWithRawResponse, + FilesResourceWithStreamingResponse, + AsyncFilesResourceWithStreamingResponse, +) +from .file_id import ( + FileIDResource, + AsyncFileIDResource, + FileIDResourceWithRawResponse, + AsyncFileIDResourceWithRawResponse, + FileIDResourceWithStreamingResponse, + AsyncFileIDResourceWithStreamingResponse, +) + +__all__ = [ + "FileIDResource", + "AsyncFileIDResource", + "FileIDResourceWithRawResponse", + "AsyncFileIDResourceWithRawResponse", + "FileIDResourceWithStreamingResponse", + "AsyncFileIDResourceWithStreamingResponse", + "FilesResource", + "AsyncFilesResource", + "FilesResourceWithRawResponse", + "AsyncFilesResourceWithRawResponse", + "FilesResourceWithStreamingResponse", + "AsyncFilesResourceWithStreamingResponse", +] diff --git a/src/mobilerun_sdk/resources/agents/files/file_id.py b/src/mobilerun_sdk/resources/agents/files/file_id.py new file mode 100644 index 0000000..9728743 --- /dev/null +++ b/src/mobilerun_sdk/resources/agents/files/file_id.py @@ -0,0 +1,398 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional + +import httpx + +from ...._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given +from ...._utils import maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._base_client import make_request_options +from ....types.agents.files import file_id_update_metadata_params +from ....types.agents.files.file_id_delete_file_response import FileIDDeleteFileResponse +from ....types.agents.files.file_id_confirm_upload_response import FileIDConfirmUploadResponse +from ....types.agents.files.file_id_update_metadata_response import FileIDUpdateMetadataResponse +from ....types.agents.files.file_id_cancel_pending_upload_response import FileIDCancelPendingUploadResponse + +__all__ = ["FileIDResource", "AsyncFileIDResource"] + + +class FileIDResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> FileIDResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return FileIDResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> FileIDResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return FileIDResourceWithStreamingResponse(self) + + def cancel_pending_upload( + self, + *, + # 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, + ) -> FileIDCancelPendingUploadResponse: + """Soft-cancels an in-flight upload before confirm. + + Only acts on `pending` rows — + refuses to touch `ready` to avoid wiping confirmed files. Idempotent: + `{ cancelled: false }` if the row exists but is no longer pending. + """ + return self._delete( + "/agents/files/:fileId/pending", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FileIDCancelPendingUploadResponse, + ) + + def confirm_upload( + self, + *, + # 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, + ) -> FileIDConfirmUploadResponse: + """Confirm a file upload by server-side HEAD validation""" + return self._post( + "/agents/files/:fileId/confirm", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FileIDConfirmUploadResponse, + ) + + def delete_file( + self, + *, + # 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, + ) -> FileIDDeleteFileResponse: + """Hard-delete a file""" + return self._delete( + "/agents/files/:fileId", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FileIDDeleteFileResponse, + ) + + def download_file( + self, + *, + # 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, + ) -> None: + """Redirect to a presigned GET URL for a file (FE owner only)""" + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._get( + "/agents/files/:fileId/download", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + def update_metadata( + self, + *, + display_name: Optional[str] | Omit = omit, + enabled: bool | 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, + ) -> FileIDUpdateMetadataResponse: + """Partial update of `displayName` and/or `enabled`. + + Only files with `zone=skills` + are mutable; other zones return 422 `unsupported_zone`. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._patch( + "/agents/files/:fileId", + body=maybe_transform( + { + "display_name": display_name, + "enabled": enabled, + }, + file_id_update_metadata_params.FileIDUpdateMetadataParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FileIDUpdateMetadataResponse, + ) + + +class AsyncFileIDResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncFileIDResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncFileIDResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncFileIDResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncFileIDResourceWithStreamingResponse(self) + + async def cancel_pending_upload( + self, + *, + # 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, + ) -> FileIDCancelPendingUploadResponse: + """Soft-cancels an in-flight upload before confirm. + + Only acts on `pending` rows — + refuses to touch `ready` to avoid wiping confirmed files. Idempotent: + `{ cancelled: false }` if the row exists but is no longer pending. + """ + return await self._delete( + "/agents/files/:fileId/pending", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FileIDCancelPendingUploadResponse, + ) + + async def confirm_upload( + self, + *, + # 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, + ) -> FileIDConfirmUploadResponse: + """Confirm a file upload by server-side HEAD validation""" + return await self._post( + "/agents/files/:fileId/confirm", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FileIDConfirmUploadResponse, + ) + + async def delete_file( + self, + *, + # 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, + ) -> FileIDDeleteFileResponse: + """Hard-delete a file""" + return await self._delete( + "/agents/files/:fileId", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FileIDDeleteFileResponse, + ) + + async def download_file( + self, + *, + # 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, + ) -> None: + """Redirect to a presigned GET URL for a file (FE owner only)""" + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._get( + "/agents/files/:fileId/download", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + async def update_metadata( + self, + *, + display_name: Optional[str] | Omit = omit, + enabled: bool | 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, + ) -> FileIDUpdateMetadataResponse: + """Partial update of `displayName` and/or `enabled`. + + Only files with `zone=skills` + are mutable; other zones return 422 `unsupported_zone`. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._patch( + "/agents/files/:fileId", + body=await async_maybe_transform( + { + "display_name": display_name, + "enabled": enabled, + }, + file_id_update_metadata_params.FileIDUpdateMetadataParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FileIDUpdateMetadataResponse, + ) + + +class FileIDResourceWithRawResponse: + def __init__(self, file_id: FileIDResource) -> None: + self._file_id = file_id + + self.cancel_pending_upload = to_raw_response_wrapper( + file_id.cancel_pending_upload, + ) + self.confirm_upload = to_raw_response_wrapper( + file_id.confirm_upload, + ) + self.delete_file = to_raw_response_wrapper( + file_id.delete_file, + ) + self.download_file = to_raw_response_wrapper( + file_id.download_file, + ) + self.update_metadata = to_raw_response_wrapper( + file_id.update_metadata, + ) + + +class AsyncFileIDResourceWithRawResponse: + def __init__(self, file_id: AsyncFileIDResource) -> None: + self._file_id = file_id + + self.cancel_pending_upload = async_to_raw_response_wrapper( + file_id.cancel_pending_upload, + ) + self.confirm_upload = async_to_raw_response_wrapper( + file_id.confirm_upload, + ) + self.delete_file = async_to_raw_response_wrapper( + file_id.delete_file, + ) + self.download_file = async_to_raw_response_wrapper( + file_id.download_file, + ) + self.update_metadata = async_to_raw_response_wrapper( + file_id.update_metadata, + ) + + +class FileIDResourceWithStreamingResponse: + def __init__(self, file_id: FileIDResource) -> None: + self._file_id = file_id + + self.cancel_pending_upload = to_streamed_response_wrapper( + file_id.cancel_pending_upload, + ) + self.confirm_upload = to_streamed_response_wrapper( + file_id.confirm_upload, + ) + self.delete_file = to_streamed_response_wrapper( + file_id.delete_file, + ) + self.download_file = to_streamed_response_wrapper( + file_id.download_file, + ) + self.update_metadata = to_streamed_response_wrapper( + file_id.update_metadata, + ) + + +class AsyncFileIDResourceWithStreamingResponse: + def __init__(self, file_id: AsyncFileIDResource) -> None: + self._file_id = file_id + + self.cancel_pending_upload = async_to_streamed_response_wrapper( + file_id.cancel_pending_upload, + ) + self.confirm_upload = async_to_streamed_response_wrapper( + file_id.confirm_upload, + ) + self.delete_file = async_to_streamed_response_wrapper( + file_id.delete_file, + ) + self.download_file = async_to_streamed_response_wrapper( + file_id.download_file, + ) + self.update_metadata = async_to_streamed_response_wrapper( + file_id.update_metadata, + ) diff --git a/src/mobilerun_sdk/resources/agents/files/files.py b/src/mobilerun_sdk/resources/agents/files/files.py new file mode 100644 index 0000000..65e8ae0 --- /dev/null +++ b/src/mobilerun_sdk/resources/agents/files/files.py @@ -0,0 +1,306 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal + +import httpx + +from .file_id import ( + FileIDResource, + AsyncFileIDResource, + FileIDResourceWithRawResponse, + AsyncFileIDResourceWithRawResponse, + FileIDResourceWithStreamingResponse, + AsyncFileIDResourceWithStreamingResponse, +) +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import maybe_transform, strip_not_given, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._base_client import make_request_options +from ....types.agents import file_list_files_params, file_mint_upload_url_params +from ....types.agents.file_list_files_response import FileListFilesResponse +from ....types.agents.file_mint_upload_url_response import FileMintUploadURLResponse + +__all__ = ["FilesResource", "AsyncFilesResource"] + + +class FilesResource(SyncAPIResource): + @cached_property + def file_id(self) -> FileIDResource: + return FileIDResource(self._client) + + @cached_property + def with_raw_response(self) -> FilesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return FilesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> FilesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return FilesResourceWithStreamingResponse(self) + + def list_files( + self, + *, + zone: Literal["user", "agent", "workflow", "skills"] | 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, + ) -> FileListFilesResponse: + """ + List the user's ready files, optionally filtered by zone + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get( + "/agents/files", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"zone": zone}, file_list_files_params.FileListFilesParams), + ), + cast_to=FileListFilesResponse, + ) + + def mint_upload_url( + self, + *, + filename: str, + 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, + ) -> FileMintUploadURLResponse: + """ + Mint a presigned PUT URL for a user file upload + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {**strip_not_given({"Idempotency-Key": idempotency_key}), **(extra_headers or {})} + return self._post( + "/agents/files/upload-url", + body=maybe_transform( + { + "filename": filename, + "mime_type": mime_type, + "size_bytes": size_bytes, + "zone": zone, + }, + file_mint_upload_url_params.FileMintUploadURLParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FileMintUploadURLResponse, + ) + + +class AsyncFilesResource(AsyncAPIResource): + @cached_property + def file_id(self) -> AsyncFileIDResource: + return AsyncFileIDResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncFilesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncFilesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncFilesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncFilesResourceWithStreamingResponse(self) + + async def list_files( + self, + *, + zone: Literal["user", "agent", "workflow", "skills"] | 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, + ) -> FileListFilesResponse: + """ + List the user's ready files, optionally filtered by zone + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._get( + "/agents/files", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform({"zone": zone}, file_list_files_params.FileListFilesParams), + ), + cast_to=FileListFilesResponse, + ) + + async def mint_upload_url( + self, + *, + filename: str, + 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, + ) -> FileMintUploadURLResponse: + """ + Mint a presigned PUT URL for a user file upload + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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( + { + "filename": filename, + "mime_type": mime_type, + "size_bytes": size_bytes, + "zone": zone, + }, + file_mint_upload_url_params.FileMintUploadURLParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FileMintUploadURLResponse, + ) + + +class FilesResourceWithRawResponse: + def __init__(self, files: FilesResource) -> None: + self._files = files + + self.list_files = to_raw_response_wrapper( + files.list_files, + ) + self.mint_upload_url = to_raw_response_wrapper( + files.mint_upload_url, + ) + + @cached_property + def file_id(self) -> FileIDResourceWithRawResponse: + return FileIDResourceWithRawResponse(self._files.file_id) + + +class AsyncFilesResourceWithRawResponse: + def __init__(self, files: AsyncFilesResource) -> None: + self._files = files + + self.list_files = async_to_raw_response_wrapper( + files.list_files, + ) + self.mint_upload_url = async_to_raw_response_wrapper( + files.mint_upload_url, + ) + + @cached_property + def file_id(self) -> AsyncFileIDResourceWithRawResponse: + return AsyncFileIDResourceWithRawResponse(self._files.file_id) + + +class FilesResourceWithStreamingResponse: + def __init__(self, files: FilesResource) -> None: + self._files = files + + self.list_files = to_streamed_response_wrapper( + files.list_files, + ) + self.mint_upload_url = to_streamed_response_wrapper( + files.mint_upload_url, + ) + + @cached_property + def file_id(self) -> FileIDResourceWithStreamingResponse: + return FileIDResourceWithStreamingResponse(self._files.file_id) + + +class AsyncFilesResourceWithStreamingResponse: + def __init__(self, files: AsyncFilesResource) -> None: + self._files = files + + self.list_files = async_to_streamed_response_wrapper( + files.list_files, + ) + self.mint_upload_url = async_to_streamed_response_wrapper( + files.mint_upload_url, + ) + + @cached_property + def file_id(self) -> AsyncFileIDResourceWithStreamingResponse: + return AsyncFileIDResourceWithStreamingResponse(self._files.file_id) diff --git a/src/mobilerun_sdk/resources/workflows/flows/flows.py b/src/mobilerun_sdk/resources/workflows/flows/flows.py index 0458a01..d6881fa 100644 --- a/src/mobilerun_sdk/resources/workflows/flows/flows.py +++ b/src/mobilerun_sdk/resources/workflows/flows/flows.py @@ -32,6 +32,7 @@ from ....types.workflows.flow_create_response import FlowCreateResponse from ....types.workflows.flow_delete_response import FlowDeleteResponse from ....types.workflows.flow_update_response import FlowUpdateResponse +from ....types.workflows.flow_unblock_response import FlowUnblockResponse from ....types.workflows.flow_retrieve_response import FlowRetrieveResponse __all__ = ["FlowsResource", "AsyncFlowsResource"] @@ -315,6 +316,41 @@ def clone( cast_to=FlowCloneResponse, ) + def unblock( + self, + flow_id: str, + *, + # 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, + ) -> FlowUnblockResponse: + """Clear a flow's blocked status after fixing the underlying issue. + + Idempotent — + safe to call on already-healthy flows. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=FlowUnblockResponse, + ) + class AsyncFlowsResource(AsyncAPIResource): @cached_property @@ -594,6 +630,41 @@ async def clone( cast_to=FlowCloneResponse, ) + async def unblock( + self, + flow_id: str, + *, + # 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, + ) -> FlowUnblockResponse: + """Clear a flow's blocked status after fixing the underlying issue. + + Idempotent — + safe to call on already-healthy flows. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + 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 + ), + cast_to=FlowUnblockResponse, + ) + class FlowsResourceWithRawResponse: def __init__(self, flows: FlowsResource) -> None: @@ -617,6 +688,9 @@ def __init__(self, flows: FlowsResource) -> None: self.clone = to_raw_response_wrapper( flows.clone, ) + self.unblock = to_raw_response_wrapper( + flows.unblock, + ) @cached_property def actions(self) -> ActionsResourceWithRawResponse: @@ -645,6 +719,9 @@ def __init__(self, flows: AsyncFlowsResource) -> None: self.clone = async_to_raw_response_wrapper( flows.clone, ) + self.unblock = async_to_raw_response_wrapper( + flows.unblock, + ) @cached_property def actions(self) -> AsyncActionsResourceWithRawResponse: @@ -673,6 +750,9 @@ def __init__(self, flows: FlowsResource) -> None: self.clone = to_streamed_response_wrapper( flows.clone, ) + self.unblock = to_streamed_response_wrapper( + flows.unblock, + ) @cached_property def actions(self) -> ActionsResourceWithStreamingResponse: @@ -701,6 +781,9 @@ def __init__(self, flows: AsyncFlowsResource) -> None: self.clone = async_to_streamed_response_wrapper( flows.clone, ) + self.unblock = async_to_streamed_response_wrapper( + flows.unblock, + ) @cached_property def actions(self) -> AsyncActionsResourceWithStreamingResponse: diff --git a/src/mobilerun_sdk/types/__init__.py b/src/mobilerun_sdk/types/__init__.py index e641405..2b5082d 100644 --- a/src/mobilerun_sdk/types/__init__.py +++ b/src/mobilerun_sdk/types/__init__.py @@ -36,7 +36,6 @@ from .hook_update_params import HookUpdateParams as HookUpdateParams from .task_list_response import TaskListResponse as TaskListResponse from .task_stop_response import TaskStopResponse as TaskStopResponse -from .agent_list_response import AgentListResponse as AgentListResponse from .app_delete_response import AppDeleteResponse as AppDeleteResponse from .carrier_list_params import CarrierListParams as CarrierListParams from .hook_perform_params import HookPerformParams as HookPerformParams diff --git a/src/mobilerun_sdk/types/agent_list_response.py b/src/mobilerun_sdk/types/agent_list_response.py deleted file mode 100644 index fc366d6..0000000 --- a/src/mobilerun_sdk/types/agent_list_response.py +++ /dev/null @@ -1,33 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import TypeAlias - -from pydantic import Field as FieldInfo - -from .._models import BaseModel - -__all__ = ["AgentListResponse", "AgentListResponseItem"] - - -class AgentListResponseItem(BaseModel): - id: int - - description: Optional[str] = None - - icon: str - - llm_model: str = FieldInfo(alias="llmModel") - - max_steps: int = FieldInfo(alias="maxSteps") - - name: str - - reasoning: bool - - subagent_model: Optional[str] = FieldInfo(alias="subagentModel", default=None) - - vision: bool - - -AgentListResponse: TypeAlias = List[AgentListResponseItem] diff --git a/src/mobilerun_sdk/types/agents/__init__.py b/src/mobilerun_sdk/types/agents/__init__.py new file mode 100644 index 0000000..f8cfbf9 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/__init__.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .file_list_files_params import FileListFilesParams as FileListFilesParams +from .file_list_files_response import FileListFilesResponse as FileListFilesResponse +from .file_mint_upload_url_params import FileMintUploadURLParams as FileMintUploadURLParams +from .chat_get_chat_state_response import ChatGetChatStateResponse as ChatGetChatStateResponse +from .chat_rehydrate_chat_response import ChatRehydrateChatResponse as ChatRehydrateChatResponse +from .file_mint_upload_url_response import FileMintUploadURLResponse as FileMintUploadURLResponse +from .chat_deliver_permission_params import ChatDeliverPermissionParams as ChatDeliverPermissionParams +from .chat_deliver_permission_response import ChatDeliverPermissionResponse as ChatDeliverPermissionResponse +from .chat_list_slash_commands_response import ChatListSlashCommandsResponse as ChatListSlashCommandsResponse diff --git a/src/mobilerun_sdk/types/agents/chat/__init__.py b/src/mobilerun_sdk/types/agents/chat/__init__.py new file mode 100644 index 0000000..0d2b831 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat/__init__.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .abort_perform_response import AbortPerformResponse as AbortPerformResponse +from .question_dismiss_params import QuestionDismissParams as QuestionDismissParams +from .question_dismiss_response import QuestionDismissResponse as QuestionDismissResponse +from .abort_force_clear_response import AbortForceClearResponse as AbortForceClearResponse +from .question_deliver_answer_params import QuestionDeliverAnswerParams as QuestionDeliverAnswerParams +from .question_deliver_answer_response import QuestionDeliverAnswerResponse as QuestionDeliverAnswerResponse diff --git a/src/mobilerun_sdk/types/agents/chat/abort_force_clear_response.py b/src/mobilerun_sdk/types/agents/chat/abort_force_clear_response.py new file mode 100644 index 0000000..d8fdfa3 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat/abort_force_clear_response.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["AbortForceClearResponse"] + + +class AbortForceClearResponse(BaseModel): + cleared: int + + ok: Literal[True] diff --git a/src/mobilerun_sdk/types/agents/chat/abort_perform_response.py b/src/mobilerun_sdk/types/agents/chat/abort_perform_response.py new file mode 100644 index 0000000..881f737 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat/abort_perform_response.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["AbortPerformResponse"] + + +class AbortPerformResponse(BaseModel): + ok: Literal[True] diff --git a/src/mobilerun_sdk/types/agents/chat/question_deliver_answer_params.py b/src/mobilerun_sdk/types/agents/chat/question_deliver_answer_params.py new file mode 100644 index 0000000..2d9afa7 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat/question_deliver_answer_params.py @@ -0,0 +1,27 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union, Iterable +from typing_extensions import Required, Annotated, TypeAlias, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["QuestionDeliverAnswerParams", "Answer", "AnswerLabel", "AnswerCustom"] + + +class QuestionDeliverAnswerParams(TypedDict, total=False): + answers: Required[Iterable[Iterable[Answer]]] + + question_id: Required[Annotated[str, PropertyInfo(alias="questionId")]] + + +class AnswerLabel(TypedDict, total=False): + label: Required[str] + + +class AnswerCustom(TypedDict, total=False): + custom: Required[str] + + +Answer: TypeAlias = Union[AnswerLabel, AnswerCustom] diff --git a/src/mobilerun_sdk/types/agents/chat/question_deliver_answer_response.py b/src/mobilerun_sdk/types/agents/chat/question_deliver_answer_response.py new file mode 100644 index 0000000..474adbb --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat/question_deliver_answer_response.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["QuestionDeliverAnswerResponse"] + + +class QuestionDeliverAnswerResponse(BaseModel): + ok: Literal[True] diff --git a/src/mobilerun_sdk/types/agents/chat/question_dismiss_params.py b/src/mobilerun_sdk/types/agents/chat/question_dismiss_params.py new file mode 100644 index 0000000..a9247df --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat/question_dismiss_params.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["QuestionDismissParams"] + + +class QuestionDismissParams(TypedDict, total=False): + question_id: Required[Annotated[str, PropertyInfo(alias="questionId")]] diff --git a/src/mobilerun_sdk/types/agents/chat/question_dismiss_response.py b/src/mobilerun_sdk/types/agents/chat/question_dismiss_response.py new file mode 100644 index 0000000..ce036a9 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat/question_dismiss_response.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["QuestionDismissResponse"] + + +class QuestionDismissResponse(BaseModel): + ok: Literal[True] diff --git a/src/mobilerun_sdk/types/agents/chat_deliver_permission_params.py b/src/mobilerun_sdk/types/agents/chat_deliver_permission_params.py new file mode 100644 index 0000000..c3e54c1 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat_deliver_permission_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["ChatDeliverPermissionParams"] + + +class ChatDeliverPermissionParams(TypedDict, total=False): + permission_id: Required[Annotated[str, PropertyInfo(alias="permissionId")]] + + response: Required[Literal["once", "always", "reject"]] diff --git a/src/mobilerun_sdk/types/agents/chat_deliver_permission_response.py b/src/mobilerun_sdk/types/agents/chat_deliver_permission_response.py new file mode 100644 index 0000000..342281d --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat_deliver_permission_response.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["ChatDeliverPermissionResponse"] + + +class ChatDeliverPermissionResponse(BaseModel): + ok: Literal[True] diff --git a/src/mobilerun_sdk/types/agents/chat_get_chat_state_response.py b/src/mobilerun_sdk/types/agents/chat_get_chat_state_response.py new file mode 100644 index 0000000..78d661f --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat_get_chat_state_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["ChatGetChatStateResponse"] + + +class ChatGetChatStateResponse(BaseModel): + abort_requested: bool = FieldInfo(alias="abortRequested") + + chat_active: bool = FieldInfo(alias="chatActive") + + workflow_active: bool = FieldInfo(alias="workflowActive") diff --git a/src/mobilerun_sdk/types/agents/chat_list_slash_commands_response.py b/src/mobilerun_sdk/types/agents/chat_list_slash_commands_response.py new file mode 100644 index 0000000..8e85806 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat_list_slash_commands_response.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from ..._models import BaseModel + +__all__ = ["ChatListSlashCommandsResponse", "Command"] + + +class Command(BaseModel): + name: str + """Including the leading slash (e.g. `/help`).""" + + summary: str + + args: Optional[str] = None + """Arg signature for the help card (e.g. + + ``, ``). Always angle-bracketed; the summary spells out when an + arg is optional. + """ + + +class ChatListSlashCommandsResponse(BaseModel): + commands: List[Command] diff --git a/src/mobilerun_sdk/types/agents/chat_rehydrate_chat_response.py b/src/mobilerun_sdk/types/agents/chat_rehydrate_chat_response.py new file mode 100644 index 0000000..3214bd6 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat_rehydrate_chat_response.py @@ -0,0 +1,44 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import TYPE_CHECKING, Dict, List, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["ChatRehydrateChatResponse", "Message", "MessagePart"] + + +class MessagePart(BaseModel): + type: str + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, Optional[object]] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> Optional[object]: ... + else: + __pydantic_extra__: Dict[str, Optional[object]] + + +class Message(BaseModel): + id: str + + parts: List[MessagePart] + + role: Literal["user", "assistant", "system"] + + source: Optional[Literal["cloud", "telegram", "api", "workflow"]] = None + + synthetic: Optional[bool] = None + + +class ChatRehydrateChatResponse(BaseModel): + messages: List[Message] + + turn_active: bool = FieldInfo(alias="turnActive") diff --git a/src/mobilerun_sdk/types/agents/file_list_files_params.py b/src/mobilerun_sdk/types/agents/file_list_files_params.py new file mode 100644 index 0000000..8802615 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/file_list_files_params.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["FileListFilesParams"] + + +class FileListFilesParams(TypedDict, total=False): + zone: Literal["user", "agent", "workflow", "skills"] diff --git a/src/mobilerun_sdk/types/agents/file_list_files_response.py b/src/mobilerun_sdk/types/agents/file_list_files_response.py new file mode 100644 index 0000000..83554e2 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/file_list_files_response.py @@ -0,0 +1,43 @@ +# 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__ = ["FileListFilesResponse", "File", "Quota"] + + +class File(BaseModel): + created_at: datetime = FieldInfo(alias="createdAt") + + created_by: Literal["user", "agent", "workflow"] = FieldInfo(alias="createdBy") + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + enabled: bool + + file_id: str = FieldInfo(alias="fileId") + + filename: str + + mime_type: str = FieldInfo(alias="mimeType") + + size_bytes: float = FieldInfo(alias="sizeBytes") + + zone: Literal["user", "agent", "workflow", "skills"] + + +class Quota(BaseModel): + current_bytes: int = FieldInfo(alias="currentBytes") + + quota_bytes: int = FieldInfo(alias="quotaBytes") + + +class FileListFilesResponse(BaseModel): + files: List[File] + + quota: Quota diff --git a/src/mobilerun_sdk/types/agents/file_mint_upload_url_params.py b/src/mobilerun_sdk/types/agents/file_mint_upload_url_params.py new file mode 100644 index 0000000..c68739b --- /dev/null +++ b/src/mobilerun_sdk/types/agents/file_mint_upload_url_params.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["FileMintUploadURLParams"] + + +class FileMintUploadURLParams(TypedDict, total=False): + filename: Required[str] + + mime_type: Required[Annotated[str, PropertyInfo(alias="mimeType")]] + + 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/agents/file_mint_upload_url_response.py b/src/mobilerun_sdk/types/agents/file_mint_upload_url_response.py new file mode 100644 index 0000000..162c71a --- /dev/null +++ b/src/mobilerun_sdk/types/agents/file_mint_upload_url_response.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["FileMintUploadURLResponse"] + + +class FileMintUploadURLResponse(BaseModel): + expires_at: datetime = FieldInfo(alias="expiresAt") + + file_id: str = FieldInfo(alias="fileId") + + put_url: str = FieldInfo(alias="putUrl") diff --git a/src/mobilerun_sdk/types/agents/files/__init__.py b/src/mobilerun_sdk/types/agents/files/__init__.py new file mode 100644 index 0000000..b74a1a8 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/files/__init__.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .file_id_delete_file_response import FileIDDeleteFileResponse as FileIDDeleteFileResponse +from .file_id_update_metadata_params import FileIDUpdateMetadataParams as FileIDUpdateMetadataParams +from .file_id_confirm_upload_response import FileIDConfirmUploadResponse as FileIDConfirmUploadResponse +from .file_id_update_metadata_response import FileIDUpdateMetadataResponse as FileIDUpdateMetadataResponse +from .file_id_cancel_pending_upload_response import ( + FileIDCancelPendingUploadResponse as FileIDCancelPendingUploadResponse, +) diff --git a/src/mobilerun_sdk/types/agents/files/file_id_cancel_pending_upload_response.py b/src/mobilerun_sdk/types/agents/files/file_id_cancel_pending_upload_response.py new file mode 100644 index 0000000..18e2ee4 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/files/file_id_cancel_pending_upload_response.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ...._models import BaseModel + +__all__ = ["FileIDCancelPendingUploadResponse"] + + +class FileIDCancelPendingUploadResponse(BaseModel): + cancelled: bool diff --git a/src/mobilerun_sdk/types/agents/files/file_id_confirm_upload_response.py b/src/mobilerun_sdk/types/agents/files/file_id_confirm_upload_response.py new file mode 100644 index 0000000..fd838b8 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/files/file_id_confirm_upload_response.py @@ -0,0 +1,35 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ...._models import BaseModel + +__all__ = ["FileIDConfirmUploadResponse"] + + +class FileIDConfirmUploadResponse(BaseModel): + actual_size_bytes: float = FieldInfo(alias="actualSizeBytes") + + created_at: datetime = FieldInfo(alias="createdAt") + + created_by: Literal["user", "agent", "workflow"] = FieldInfo(alias="createdBy") + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + enabled: bool + + file_id: str = FieldInfo(alias="fileId") + + filename: str + + mime_type: str = FieldInfo(alias="mimeType") + + size_bytes: float = FieldInfo(alias="sizeBytes") + + state: Literal["ready"] + + zone: Literal["user", "agent", "workflow", "skills"] diff --git a/src/mobilerun_sdk/types/agents/files/file_id_delete_file_response.py b/src/mobilerun_sdk/types/agents/files/file_id_delete_file_response.py new file mode 100644 index 0000000..3014432 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/files/file_id_delete_file_response.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["FileIDDeleteFileResponse"] + + +class FileIDDeleteFileResponse(BaseModel): + ok: Literal[True] diff --git a/src/mobilerun_sdk/types/agents/files/file_id_update_metadata_params.py b/src/mobilerun_sdk/types/agents/files/file_id_update_metadata_params.py new file mode 100644 index 0000000..9a0b940 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/files/file_id_update_metadata_params.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Annotated, TypedDict + +from ...._utils import PropertyInfo + +__all__ = ["FileIDUpdateMetadataParams"] + + +class FileIDUpdateMetadataParams(TypedDict, total=False): + display_name: Annotated[Optional[str], PropertyInfo(alias="displayName")] + + enabled: bool diff --git a/src/mobilerun_sdk/types/agents/files/file_id_update_metadata_response.py b/src/mobilerun_sdk/types/agents/files/file_id_update_metadata_response.py new file mode 100644 index 0000000..6ab101b --- /dev/null +++ b/src/mobilerun_sdk/types/agents/files/file_id_update_metadata_response.py @@ -0,0 +1,31 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ...._models import BaseModel + +__all__ = ["FileIDUpdateMetadataResponse"] + + +class FileIDUpdateMetadataResponse(BaseModel): + created_at: datetime = FieldInfo(alias="createdAt") + + created_by: Literal["user", "agent", "workflow"] = FieldInfo(alias="createdBy") + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + enabled: bool + + file_id: str = FieldInfo(alias="fileId") + + filename: str + + mime_type: str = FieldInfo(alias="mimeType") + + size_bytes: float = FieldInfo(alias="sizeBytes") + + zone: Literal["user", "agent", "workflow", "skills"] diff --git a/src/mobilerun_sdk/types/workflows/__init__.py b/src/mobilerun_sdk/types/workflows/__init__.py index 85513bc..89853e2 100644 --- a/src/mobilerun_sdk/types/workflows/__init__.py +++ b/src/mobilerun_sdk/types/workflows/__init__.py @@ -27,6 +27,7 @@ from .secret_list_response import SecretListResponse as SecretListResponse from .event_ingest_response import EventIngestResponse as EventIngestResponse from .execution_list_params import ExecutionListParams as ExecutionListParams +from .flow_unblock_response import FlowUnblockResponse as FlowUnblockResponse from .trigger_create_params import TriggerCreateParams as TriggerCreateParams from .trigger_fire_response import TriggerFireResponse as TriggerFireResponse from .trigger_list_response import TriggerListResponse as TriggerListResponse diff --git a/src/mobilerun_sdk/types/workflows/flow_unblock_response.py b/src/mobilerun_sdk/types/workflows/flow_unblock_response.py new file mode 100644 index 0000000..3771e29 --- /dev/null +++ b/src/mobilerun_sdk/types/workflows/flow_unblock_response.py @@ -0,0 +1,10 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from ..flow import Flow +from ..._models import BaseModel + +__all__ = ["FlowUnblockResponse"] + + +class FlowUnblockResponse(BaseModel): + data: Flow diff --git a/tests/api_resources/agents/__init__.py b/tests/api_resources/agents/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/agents/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/agents/chat/__init__.py b/tests/api_resources/agents/chat/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/agents/chat/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/agents/chat/test_abort.py b/tests/api_resources/agents/chat/test_abort.py new file mode 100644 index 0000000..59426a3 --- /dev/null +++ b/tests/api_resources/agents/chat/test_abort.py @@ -0,0 +1,136 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.agents.chat import AbortPerformResponse, AbortForceClearResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestAbort: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_force_clear(self, client: Mobilerun) -> None: + abort = client.agents.chat.abort.force_clear() + assert_matches_type(AbortForceClearResponse, abort, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_force_clear(self, client: Mobilerun) -> None: + response = client.agents.chat.abort.with_raw_response.force_clear() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + abort = response.parse() + assert_matches_type(AbortForceClearResponse, abort, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_force_clear(self, client: Mobilerun) -> None: + with client.agents.chat.abort.with_streaming_response.force_clear() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + abort = response.parse() + assert_matches_type(AbortForceClearResponse, abort, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_perform(self, client: Mobilerun) -> None: + abort = client.agents.chat.abort.perform() + assert_matches_type(AbortPerformResponse, abort, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_perform(self, client: Mobilerun) -> None: + response = client.agents.chat.abort.with_raw_response.perform() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + abort = response.parse() + assert_matches_type(AbortPerformResponse, abort, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_perform(self, client: Mobilerun) -> None: + with client.agents.chat.abort.with_streaming_response.perform() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + abort = response.parse() + assert_matches_type(AbortPerformResponse, abort, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncAbort: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_force_clear(self, async_client: AsyncMobilerun) -> None: + abort = await async_client.agents.chat.abort.force_clear() + assert_matches_type(AbortForceClearResponse, abort, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_force_clear(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.chat.abort.with_raw_response.force_clear() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + abort = await response.parse() + assert_matches_type(AbortForceClearResponse, abort, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_force_clear(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.chat.abort.with_streaming_response.force_clear() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + abort = await response.parse() + assert_matches_type(AbortForceClearResponse, abort, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_perform(self, async_client: AsyncMobilerun) -> None: + abort = await async_client.agents.chat.abort.perform() + assert_matches_type(AbortPerformResponse, abort, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_perform(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.chat.abort.with_raw_response.perform() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + abort = await response.parse() + assert_matches_type(AbortPerformResponse, abort, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_perform(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.chat.abort.with_streaming_response.perform() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + abort = await response.parse() + assert_matches_type(AbortPerformResponse, abort, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/agents/chat/test_question.py b/tests/api_resources/agents/chat/test_question.py new file mode 100644 index 0000000..e200ee4 --- /dev/null +++ b/tests/api_resources/agents/chat/test_question.py @@ -0,0 +1,169 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.agents.chat import ( + QuestionDismissResponse, + QuestionDeliverAnswerResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestQuestion: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_deliver_answer(self, client: Mobilerun) -> None: + question = client.agents.chat.question.deliver_answer( + answers=[[{"label": "x"}]], + question_id="x", + ) + assert_matches_type(QuestionDeliverAnswerResponse, question, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_deliver_answer(self, client: Mobilerun) -> None: + response = client.agents.chat.question.with_raw_response.deliver_answer( + answers=[[{"label": "x"}]], + question_id="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + question = response.parse() + assert_matches_type(QuestionDeliverAnswerResponse, question, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_deliver_answer(self, client: Mobilerun) -> None: + with client.agents.chat.question.with_streaming_response.deliver_answer( + answers=[[{"label": "x"}]], + question_id="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + question = response.parse() + assert_matches_type(QuestionDeliverAnswerResponse, question, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_dismiss(self, client: Mobilerun) -> None: + question = client.agents.chat.question.dismiss( + question_id="x", + ) + assert_matches_type(QuestionDismissResponse, question, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_dismiss(self, client: Mobilerun) -> None: + response = client.agents.chat.question.with_raw_response.dismiss( + question_id="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + question = response.parse() + assert_matches_type(QuestionDismissResponse, question, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_dismiss(self, client: Mobilerun) -> None: + with client.agents.chat.question.with_streaming_response.dismiss( + question_id="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + question = response.parse() + assert_matches_type(QuestionDismissResponse, question, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncQuestion: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_deliver_answer(self, async_client: AsyncMobilerun) -> None: + question = await async_client.agents.chat.question.deliver_answer( + answers=[[{"label": "x"}]], + question_id="x", + ) + assert_matches_type(QuestionDeliverAnswerResponse, question, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_deliver_answer(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.chat.question.with_raw_response.deliver_answer( + answers=[[{"label": "x"}]], + question_id="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + question = await response.parse() + assert_matches_type(QuestionDeliverAnswerResponse, question, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_deliver_answer(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.chat.question.with_streaming_response.deliver_answer( + answers=[[{"label": "x"}]], + question_id="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + question = await response.parse() + assert_matches_type(QuestionDeliverAnswerResponse, question, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_dismiss(self, async_client: AsyncMobilerun) -> None: + question = await async_client.agents.chat.question.dismiss( + question_id="x", + ) + assert_matches_type(QuestionDismissResponse, question, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_dismiss(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.chat.question.with_raw_response.dismiss( + question_id="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + question = await response.parse() + assert_matches_type(QuestionDismissResponse, question, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_dismiss(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.chat.question.with_streaming_response.dismiss( + question_id="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + question = await response.parse() + assert_matches_type(QuestionDismissResponse, question, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/agents/files/__init__.py b/tests/api_resources/agents/files/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/agents/files/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/agents/files/test_file_id.py b/tests/api_resources/agents/files/test_file_id.py new file mode 100644 index 0000000..372cc6c --- /dev/null +++ b/tests/api_resources/agents/files/test_file_id.py @@ -0,0 +1,327 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.agents.files import ( + FileIDDeleteFileResponse, + FileIDConfirmUploadResponse, + FileIDUpdateMetadataResponse, + FileIDCancelPendingUploadResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestFileID: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_cancel_pending_upload(self, client: Mobilerun) -> None: + file_id = client.agents.files.file_id.cancel_pending_upload() + assert_matches_type(FileIDCancelPendingUploadResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_cancel_pending_upload(self, client: Mobilerun) -> None: + response = client.agents.files.file_id.with_raw_response.cancel_pending_upload() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file_id = response.parse() + assert_matches_type(FileIDCancelPendingUploadResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_cancel_pending_upload(self, client: Mobilerun) -> None: + with client.agents.files.file_id.with_streaming_response.cancel_pending_upload() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + file_id = response.parse() + assert_matches_type(FileIDCancelPendingUploadResponse, file_id, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_confirm_upload(self, client: Mobilerun) -> None: + file_id = client.agents.files.file_id.confirm_upload() + assert_matches_type(FileIDConfirmUploadResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_confirm_upload(self, client: Mobilerun) -> None: + response = client.agents.files.file_id.with_raw_response.confirm_upload() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file_id = response.parse() + assert_matches_type(FileIDConfirmUploadResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_confirm_upload(self, client: Mobilerun) -> None: + with client.agents.files.file_id.with_streaming_response.confirm_upload() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + file_id = response.parse() + assert_matches_type(FileIDConfirmUploadResponse, file_id, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete_file(self, client: Mobilerun) -> None: + file_id = client.agents.files.file_id.delete_file() + assert_matches_type(FileIDDeleteFileResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete_file(self, client: Mobilerun) -> None: + response = client.agents.files.file_id.with_raw_response.delete_file() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file_id = response.parse() + assert_matches_type(FileIDDeleteFileResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete_file(self, client: Mobilerun) -> None: + with client.agents.files.file_id.with_streaming_response.delete_file() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + file_id = response.parse() + assert_matches_type(FileIDDeleteFileResponse, file_id, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_download_file(self, client: Mobilerun) -> None: + file_id = client.agents.files.file_id.download_file() + assert file_id is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_download_file(self, client: Mobilerun) -> None: + response = client.agents.files.file_id.with_raw_response.download_file() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file_id = response.parse() + assert file_id is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_download_file(self, client: Mobilerun) -> None: + with client.agents.files.file_id.with_streaming_response.download_file() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + file_id = response.parse() + assert file_id is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update_metadata(self, client: Mobilerun) -> None: + file_id = client.agents.files.file_id.update_metadata() + assert_matches_type(FileIDUpdateMetadataResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update_metadata_with_all_params(self, client: Mobilerun) -> None: + file_id = client.agents.files.file_id.update_metadata( + display_name="x", + enabled=True, + ) + assert_matches_type(FileIDUpdateMetadataResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_update_metadata(self, client: Mobilerun) -> None: + response = client.agents.files.file_id.with_raw_response.update_metadata() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file_id = response.parse() + assert_matches_type(FileIDUpdateMetadataResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_update_metadata(self, client: Mobilerun) -> None: + with client.agents.files.file_id.with_streaming_response.update_metadata() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + file_id = response.parse() + assert_matches_type(FileIDUpdateMetadataResponse, file_id, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncFileID: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_cancel_pending_upload(self, async_client: AsyncMobilerun) -> None: + file_id = await async_client.agents.files.file_id.cancel_pending_upload() + assert_matches_type(FileIDCancelPendingUploadResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_cancel_pending_upload(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.files.file_id.with_raw_response.cancel_pending_upload() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file_id = await response.parse() + assert_matches_type(FileIDCancelPendingUploadResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_cancel_pending_upload(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.files.file_id.with_streaming_response.cancel_pending_upload() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + file_id = await response.parse() + assert_matches_type(FileIDCancelPendingUploadResponse, file_id, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_confirm_upload(self, async_client: AsyncMobilerun) -> None: + file_id = await async_client.agents.files.file_id.confirm_upload() + assert_matches_type(FileIDConfirmUploadResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_confirm_upload(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.files.file_id.with_raw_response.confirm_upload() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file_id = await response.parse() + assert_matches_type(FileIDConfirmUploadResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_confirm_upload(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.files.file_id.with_streaming_response.confirm_upload() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + file_id = await response.parse() + assert_matches_type(FileIDConfirmUploadResponse, file_id, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete_file(self, async_client: AsyncMobilerun) -> None: + file_id = await async_client.agents.files.file_id.delete_file() + assert_matches_type(FileIDDeleteFileResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete_file(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.files.file_id.with_raw_response.delete_file() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file_id = await response.parse() + assert_matches_type(FileIDDeleteFileResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete_file(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.files.file_id.with_streaming_response.delete_file() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + file_id = await response.parse() + assert_matches_type(FileIDDeleteFileResponse, file_id, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_download_file(self, async_client: AsyncMobilerun) -> None: + file_id = await async_client.agents.files.file_id.download_file() + assert file_id is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_download_file(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.files.file_id.with_raw_response.download_file() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file_id = await response.parse() + assert file_id is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_download_file(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.files.file_id.with_streaming_response.download_file() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + file_id = await response.parse() + assert file_id is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_metadata(self, async_client: AsyncMobilerun) -> None: + file_id = await async_client.agents.files.file_id.update_metadata() + assert_matches_type(FileIDUpdateMetadataResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_metadata_with_all_params(self, async_client: AsyncMobilerun) -> None: + file_id = await async_client.agents.files.file_id.update_metadata( + display_name="x", + enabled=True, + ) + assert_matches_type(FileIDUpdateMetadataResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_update_metadata(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.files.file_id.with_raw_response.update_metadata() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file_id = await response.parse() + assert_matches_type(FileIDUpdateMetadataResponse, file_id, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_update_metadata(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.files.file_id.with_streaming_response.update_metadata() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + file_id = await response.parse() + assert_matches_type(FileIDUpdateMetadataResponse, file_id, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/agents/test_chat.py b/tests/api_resources/agents/test_chat.py new file mode 100644 index 0000000..a5525f6 --- /dev/null +++ b/tests/api_resources/agents/test_chat.py @@ -0,0 +1,271 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.agents import ( + ChatGetChatStateResponse, + ChatRehydrateChatResponse, + ChatDeliverPermissionResponse, + ChatListSlashCommandsResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestChat: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_deliver_permission(self, client: Mobilerun) -> None: + chat = client.agents.chat.deliver_permission( + permission_id="x", + response="once", + ) + assert_matches_type(ChatDeliverPermissionResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_deliver_permission(self, client: Mobilerun) -> None: + response = client.agents.chat.with_raw_response.deliver_permission( + permission_id="x", + response="once", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + chat = response.parse() + assert_matches_type(ChatDeliverPermissionResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_deliver_permission(self, client: Mobilerun) -> None: + with client.agents.chat.with_streaming_response.deliver_permission( + permission_id="x", + response="once", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + chat = response.parse() + assert_matches_type(ChatDeliverPermissionResponse, chat, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_chat_state(self, client: Mobilerun) -> None: + chat = client.agents.chat.get_chat_state() + assert_matches_type(ChatGetChatStateResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_chat_state(self, client: Mobilerun) -> None: + response = client.agents.chat.with_raw_response.get_chat_state() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + chat = response.parse() + assert_matches_type(ChatGetChatStateResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_chat_state(self, client: Mobilerun) -> None: + with client.agents.chat.with_streaming_response.get_chat_state() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + chat = response.parse() + assert_matches_type(ChatGetChatStateResponse, chat, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_slash_commands(self, client: Mobilerun) -> None: + chat = client.agents.chat.list_slash_commands() + assert_matches_type(ChatListSlashCommandsResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list_slash_commands(self, client: Mobilerun) -> None: + response = client.agents.chat.with_raw_response.list_slash_commands() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + chat = response.parse() + assert_matches_type(ChatListSlashCommandsResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list_slash_commands(self, client: Mobilerun) -> None: + with client.agents.chat.with_streaming_response.list_slash_commands() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + chat = response.parse() + assert_matches_type(ChatListSlashCommandsResponse, chat, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_rehydrate_chat(self, client: Mobilerun) -> None: + chat = client.agents.chat.rehydrate_chat() + assert_matches_type(ChatRehydrateChatResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_rehydrate_chat(self, client: Mobilerun) -> None: + response = client.agents.chat.with_raw_response.rehydrate_chat() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + chat = response.parse() + assert_matches_type(ChatRehydrateChatResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_rehydrate_chat(self, client: Mobilerun) -> None: + with client.agents.chat.with_streaming_response.rehydrate_chat() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + chat = response.parse() + assert_matches_type(ChatRehydrateChatResponse, chat, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncChat: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_deliver_permission(self, async_client: AsyncMobilerun) -> None: + chat = await async_client.agents.chat.deliver_permission( + permission_id="x", + response="once", + ) + assert_matches_type(ChatDeliverPermissionResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_deliver_permission(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.chat.with_raw_response.deliver_permission( + permission_id="x", + response="once", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + chat = await response.parse() + assert_matches_type(ChatDeliverPermissionResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_deliver_permission(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.chat.with_streaming_response.deliver_permission( + permission_id="x", + response="once", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + chat = await response.parse() + assert_matches_type(ChatDeliverPermissionResponse, chat, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_chat_state(self, async_client: AsyncMobilerun) -> None: + chat = await async_client.agents.chat.get_chat_state() + assert_matches_type(ChatGetChatStateResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_chat_state(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.chat.with_raw_response.get_chat_state() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + chat = await response.parse() + assert_matches_type(ChatGetChatStateResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_chat_state(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.chat.with_streaming_response.get_chat_state() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + chat = await response.parse() + assert_matches_type(ChatGetChatStateResponse, chat, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_slash_commands(self, async_client: AsyncMobilerun) -> None: + chat = await async_client.agents.chat.list_slash_commands() + assert_matches_type(ChatListSlashCommandsResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list_slash_commands(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.chat.with_raw_response.list_slash_commands() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + chat = await response.parse() + assert_matches_type(ChatListSlashCommandsResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list_slash_commands(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.chat.with_streaming_response.list_slash_commands() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + chat = await response.parse() + assert_matches_type(ChatListSlashCommandsResponse, chat, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_rehydrate_chat(self, async_client: AsyncMobilerun) -> None: + chat = await async_client.agents.chat.rehydrate_chat() + assert_matches_type(ChatRehydrateChatResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_rehydrate_chat(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.chat.with_raw_response.rehydrate_chat() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + chat = await response.parse() + assert_matches_type(ChatRehydrateChatResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_rehydrate_chat(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.chat.with_streaming_response.rehydrate_chat() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + chat = await response.parse() + assert_matches_type(ChatRehydrateChatResponse, chat, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/agents/test_files.py b/tests/api_resources/agents/test_files.py new file mode 100644 index 0000000..133bc30 --- /dev/null +++ b/tests/api_resources/agents/test_files.py @@ -0,0 +1,203 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.agents import ( + FileListFilesResponse, + FileMintUploadURLResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestFiles: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_files(self, client: Mobilerun) -> None: + file = client.agents.files.list_files() + assert_matches_type(FileListFilesResponse, file, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_files_with_all_params(self, client: Mobilerun) -> None: + file = client.agents.files.list_files( + zone="user", + ) + assert_matches_type(FileListFilesResponse, file, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list_files(self, client: Mobilerun) -> None: + response = client.agents.files.with_raw_response.list_files() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = response.parse() + assert_matches_type(FileListFilesResponse, file, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list_files(self, client: Mobilerun) -> None: + with client.agents.files.with_streaming_response.list_files() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + file = response.parse() + assert_matches_type(FileListFilesResponse, file, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_mint_upload_url(self, client: Mobilerun) -> None: + file = client.agents.files.mint_upload_url( + filename="x", + mime_type="x", + size_bytes=1, + ) + assert_matches_type(FileMintUploadURLResponse, file, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_mint_upload_url_with_all_params(self, client: Mobilerun) -> None: + file = client.agents.files.mint_upload_url( + filename="x", + mime_type="x", + size_bytes=1, + zone="user", + idempotency_key="x", + ) + assert_matches_type(FileMintUploadURLResponse, file, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_mint_upload_url(self, client: Mobilerun) -> None: + response = client.agents.files.with_raw_response.mint_upload_url( + filename="x", + mime_type="x", + size_bytes=1, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = response.parse() + assert_matches_type(FileMintUploadURLResponse, file, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_mint_upload_url(self, client: Mobilerun) -> None: + with client.agents.files.with_streaming_response.mint_upload_url( + filename="x", + mime_type="x", + size_bytes=1, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + file = response.parse() + assert_matches_type(FileMintUploadURLResponse, file, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncFiles: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_files(self, async_client: AsyncMobilerun) -> None: + file = await async_client.agents.files.list_files() + assert_matches_type(FileListFilesResponse, file, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_files_with_all_params(self, async_client: AsyncMobilerun) -> None: + file = await async_client.agents.files.list_files( + zone="user", + ) + assert_matches_type(FileListFilesResponse, file, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list_files(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.files.with_raw_response.list_files() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = await response.parse() + assert_matches_type(FileListFilesResponse, file, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list_files(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.files.with_streaming_response.list_files() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + file = await response.parse() + assert_matches_type(FileListFilesResponse, file, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_mint_upload_url(self, async_client: AsyncMobilerun) -> None: + file = await async_client.agents.files.mint_upload_url( + filename="x", + mime_type="x", + size_bytes=1, + ) + assert_matches_type(FileMintUploadURLResponse, file, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_mint_upload_url_with_all_params(self, async_client: AsyncMobilerun) -> None: + file = await async_client.agents.files.mint_upload_url( + filename="x", + mime_type="x", + size_bytes=1, + zone="user", + idempotency_key="x", + ) + assert_matches_type(FileMintUploadURLResponse, file, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_mint_upload_url(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.files.with_raw_response.mint_upload_url( + filename="x", + mime_type="x", + size_bytes=1, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = await response.parse() + assert_matches_type(FileMintUploadURLResponse, file, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_mint_upload_url(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.files.with_streaming_response.mint_upload_url( + filename="x", + mime_type="x", + size_bytes=1, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + file = await response.parse() + assert_matches_type(FileMintUploadURLResponse, file, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_agents.py b/tests/api_resources/test_agents.py deleted file mode 100644 index 8087dea..0000000 --- a/tests/api_resources/test_agents.py +++ /dev/null @@ -1,80 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from tests.utils import assert_matches_type -from mobilerun_sdk import Mobilerun, AsyncMobilerun -from mobilerun_sdk.types import AgentListResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestAgents: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_list(self, client: Mobilerun) -> None: - agent = client.agents.list() - assert_matches_type(AgentListResponse, agent, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_list(self, client: Mobilerun) -> None: - response = client.agents.with_raw_response.list() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - agent = response.parse() - assert_matches_type(AgentListResponse, agent, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_list(self, client: Mobilerun) -> None: - with client.agents.with_streaming_response.list() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - agent = response.parse() - assert_matches_type(AgentListResponse, agent, path=["response"]) - - assert cast(Any, response.is_closed) is True - - -class TestAsyncAgents: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_list(self, async_client: AsyncMobilerun) -> None: - agent = await async_client.agents.list() - assert_matches_type(AgentListResponse, agent, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: - response = await async_client.agents.with_raw_response.list() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - agent = await response.parse() - assert_matches_type(AgentListResponse, agent, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: - async with async_client.agents.with_streaming_response.list() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - agent = await response.parse() - assert_matches_type(AgentListResponse, agent, path=["response"]) - - assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/workflows/test_flows.py b/tests/api_resources/workflows/test_flows.py index d4ba063..d7640f1 100644 --- a/tests/api_resources/workflows/test_flows.py +++ b/tests/api_resources/workflows/test_flows.py @@ -15,6 +15,7 @@ FlowCreateResponse, FlowDeleteResponse, FlowUpdateResponse, + FlowUnblockResponse, FlowRetrieveResponse, ) @@ -346,6 +347,48 @@ def test_path_params_clone(self, client: Mobilerun) -> None: flow_id="", ) + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_unblock(self, client: Mobilerun) -> None: + flow = client.workflows.flows.unblock( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowUnblockResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_unblock(self, client: Mobilerun) -> None: + response = client.workflows.flows.with_raw_response.unblock( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + flow = response.parse() + assert_matches_type(FlowUnblockResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_unblock(self, client: Mobilerun) -> None: + with client.workflows.flows.with_streaming_response.unblock( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + flow = response.parse() + assert_matches_type(FlowUnblockResponse, flow, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_unblock(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + client.workflows.flows.with_raw_response.unblock( + "", + ) + class TestAsyncFlows: parametrize = pytest.mark.parametrize( @@ -673,3 +716,45 @@ async def test_path_params_clone(self, async_client: AsyncMobilerun) -> None: await async_client.workflows.flows.with_raw_response.clone( flow_id="", ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_unblock(self, async_client: AsyncMobilerun) -> None: + flow = await async_client.workflows.flows.unblock( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(FlowUnblockResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_unblock(self, async_client: AsyncMobilerun) -> None: + response = await async_client.workflows.flows.with_raw_response.unblock( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + flow = await response.parse() + assert_matches_type(FlowUnblockResponse, flow, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_unblock(self, async_client: AsyncMobilerun) -> None: + async with async_client.workflows.flows.with_streaming_response.unblock( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + flow = await response.parse() + assert_matches_type(FlowUnblockResponse, flow, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_unblock(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `flow_id` but received ''"): + await async_client.workflows.flows.with_raw_response.unblock( + "", + ) From 7fa7979dda9d7827014ec82d390c622c3f096929 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 08:33:23 +0000 Subject: [PATCH 14/21] feat(api): manual updates --- .stats.yml | 6 +- README.md | 17 +- api.md | 34 +++ src/mobilerun_sdk/_client.py | 6 + .../resources/agents/__init__.py | 14 + src/mobilerun_sdk/resources/agents/agents.py | 101 +++++++ .../resources/agents/telegram/__init__.py | 33 ++ .../resources/agents/telegram/bots.py | 282 ++++++++++++++++++ .../resources/agents/telegram/telegram.py | 222 ++++++++++++++ src/mobilerun_sdk/types/__init__.py | 1 + .../types/agent_list_response.py | 33 ++ src/mobilerun_sdk/types/agents/__init__.py | 1 + .../types/agents/telegram/__init__.py | 7 + .../agents/telegram/bot_list_response.py | 31 ++ .../telegram/bot_request_link_response.py | 15 + .../telegram/bot_revoke_link_response.py | 11 + .../agents/telegram_receive_update_params.py | 49 +++ .../api_resources/agents/telegram/__init__.py | 1 + .../agents/telegram/test_bots.py | 220 ++++++++++++++ tests/api_resources/agents/test_telegram.py | 136 +++++++++ tests/api_resources/test_agents.py | 80 +++++ 21 files changed, 1288 insertions(+), 12 deletions(-) create mode 100644 src/mobilerun_sdk/resources/agents/telegram/__init__.py create mode 100644 src/mobilerun_sdk/resources/agents/telegram/bots.py create mode 100644 src/mobilerun_sdk/resources/agents/telegram/telegram.py create mode 100644 src/mobilerun_sdk/types/agent_list_response.py create mode 100644 src/mobilerun_sdk/types/agents/telegram/__init__.py create mode 100644 src/mobilerun_sdk/types/agents/telegram/bot_list_response.py create mode 100644 src/mobilerun_sdk/types/agents/telegram/bot_request_link_response.py create mode 100644 src/mobilerun_sdk/types/agents/telegram/bot_revoke_link_response.py create mode 100644 src/mobilerun_sdk/types/agents/telegram_receive_update_params.py create mode 100644 tests/api_resources/agents/telegram/__init__.py create mode 100644 tests/api_resources/agents/telegram/test_bots.py create mode 100644 tests/api_resources/agents/test_telegram.py create mode 100644 tests/api_resources/test_agents.py diff --git a/.stats.yml b/.stats.yml index fc53991..d6b16f9 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 158 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-af9a32a09b514040aa7da0199ecd9c2084733f81afdccad87bdf48b7c63756d6.yml +configured_endpoints: 163 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-74bcd5b17c204f3ed69b241a2077b638fff3357fcff267c7e07b1a7aec85acb2.yml openapi_spec_hash: 29b62d198d5699a230afd5397359cecb -config_hash: fc0353d3ca4f3676121e9780c20f0490 +config_hash: 24cb7c22ef5bfbe580e8b3cd6738c2a6 diff --git a/README.md b/README.md index 73b8b1d..7ca1fa3 100644 --- a/README.md +++ b/README.md @@ -124,17 +124,16 @@ from mobilerun_sdk import Mobilerun client = Mobilerun() -device = client.devices.create( - carrier={ - "gsm_operator_alpha": "GsmOperatorAlpha", - "gsm_operator_numeric": 0, - "gsm_sim_operator_alpha": "GsmSimOperatorAlpha", - "gsm_sim_operator_iso_country": "GsmSimOperatorIsoCountry", - "gsm_sim_operator_numeric": 0, - "persist_sys_timezone": "PersistSysTimezone", +client.agents.telegram.receive_update( + update_id=0, + message={ + "chat": { + "id": 0, + "type": "type", + }, + "message_id": 0, }, ) -print(device.carrier) ``` ## File uploads diff --git a/api.md b/api.md index c364f55..f9cf5eb 100644 --- a/api.md +++ b/api.md @@ -16,6 +16,16 @@ from mobilerun_sdk.types import ( # Agents +Types: + +```python +from mobilerun_sdk.types import AgentListResponse +``` + +Methods: + +- client.agents.list() -> AgentListResponse + ## Chat Types: @@ -96,6 +106,30 @@ Methods: - client.agents.files.file_id.download_file() -> None - client.agents.files.file_id.update_metadata(\*\*params) -> FileIDUpdateMetadataResponse +## Telegram + +Methods: + +- client.agents.telegram.receive_update(\*\*params) -> None + +### Bots + +Types: + +```python +from mobilerun_sdk.types.agents.telegram import ( + BotListResponse, + BotRequestLinkResponse, + BotRevokeLinkResponse, +) +``` + +Methods: + +- client.agents.telegram.bots.list() -> BotListResponse +- client.agents.telegram.bots.request_link() -> BotRequestLinkResponse +- client.agents.telegram.bots.revoke_link(id) -> BotRevokeLinkResponse + # Apps Types: diff --git a/src/mobilerun_sdk/_client.py b/src/mobilerun_sdk/_client.py index 569a208..e43e45a 100644 --- a/src/mobilerun_sdk/_client.py +++ b/src/mobilerun_sdk/_client.py @@ -135,6 +135,7 @@ def __init__( @cached_property def agents(self) -> AgentsResource: + """Agents API""" from .resources.agents import AgentsResource return AgentsResource(self) @@ -391,6 +392,7 @@ def __init__( @cached_property def agents(self) -> AsyncAgentsResource: + """Agents API""" from .resources.agents import AsyncAgentsResource return AsyncAgentsResource(self) @@ -593,6 +595,7 @@ def __init__(self, client: Mobilerun) -> None: @cached_property def agents(self) -> agents.AgentsResourceWithRawResponse: + """Agents API""" from .resources.agents import AgentsResourceWithRawResponse return AgentsResourceWithRawResponse(self._client.agents) @@ -672,6 +675,7 @@ def __init__(self, client: AsyncMobilerun) -> None: @cached_property def agents(self) -> agents.AsyncAgentsResourceWithRawResponse: + """Agents API""" from .resources.agents import AsyncAgentsResourceWithRawResponse return AsyncAgentsResourceWithRawResponse(self._client.agents) @@ -751,6 +755,7 @@ def __init__(self, client: Mobilerun) -> None: @cached_property def agents(self) -> agents.AgentsResourceWithStreamingResponse: + """Agents API""" from .resources.agents import AgentsResourceWithStreamingResponse return AgentsResourceWithStreamingResponse(self._client.agents) @@ -830,6 +835,7 @@ def __init__(self, client: AsyncMobilerun) -> None: @cached_property def agents(self) -> agents.AsyncAgentsResourceWithStreamingResponse: + """Agents API""" from .resources.agents import AsyncAgentsResourceWithStreamingResponse return AsyncAgentsResourceWithStreamingResponse(self._client.agents) diff --git a/src/mobilerun_sdk/resources/agents/__init__.py b/src/mobilerun_sdk/resources/agents/__init__.py index 8cd1035..1ac6c3b 100644 --- a/src/mobilerun_sdk/resources/agents/__init__.py +++ b/src/mobilerun_sdk/resources/agents/__init__.py @@ -24,6 +24,14 @@ AgentsResourceWithStreamingResponse, AsyncAgentsResourceWithStreamingResponse, ) +from .telegram import ( + TelegramResource, + AsyncTelegramResource, + TelegramResourceWithRawResponse, + AsyncTelegramResourceWithRawResponse, + TelegramResourceWithStreamingResponse, + AsyncTelegramResourceWithStreamingResponse, +) __all__ = [ "ChatResource", @@ -38,6 +46,12 @@ "AsyncFilesResourceWithRawResponse", "FilesResourceWithStreamingResponse", "AsyncFilesResourceWithStreamingResponse", + "TelegramResource", + "AsyncTelegramResource", + "TelegramResourceWithRawResponse", + "AsyncTelegramResourceWithRawResponse", + "TelegramResourceWithStreamingResponse", + "AsyncTelegramResourceWithStreamingResponse", "AgentsResource", "AsyncAgentsResource", "AgentsResourceWithRawResponse", diff --git a/src/mobilerun_sdk/resources/agents/agents.py b/src/mobilerun_sdk/resources/agents/agents.py index 1d6053a..c6d5492 100644 --- a/src/mobilerun_sdk/resources/agents/agents.py +++ b/src/mobilerun_sdk/resources/agents/agents.py @@ -2,6 +2,9 @@ from __future__ import annotations +import httpx + +from ..._types import Body, Query, Headers, NotGiven, not_given from ..._compat import cached_property from .chat.chat import ( ChatResource, @@ -12,6 +15,12 @@ AsyncChatResourceWithStreamingResponse, ) from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) from .files.files import ( FilesResource, AsyncFilesResource, @@ -20,11 +29,23 @@ FilesResourceWithStreamingResponse, AsyncFilesResourceWithStreamingResponse, ) +from ..._base_client import make_request_options +from .telegram.telegram import ( + TelegramResource, + AsyncTelegramResource, + TelegramResourceWithRawResponse, + AsyncTelegramResourceWithRawResponse, + TelegramResourceWithStreamingResponse, + AsyncTelegramResourceWithStreamingResponse, +) +from ...types.agent_list_response import AgentListResponse __all__ = ["AgentsResource", "AsyncAgentsResource"] class AgentsResource(SyncAPIResource): + """Agents API""" + @cached_property def chat(self) -> ChatResource: return ChatResource(self._client) @@ -33,6 +54,10 @@ def chat(self) -> ChatResource: def files(self) -> FilesResource: return FilesResource(self._client) + @cached_property + def telegram(self) -> TelegramResource: + return TelegramResource(self._client) + @cached_property def with_raw_response(self) -> AgentsResourceWithRawResponse: """ @@ -52,8 +77,29 @@ def with_streaming_response(self) -> AgentsResourceWithStreamingResponse: """ return AgentsResourceWithStreamingResponse(self) + def list( + self, + *, + # 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, + ) -> AgentListResponse: + """List all available agents with their default configurations.""" + return self._get( + "/agents", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AgentListResponse, + ) + class AsyncAgentsResource(AsyncAPIResource): + """Agents API""" + @cached_property def chat(self) -> AsyncChatResource: return AsyncChatResource(self._client) @@ -62,6 +108,10 @@ def chat(self) -> AsyncChatResource: def files(self) -> AsyncFilesResource: return AsyncFilesResource(self._client) + @cached_property + def telegram(self) -> AsyncTelegramResource: + return AsyncTelegramResource(self._client) + @cached_property def with_raw_response(self) -> AsyncAgentsResourceWithRawResponse: """ @@ -81,11 +131,34 @@ def with_streaming_response(self) -> AsyncAgentsResourceWithStreamingResponse: """ return AsyncAgentsResourceWithStreamingResponse(self) + async def list( + self, + *, + # 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, + ) -> AgentListResponse: + """List all available agents with their default configurations.""" + return await self._get( + "/agents", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AgentListResponse, + ) + class AgentsResourceWithRawResponse: def __init__(self, agents: AgentsResource) -> None: self._agents = agents + self.list = to_raw_response_wrapper( + agents.list, + ) + @cached_property def chat(self) -> ChatResourceWithRawResponse: return ChatResourceWithRawResponse(self._agents.chat) @@ -94,11 +167,19 @@ def chat(self) -> ChatResourceWithRawResponse: def files(self) -> FilesResourceWithRawResponse: return FilesResourceWithRawResponse(self._agents.files) + @cached_property + def telegram(self) -> TelegramResourceWithRawResponse: + return TelegramResourceWithRawResponse(self._agents.telegram) + class AsyncAgentsResourceWithRawResponse: def __init__(self, agents: AsyncAgentsResource) -> None: self._agents = agents + self.list = async_to_raw_response_wrapper( + agents.list, + ) + @cached_property def chat(self) -> AsyncChatResourceWithRawResponse: return AsyncChatResourceWithRawResponse(self._agents.chat) @@ -107,11 +188,19 @@ def chat(self) -> AsyncChatResourceWithRawResponse: def files(self) -> AsyncFilesResourceWithRawResponse: return AsyncFilesResourceWithRawResponse(self._agents.files) + @cached_property + def telegram(self) -> AsyncTelegramResourceWithRawResponse: + return AsyncTelegramResourceWithRawResponse(self._agents.telegram) + class AgentsResourceWithStreamingResponse: def __init__(self, agents: AgentsResource) -> None: self._agents = agents + self.list = to_streamed_response_wrapper( + agents.list, + ) + @cached_property def chat(self) -> ChatResourceWithStreamingResponse: return ChatResourceWithStreamingResponse(self._agents.chat) @@ -120,11 +209,19 @@ def chat(self) -> ChatResourceWithStreamingResponse: def files(self) -> FilesResourceWithStreamingResponse: return FilesResourceWithStreamingResponse(self._agents.files) + @cached_property + def telegram(self) -> TelegramResourceWithStreamingResponse: + return TelegramResourceWithStreamingResponse(self._agents.telegram) + class AsyncAgentsResourceWithStreamingResponse: def __init__(self, agents: AsyncAgentsResource) -> None: self._agents = agents + self.list = async_to_streamed_response_wrapper( + agents.list, + ) + @cached_property def chat(self) -> AsyncChatResourceWithStreamingResponse: return AsyncChatResourceWithStreamingResponse(self._agents.chat) @@ -132,3 +229,7 @@ def chat(self) -> AsyncChatResourceWithStreamingResponse: @cached_property def files(self) -> AsyncFilesResourceWithStreamingResponse: return AsyncFilesResourceWithStreamingResponse(self._agents.files) + + @cached_property + def telegram(self) -> AsyncTelegramResourceWithStreamingResponse: + return AsyncTelegramResourceWithStreamingResponse(self._agents.telegram) diff --git a/src/mobilerun_sdk/resources/agents/telegram/__init__.py b/src/mobilerun_sdk/resources/agents/telegram/__init__.py new file mode 100644 index 0000000..712a44e --- /dev/null +++ b/src/mobilerun_sdk/resources/agents/telegram/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .bots import ( + BotsResource, + AsyncBotsResource, + BotsResourceWithRawResponse, + AsyncBotsResourceWithRawResponse, + BotsResourceWithStreamingResponse, + AsyncBotsResourceWithStreamingResponse, +) +from .telegram import ( + TelegramResource, + AsyncTelegramResource, + TelegramResourceWithRawResponse, + AsyncTelegramResourceWithRawResponse, + TelegramResourceWithStreamingResponse, + AsyncTelegramResourceWithStreamingResponse, +) + +__all__ = [ + "BotsResource", + "AsyncBotsResource", + "BotsResourceWithRawResponse", + "AsyncBotsResourceWithRawResponse", + "BotsResourceWithStreamingResponse", + "AsyncBotsResourceWithStreamingResponse", + "TelegramResource", + "AsyncTelegramResource", + "TelegramResourceWithRawResponse", + "AsyncTelegramResourceWithRawResponse", + "TelegramResourceWithStreamingResponse", + "AsyncTelegramResourceWithStreamingResponse", +] diff --git a/src/mobilerun_sdk/resources/agents/telegram/bots.py b/src/mobilerun_sdk/resources/agents/telegram/bots.py new file mode 100644 index 0000000..473baa6 --- /dev/null +++ b/src/mobilerun_sdk/resources/agents/telegram/bots.py @@ -0,0 +1,282 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._base_client import make_request_options +from ....types.agents.telegram.bot_list_response import BotListResponse +from ....types.agents.telegram.bot_revoke_link_response import BotRevokeLinkResponse +from ....types.agents.telegram.bot_request_link_response import BotRequestLinkResponse + +__all__ = ["BotsResource", "AsyncBotsResource"] + + +class BotsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> BotsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return BotsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> BotsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return BotsResourceWithStreamingResponse(self) + + def list( + self, + *, + # 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, + ) -> BotListResponse: + """List the current user's Telegram link rows""" + return self._get( + "/agents/telegram/bots", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BotListResponse, + ) + + def request_link( + self, + *, + # 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, + ) -> BotRequestLinkResponse: + """ + Issues a one-shot deeplink (`t.me/?start=`) for the + operator-owned shared bot. The user opens the link, taps `Start`, and the + webhook binds their Telegram account to this droidrun user. No bot token is + needed from the user — the operator owns the bot. + """ + return self._post( + "/agents/telegram/bots/connect", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BotRequestLinkResponse, + ) + + def revoke_link( + self, + id: str, + *, + # 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, + ) -> BotRevokeLinkResponse: + """Disables the link. + + Future inbound messages from this Telegram account get the + welcome reply. The existing chat history is NOT wiped — start a fresh chat from + the UI if you suspect compromise. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._post( + path_template("/agents/telegram/bots/{id}/revoke", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BotRevokeLinkResponse, + ) + + +class AsyncBotsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncBotsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncBotsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncBotsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncBotsResourceWithStreamingResponse(self) + + async def list( + self, + *, + # 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, + ) -> BotListResponse: + """List the current user's Telegram link rows""" + return await self._get( + "/agents/telegram/bots", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BotListResponse, + ) + + async def request_link( + self, + *, + # 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, + ) -> BotRequestLinkResponse: + """ + Issues a one-shot deeplink (`t.me/?start=`) for the + operator-owned shared bot. The user opens the link, taps `Start`, and the + webhook binds their Telegram account to this droidrun user. No bot token is + needed from the user — the operator owns the bot. + """ + return await self._post( + "/agents/telegram/bots/connect", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BotRequestLinkResponse, + ) + + async def revoke_link( + self, + id: str, + *, + # 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, + ) -> BotRevokeLinkResponse: + """Disables the link. + + Future inbound messages from this Telegram account get the + welcome reply. The existing chat history is NOT wiped — start a fresh chat from + the UI if you suspect compromise. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._post( + path_template("/agents/telegram/bots/{id}/revoke", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BotRevokeLinkResponse, + ) + + +class BotsResourceWithRawResponse: + def __init__(self, bots: BotsResource) -> None: + self._bots = bots + + self.list = to_raw_response_wrapper( + bots.list, + ) + self.request_link = to_raw_response_wrapper( + bots.request_link, + ) + self.revoke_link = to_raw_response_wrapper( + bots.revoke_link, + ) + + +class AsyncBotsResourceWithRawResponse: + def __init__(self, bots: AsyncBotsResource) -> None: + self._bots = bots + + self.list = async_to_raw_response_wrapper( + bots.list, + ) + self.request_link = async_to_raw_response_wrapper( + bots.request_link, + ) + self.revoke_link = async_to_raw_response_wrapper( + bots.revoke_link, + ) + + +class BotsResourceWithStreamingResponse: + def __init__(self, bots: BotsResource) -> None: + self._bots = bots + + self.list = to_streamed_response_wrapper( + bots.list, + ) + self.request_link = to_streamed_response_wrapper( + bots.request_link, + ) + self.revoke_link = to_streamed_response_wrapper( + bots.revoke_link, + ) + + +class AsyncBotsResourceWithStreamingResponse: + def __init__(self, bots: AsyncBotsResource) -> None: + self._bots = bots + + self.list = async_to_streamed_response_wrapper( + bots.list, + ) + self.request_link = async_to_streamed_response_wrapper( + bots.request_link, + ) + self.revoke_link = async_to_streamed_response_wrapper( + bots.revoke_link, + ) diff --git a/src/mobilerun_sdk/resources/agents/telegram/telegram.py b/src/mobilerun_sdk/resources/agents/telegram/telegram.py new file mode 100644 index 0000000..c41e885 --- /dev/null +++ b/src/mobilerun_sdk/resources/agents/telegram/telegram.py @@ -0,0 +1,222 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from .bots import ( + BotsResource, + AsyncBotsResource, + BotsResourceWithRawResponse, + AsyncBotsResourceWithRawResponse, + BotsResourceWithStreamingResponse, + AsyncBotsResourceWithStreamingResponse, +) +from ...._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given +from ...._utils import maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._base_client import make_request_options +from ....types.agents import telegram_receive_update_params + +__all__ = ["TelegramResource", "AsyncTelegramResource"] + + +class TelegramResource(SyncAPIResource): + @cached_property + def bots(self) -> BotsResource: + return BotsResource(self._client) + + @cached_property + def with_raw_response(self) -> TelegramResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return TelegramResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> TelegramResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return TelegramResourceWithStreamingResponse(self) + + def receive_update( + self, + *, + update_id: float, + message: telegram_receive_update_params.Message | 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, + ) -> None: + """ + Public endpoint called by Telegram's servers for the operator-owned shared bot. + One fixed URL, one fixed secret: the orchestrator compares + `X-Telegram-Bot-Api-Secret-Token` against `env.TELEGRAM_WEBHOOK_SECRET` with a + constant-time check. Inbound routing keys on `message.from.id` (Telegram user + id) → active link row → droidrun user. Returns 200 for ignorable events (group + chats, dedup hits, unrecognized senders) to avoid Telegram retry storms; 401 + only for missing/wrong secret; 400 for malformed bodies. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return self._post( + "/agents/telegram/webhook", + body=maybe_transform( + { + "update_id": update_id, + "message": message, + }, + telegram_receive_update_params.TelegramReceiveUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + +class AsyncTelegramResource(AsyncAPIResource): + @cached_property + def bots(self) -> AsyncBotsResource: + return AsyncBotsResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncTelegramResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncTelegramResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncTelegramResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncTelegramResourceWithStreamingResponse(self) + + async def receive_update( + self, + *, + update_id: float, + message: telegram_receive_update_params.Message | 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, + ) -> None: + """ + Public endpoint called by Telegram's servers for the operator-owned shared bot. + One fixed URL, one fixed secret: the orchestrator compares + `X-Telegram-Bot-Api-Secret-Token` against `env.TELEGRAM_WEBHOOK_SECRET` with a + constant-time check. Inbound routing keys on `message.from.id` (Telegram user + id) → active link row → droidrun user. Returns 200 for ignorable events (group + chats, dedup hits, unrecognized senders) to avoid Telegram retry storms; 401 + only for missing/wrong secret; 400 for malformed bodies. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + return await self._post( + "/agents/telegram/webhook", + body=await async_maybe_transform( + { + "update_id": update_id, + "message": message, + }, + telegram_receive_update_params.TelegramReceiveUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=NoneType, + ) + + +class TelegramResourceWithRawResponse: + def __init__(self, telegram: TelegramResource) -> None: + self._telegram = telegram + + self.receive_update = to_raw_response_wrapper( + telegram.receive_update, + ) + + @cached_property + def bots(self) -> BotsResourceWithRawResponse: + return BotsResourceWithRawResponse(self._telegram.bots) + + +class AsyncTelegramResourceWithRawResponse: + def __init__(self, telegram: AsyncTelegramResource) -> None: + self._telegram = telegram + + self.receive_update = async_to_raw_response_wrapper( + telegram.receive_update, + ) + + @cached_property + def bots(self) -> AsyncBotsResourceWithRawResponse: + return AsyncBotsResourceWithRawResponse(self._telegram.bots) + + +class TelegramResourceWithStreamingResponse: + def __init__(self, telegram: TelegramResource) -> None: + self._telegram = telegram + + self.receive_update = to_streamed_response_wrapper( + telegram.receive_update, + ) + + @cached_property + def bots(self) -> BotsResourceWithStreamingResponse: + return BotsResourceWithStreamingResponse(self._telegram.bots) + + +class AsyncTelegramResourceWithStreamingResponse: + def __init__(self, telegram: AsyncTelegramResource) -> None: + self._telegram = telegram + + self.receive_update = async_to_streamed_response_wrapper( + telegram.receive_update, + ) + + @cached_property + def bots(self) -> AsyncBotsResourceWithStreamingResponse: + return AsyncBotsResourceWithStreamingResponse(self._telegram.bots) diff --git a/src/mobilerun_sdk/types/__init__.py b/src/mobilerun_sdk/types/__init__.py index 2b5082d..e641405 100644 --- a/src/mobilerun_sdk/types/__init__.py +++ b/src/mobilerun_sdk/types/__init__.py @@ -36,6 +36,7 @@ from .hook_update_params import HookUpdateParams as HookUpdateParams from .task_list_response import TaskListResponse as TaskListResponse from .task_stop_response import TaskStopResponse as TaskStopResponse +from .agent_list_response import AgentListResponse as AgentListResponse from .app_delete_response import AppDeleteResponse as AppDeleteResponse from .carrier_list_params import CarrierListParams as CarrierListParams from .hook_perform_params import HookPerformParams as HookPerformParams diff --git a/src/mobilerun_sdk/types/agent_list_response.py b/src/mobilerun_sdk/types/agent_list_response.py new file mode 100644 index 0000000..fc366d6 --- /dev/null +++ b/src/mobilerun_sdk/types/agent_list_response.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import TypeAlias + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["AgentListResponse", "AgentListResponseItem"] + + +class AgentListResponseItem(BaseModel): + id: int + + description: Optional[str] = None + + icon: str + + llm_model: str = FieldInfo(alias="llmModel") + + max_steps: int = FieldInfo(alias="maxSteps") + + name: str + + reasoning: bool + + subagent_model: Optional[str] = FieldInfo(alias="subagentModel", default=None) + + vision: bool + + +AgentListResponse: TypeAlias = List[AgentListResponseItem] diff --git a/src/mobilerun_sdk/types/agents/__init__.py b/src/mobilerun_sdk/types/agents/__init__.py index f8cfbf9..1634fda 100644 --- a/src/mobilerun_sdk/types/agents/__init__.py +++ b/src/mobilerun_sdk/types/agents/__init__.py @@ -9,5 +9,6 @@ from .chat_rehydrate_chat_response import ChatRehydrateChatResponse as ChatRehydrateChatResponse from .file_mint_upload_url_response import FileMintUploadURLResponse as FileMintUploadURLResponse from .chat_deliver_permission_params import ChatDeliverPermissionParams as ChatDeliverPermissionParams +from .telegram_receive_update_params import TelegramReceiveUpdateParams as TelegramReceiveUpdateParams from .chat_deliver_permission_response import ChatDeliverPermissionResponse as ChatDeliverPermissionResponse from .chat_list_slash_commands_response import ChatListSlashCommandsResponse as ChatListSlashCommandsResponse diff --git a/src/mobilerun_sdk/types/agents/telegram/__init__.py b/src/mobilerun_sdk/types/agents/telegram/__init__.py new file mode 100644 index 0000000..b6a23cd --- /dev/null +++ b/src/mobilerun_sdk/types/agents/telegram/__init__.py @@ -0,0 +1,7 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .bot_list_response import BotListResponse as BotListResponse +from .bot_revoke_link_response import BotRevokeLinkResponse as BotRevokeLinkResponse +from .bot_request_link_response import BotRequestLinkResponse as BotRequestLinkResponse diff --git a/src/mobilerun_sdk/types/agents/telegram/bot_list_response.py b/src/mobilerun_sdk/types/agents/telegram/bot_list_response.py new file mode 100644 index 0000000..72f70d8 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/telegram/bot_list_response.py @@ -0,0 +1,31 @@ +# 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__ = ["BotListResponse", "Bot"] + + +class Bot(BaseModel): + id: str + + bot_username: str = FieldInfo(alias="botUsername") + + created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None) + + last_message_at: Optional[datetime] = FieldInfo(alias="lastMessageAt", default=None) + + link_code_expires_at: Optional[datetime] = FieldInfo(alias="linkCodeExpiresAt", default=None) + + owner_telegram_user_id: Optional[int] = FieldInfo(alias="ownerTelegramUserId", default=None) + + status: Literal["pending", "active", "disabled"] + + +class BotListResponse(BaseModel): + bots: List[Bot] diff --git a/src/mobilerun_sdk/types/agents/telegram/bot_request_link_response.py b/src/mobilerun_sdk/types/agents/telegram/bot_request_link_response.py new file mode 100644 index 0000000..98bc329 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/telegram/bot_request_link_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from pydantic import Field as FieldInfo + +from ...._models import BaseModel + +__all__ = ["BotRequestLinkResponse"] + + +class BotRequestLinkResponse(BaseModel): + id: str + + bot_username: str = FieldInfo(alias="botUsername") + + deep_link: str = FieldInfo(alias="deepLink") diff --git a/src/mobilerun_sdk/types/agents/telegram/bot_revoke_link_response.py b/src/mobilerun_sdk/types/agents/telegram/bot_revoke_link_response.py new file mode 100644 index 0000000..0ff50b6 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/telegram/bot_revoke_link_response.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["BotRevokeLinkResponse"] + + +class BotRevokeLinkResponse(BaseModel): + revoked: Literal[True] diff --git a/src/mobilerun_sdk/types/agents/telegram_receive_update_params.py b/src/mobilerun_sdk/types/agents/telegram_receive_update_params.py new file mode 100644 index 0000000..549300e --- /dev/null +++ b/src/mobilerun_sdk/types/agents/telegram_receive_update_params.py @@ -0,0 +1,49 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Required, TypedDict + +__all__ = ["TelegramReceiveUpdateParams", "Message", "MessageChat", "MessageFrom"] + + +class TelegramReceiveUpdateParams(TypedDict, total=False): + update_id: Required[float] + + message: Message + + +class MessageChat(TypedDict, total=False, extra_items=Optional[object]): # type: ignore[call-arg] + id: Required[float] + + type: Required[str] + + +class MessageFrom(TypedDict, total=False, extra_items=Optional[object]): # type: ignore[call-arg] + id: Required[float] + + first_name: str + + is_bot: bool + + username: str + + +_MessageReservedKeywords = TypedDict( + "_MessageReservedKeywords", + { + "from": MessageFrom, + }, + total=False, +) + + +class Message(_MessageReservedKeywords, total=False, extra_items=Optional[object]): # type: ignore[call-arg] + chat: Required[MessageChat] + + message_id: Required[float] + + caption: str + + text: str diff --git a/tests/api_resources/agents/telegram/__init__.py b/tests/api_resources/agents/telegram/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/agents/telegram/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/agents/telegram/test_bots.py b/tests/api_resources/agents/telegram/test_bots.py new file mode 100644 index 0000000..524c869 --- /dev/null +++ b/tests/api_resources/agents/telegram/test_bots.py @@ -0,0 +1,220 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.agents.telegram import BotListResponse, BotRevokeLinkResponse, BotRequestLinkResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestBots: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + bot = client.agents.telegram.bots.list() + assert_matches_type(BotListResponse, bot, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.agents.telegram.bots.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + bot = response.parse() + assert_matches_type(BotListResponse, bot, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.agents.telegram.bots.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + bot = response.parse() + assert_matches_type(BotListResponse, bot, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_request_link(self, client: Mobilerun) -> None: + bot = client.agents.telegram.bots.request_link() + assert_matches_type(BotRequestLinkResponse, bot, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_request_link(self, client: Mobilerun) -> None: + response = client.agents.telegram.bots.with_raw_response.request_link() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + bot = response.parse() + assert_matches_type(BotRequestLinkResponse, bot, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_request_link(self, client: Mobilerun) -> None: + with client.agents.telegram.bots.with_streaming_response.request_link() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + bot = response.parse() + assert_matches_type(BotRequestLinkResponse, bot, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_revoke_link(self, client: Mobilerun) -> None: + bot = client.agents.telegram.bots.revoke_link( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(BotRevokeLinkResponse, bot, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_revoke_link(self, client: Mobilerun) -> None: + response = client.agents.telegram.bots.with_raw_response.revoke_link( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + bot = response.parse() + assert_matches_type(BotRevokeLinkResponse, bot, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_revoke_link(self, client: Mobilerun) -> None: + with client.agents.telegram.bots.with_streaming_response.revoke_link( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + bot = response.parse() + assert_matches_type(BotRevokeLinkResponse, bot, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_revoke_link(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.agents.telegram.bots.with_raw_response.revoke_link( + "", + ) + + +class TestAsyncBots: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + bot = await async_client.agents.telegram.bots.list() + assert_matches_type(BotListResponse, bot, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.telegram.bots.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + bot = await response.parse() + assert_matches_type(BotListResponse, bot, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.telegram.bots.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + bot = await response.parse() + assert_matches_type(BotListResponse, bot, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_request_link(self, async_client: AsyncMobilerun) -> None: + bot = await async_client.agents.telegram.bots.request_link() + assert_matches_type(BotRequestLinkResponse, bot, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_request_link(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.telegram.bots.with_raw_response.request_link() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + bot = await response.parse() + assert_matches_type(BotRequestLinkResponse, bot, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_request_link(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.telegram.bots.with_streaming_response.request_link() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + bot = await response.parse() + assert_matches_type(BotRequestLinkResponse, bot, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_revoke_link(self, async_client: AsyncMobilerun) -> None: + bot = await async_client.agents.telegram.bots.revoke_link( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(BotRevokeLinkResponse, bot, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_revoke_link(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.telegram.bots.with_raw_response.revoke_link( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + bot = await response.parse() + assert_matches_type(BotRevokeLinkResponse, bot, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_revoke_link(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.telegram.bots.with_streaming_response.revoke_link( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + bot = await response.parse() + assert_matches_type(BotRevokeLinkResponse, bot, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_revoke_link(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.agents.telegram.bots.with_raw_response.revoke_link( + "", + ) diff --git a/tests/api_resources/agents/test_telegram.py b/tests/api_resources/agents/test_telegram.py new file mode 100644 index 0000000..c052107 --- /dev/null +++ b/tests/api_resources/agents/test_telegram.py @@ -0,0 +1,136 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from mobilerun_sdk import Mobilerun, AsyncMobilerun + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestTelegram: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_receive_update(self, client: Mobilerun) -> None: + telegram = client.agents.telegram.receive_update( + update_id=0, + ) + assert telegram is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_receive_update_with_all_params(self, client: Mobilerun) -> None: + telegram = client.agents.telegram.receive_update( + update_id=0, + message={ + "chat": { + "id": 0, + "type": "type", + }, + "message_id": 0, + "caption": "caption", + "from": { + "id": 0, + "first_name": "first_name", + "is_bot": True, + "username": "username", + }, + "text": "text", + }, + ) + assert telegram is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_receive_update(self, client: Mobilerun) -> None: + response = client.agents.telegram.with_raw_response.receive_update( + update_id=0, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + telegram = response.parse() + assert telegram is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_receive_update(self, client: Mobilerun) -> None: + with client.agents.telegram.with_streaming_response.receive_update( + update_id=0, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + telegram = response.parse() + assert telegram is None + + assert cast(Any, response.is_closed) is True + + +class TestAsyncTelegram: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_receive_update(self, async_client: AsyncMobilerun) -> None: + telegram = await async_client.agents.telegram.receive_update( + update_id=0, + ) + assert telegram is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_receive_update_with_all_params(self, async_client: AsyncMobilerun) -> None: + telegram = await async_client.agents.telegram.receive_update( + update_id=0, + message={ + "chat": { + "id": 0, + "type": "type", + }, + "message_id": 0, + "caption": "caption", + "from": { + "id": 0, + "first_name": "first_name", + "is_bot": True, + "username": "username", + }, + "text": "text", + }, + ) + assert telegram is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_receive_update(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.telegram.with_raw_response.receive_update( + update_id=0, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + telegram = await response.parse() + assert telegram is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_receive_update(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.telegram.with_streaming_response.receive_update( + update_id=0, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + telegram = await response.parse() + assert telegram is None + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_agents.py b/tests/api_resources/test_agents.py new file mode 100644 index 0000000..8087dea --- /dev/null +++ b/tests/api_resources/test_agents.py @@ -0,0 +1,80 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types import AgentListResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestAgents: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + agent = client.agents.list() + assert_matches_type(AgentListResponse, agent, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.agents.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + agent = response.parse() + assert_matches_type(AgentListResponse, agent, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.agents.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + agent = response.parse() + assert_matches_type(AgentListResponse, agent, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncAgents: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + agent = await async_client.agents.list() + assert_matches_type(AgentListResponse, agent, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + agent = await response.parse() + assert_matches_type(AgentListResponse, agent, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + agent = await response.parse() + assert_matches_type(AgentListResponse, agent, path=["response"]) + + assert cast(Any, response.is_closed) is True From 1b32b0daa46383c045df0b9ec5e8903d0c6b8808 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 08:36:27 +0000 Subject: [PATCH 15/21] feat(api): manual updates --- .stats.yml | 6 +- api.md | 6 + .../resources/agents/chat/chat.py | 273 ++++++++++++++++- src/mobilerun_sdk/types/agents/__init__.py | 5 + .../types/agents/chat_send_message_params.py | 13 + .../agents/chat_send_message_response.py | 15 + .../types/agents/chat_send_prompt_params.py | 41 +++ .../types/agents/chat_send_prompt_response.py | 7 + .../agents/chat_subscribe_events_response.py | 7 + tests/api_resources/agents/test_chat.py | 285 ++++++++++++++++++ 10 files changed, 653 insertions(+), 5 deletions(-) create mode 100644 src/mobilerun_sdk/types/agents/chat_send_message_params.py create mode 100644 src/mobilerun_sdk/types/agents/chat_send_message_response.py create mode 100644 src/mobilerun_sdk/types/agents/chat_send_prompt_params.py create mode 100644 src/mobilerun_sdk/types/agents/chat_send_prompt_response.py create mode 100644 src/mobilerun_sdk/types/agents/chat_subscribe_events_response.py diff --git a/.stats.yml b/.stats.yml index d6b16f9..b0669d9 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 163 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-74bcd5b17c204f3ed69b241a2077b638fff3357fcff267c7e07b1a7aec85acb2.yml +configured_endpoints: 166 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-ebfd74bffdfad2397a31dad7ca8447317454ab771762a245bf02a3f5559c69a7.yml openapi_spec_hash: 29b62d198d5699a230afd5397359cecb -config_hash: 24cb7c22ef5bfbe580e8b3cd6738c2a6 +config_hash: 0db69001ab026b2a4733e3adb0366b8d diff --git a/api.md b/api.md index f9cf5eb..f1a2d2c 100644 --- a/api.md +++ b/api.md @@ -36,6 +36,9 @@ from mobilerun_sdk.types.agents import ( ChatGetChatStateResponse, ChatListSlashCommandsResponse, ChatRehydrateChatResponse, + ChatSendMessageResponse, + ChatSendPromptResponse, + ChatSubscribeEventsResponse, ) ``` @@ -45,6 +48,9 @@ Methods: - client.agents.chat.get_chat_state() -> ChatGetChatStateResponse - client.agents.chat.list_slash_commands() -> ChatListSlashCommandsResponse - client.agents.chat.rehydrate_chat() -> ChatRehydrateChatResponse +- client.agents.chat.send_message(\*\*params) -> ChatSendMessageResponse +- client.agents.chat.send_prompt(\*\*params) -> str +- client.agents.chat.subscribe_events() -> str ### Abort diff --git a/src/mobilerun_sdk/resources/agents/chat/chat.py b/src/mobilerun_sdk/resources/agents/chat/chat.py index ed91b94..c4a7968 100644 --- a/src/mobilerun_sdk/resources/agents/chat/chat.py +++ b/src/mobilerun_sdk/resources/agents/chat/chat.py @@ -2,6 +2,7 @@ from __future__ import annotations +from typing import Dict, Iterable, Optional from typing_extensions import Literal import httpx @@ -22,7 +23,7 @@ QuestionResourceWithStreamingResponse, AsyncQuestionResourceWithStreamingResponse, ) -from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given from ...._utils import maybe_transform, async_maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource @@ -32,10 +33,14 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) +from ...._streaming import Stream, AsyncStream from ...._base_client import make_request_options -from ....types.agents import chat_deliver_permission_params +from ....types.agents import chat_send_prompt_params, chat_send_message_params, chat_deliver_permission_params +from ....types.agents.chat_send_prompt_response import ChatSendPromptResponse +from ....types.agents.chat_send_message_response import ChatSendMessageResponse from ....types.agents.chat_get_chat_state_response import ChatGetChatStateResponse from ....types.agents.chat_rehydrate_chat_response import ChatRehydrateChatResponse +from ....types.agents.chat_subscribe_events_response import ChatSubscribeEventsResponse from ....types.agents.chat_deliver_permission_response import ChatDeliverPermissionResponse from ....types.agents.chat_list_slash_commands_response import ChatListSlashCommandsResponse @@ -171,6 +176,120 @@ def rehydrate_chat( cast_to=ChatRehydrateChatResponse, ) + def send_message( + self, + *, + message: str, + agent: 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, + ) -> ChatSendMessageResponse: + """Send a single user message (direct API). + + Content-negotiated: SSE or JSON. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/agents/chat/message", + body=maybe_transform( + { + "message": message, + "agent": agent, + }, + chat_send_message_params.ChatSendMessageParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ChatSendMessageResponse, + ) + + def send_prompt( + self, + *, + messages: Iterable[chat_send_prompt_params.Message], + id: str | Omit = omit, + agent: str | Omit = omit, + context: str | Omit = omit, + file_ids: SequenceNotStr[str] | Omit = omit, + metadata: Dict[str, Optional[object]] | Omit = omit, + trigger: Literal["submit-message", "regenerate-message"] | 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, + ) -> Stream[ChatSendPromptResponse]: + """ + Send a chat prompt; streams agent events. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"Accept": "text/event-stream", **(extra_headers or {})} + return self._post( + "/agents/chat/prompt", + body=maybe_transform( + { + "messages": messages, + "id": id, + "agent": agent, + "context": context, + "file_ids": file_ids, + "metadata": metadata, + "trigger": trigger, + }, + chat_send_prompt_params.ChatSendPromptParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=str, + stream=True, + stream_cls=Stream[ChatSendPromptResponse], + ) + + def subscribe_events( + self, + *, + # 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, + ) -> Stream[ChatSubscribeEventsResponse]: + """SSE channel for chat-change notifications.""" + extra_headers = {"Accept": "text/event-stream", **(extra_headers or {})} + return self._get( + "/agents/chat/events", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=str, + stream=True, + stream_cls=Stream[ChatSubscribeEventsResponse], + ) + class AsyncChatResource(AsyncAPIResource): @cached_property @@ -301,6 +420,120 @@ async def rehydrate_chat( cast_to=ChatRehydrateChatResponse, ) + async def send_message( + self, + *, + message: str, + agent: 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, + ) -> ChatSendMessageResponse: + """Send a single user message (direct API). + + Content-negotiated: SSE or JSON. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/agents/chat/message", + body=await async_maybe_transform( + { + "message": message, + "agent": agent, + }, + chat_send_message_params.ChatSendMessageParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ChatSendMessageResponse, + ) + + async def send_prompt( + self, + *, + messages: Iterable[chat_send_prompt_params.Message], + id: str | Omit = omit, + agent: str | Omit = omit, + context: str | Omit = omit, + file_ids: SequenceNotStr[str] | Omit = omit, + metadata: Dict[str, Optional[object]] | Omit = omit, + trigger: Literal["submit-message", "regenerate-message"] | 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, + ) -> AsyncStream[ChatSendPromptResponse]: + """ + Send a chat prompt; streams agent events. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"Accept": "text/event-stream", **(extra_headers or {})} + return await self._post( + "/agents/chat/prompt", + body=await async_maybe_transform( + { + "messages": messages, + "id": id, + "agent": agent, + "context": context, + "file_ids": file_ids, + "metadata": metadata, + "trigger": trigger, + }, + chat_send_prompt_params.ChatSendPromptParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=str, + stream=True, + stream_cls=AsyncStream[ChatSendPromptResponse], + ) + + async def subscribe_events( + self, + *, + # 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, + ) -> AsyncStream[ChatSubscribeEventsResponse]: + """SSE channel for chat-change notifications.""" + extra_headers = {"Accept": "text/event-stream", **(extra_headers or {})} + return await self._get( + "/agents/chat/events", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=str, + stream=True, + stream_cls=AsyncStream[ChatSubscribeEventsResponse], + ) + class ChatResourceWithRawResponse: def __init__(self, chat: ChatResource) -> None: @@ -318,6 +551,15 @@ def __init__(self, chat: ChatResource) -> None: self.rehydrate_chat = to_raw_response_wrapper( chat.rehydrate_chat, ) + self.send_message = to_raw_response_wrapper( + chat.send_message, + ) + self.send_prompt = to_raw_response_wrapper( + chat.send_prompt, + ) + self.subscribe_events = to_raw_response_wrapper( + chat.subscribe_events, + ) @cached_property def abort(self) -> AbortResourceWithRawResponse: @@ -344,6 +586,15 @@ def __init__(self, chat: AsyncChatResource) -> None: self.rehydrate_chat = async_to_raw_response_wrapper( chat.rehydrate_chat, ) + self.send_message = async_to_raw_response_wrapper( + chat.send_message, + ) + self.send_prompt = async_to_raw_response_wrapper( + chat.send_prompt, + ) + self.subscribe_events = async_to_raw_response_wrapper( + chat.subscribe_events, + ) @cached_property def abort(self) -> AsyncAbortResourceWithRawResponse: @@ -370,6 +621,15 @@ def __init__(self, chat: ChatResource) -> None: self.rehydrate_chat = to_streamed_response_wrapper( chat.rehydrate_chat, ) + self.send_message = to_streamed_response_wrapper( + chat.send_message, + ) + self.send_prompt = to_streamed_response_wrapper( + chat.send_prompt, + ) + self.subscribe_events = to_streamed_response_wrapper( + chat.subscribe_events, + ) @cached_property def abort(self) -> AbortResourceWithStreamingResponse: @@ -396,6 +656,15 @@ def __init__(self, chat: AsyncChatResource) -> None: self.rehydrate_chat = async_to_streamed_response_wrapper( chat.rehydrate_chat, ) + self.send_message = async_to_streamed_response_wrapper( + chat.send_message, + ) + self.send_prompt = async_to_streamed_response_wrapper( + chat.send_prompt, + ) + self.subscribe_events = async_to_streamed_response_wrapper( + chat.subscribe_events, + ) @cached_property def abort(self) -> AsyncAbortResourceWithStreamingResponse: diff --git a/src/mobilerun_sdk/types/agents/__init__.py b/src/mobilerun_sdk/types/agents/__init__.py index 1634fda..b04d567 100644 --- a/src/mobilerun_sdk/types/agents/__init__.py +++ b/src/mobilerun_sdk/types/agents/__init__.py @@ -3,12 +3,17 @@ from __future__ import annotations from .file_list_files_params import FileListFilesParams as FileListFilesParams +from .chat_send_prompt_params import ChatSendPromptParams as ChatSendPromptParams +from .chat_send_message_params import ChatSendMessageParams as ChatSendMessageParams from .file_list_files_response import FileListFilesResponse as FileListFilesResponse +from .chat_send_prompt_response import ChatSendPromptResponse as ChatSendPromptResponse +from .chat_send_message_response import ChatSendMessageResponse as ChatSendMessageResponse from .file_mint_upload_url_params import FileMintUploadURLParams as FileMintUploadURLParams from .chat_get_chat_state_response import ChatGetChatStateResponse as ChatGetChatStateResponse from .chat_rehydrate_chat_response import ChatRehydrateChatResponse as ChatRehydrateChatResponse from .file_mint_upload_url_response import FileMintUploadURLResponse as FileMintUploadURLResponse from .chat_deliver_permission_params import ChatDeliverPermissionParams as ChatDeliverPermissionParams +from .chat_subscribe_events_response import ChatSubscribeEventsResponse as ChatSubscribeEventsResponse from .telegram_receive_update_params import TelegramReceiveUpdateParams as TelegramReceiveUpdateParams from .chat_deliver_permission_response import ChatDeliverPermissionResponse as ChatDeliverPermissionResponse from .chat_list_slash_commands_response import ChatListSlashCommandsResponse as ChatListSlashCommandsResponse diff --git a/src/mobilerun_sdk/types/agents/chat_send_message_params.py b/src/mobilerun_sdk/types/agents/chat_send_message_params.py new file mode 100644 index 0000000..e39c7dd --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat_send_message_params.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["ChatSendMessageParams"] + + +class ChatSendMessageParams(TypedDict, total=False): + message: Required[str] + + agent: str diff --git a/src/mobilerun_sdk/types/agents/chat_send_message_response.py b/src/mobilerun_sdk/types/agents/chat_send_message_response.py new file mode 100644 index 0000000..3ad7cb8 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat_send_message_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["ChatSendMessageResponse"] + + +class ChatSendMessageResponse(BaseModel): + assistant_text: str = FieldInfo(alias="assistantText") + + error_text: Optional[str] = FieldInfo(alias="errorText", default=None) diff --git a/src/mobilerun_sdk/types/agents/chat_send_prompt_params.py b/src/mobilerun_sdk/types/agents/chat_send_prompt_params.py new file mode 100644 index 0000000..69f5188 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat_send_prompt_params.py @@ -0,0 +1,41 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Iterable, Optional +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ..._types import SequenceNotStr +from ..._utils import PropertyInfo + +__all__ = ["ChatSendPromptParams", "Message", "MessagePart"] + + +class ChatSendPromptParams(TypedDict, total=False): + messages: Required[Iterable[Message]] + + id: str + + agent: str + + context: str + + file_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="fileIds")] + + metadata: Dict[str, Optional[object]] + + trigger: Literal["submit-message", "regenerate-message"] + + +class MessagePart(TypedDict, total=False, extra_items=Optional[object]): # type: ignore[call-arg] + type: Required[str] + + +class Message(TypedDict, total=False): + id: Required[str] + + parts: Required[Iterable[MessagePart]] + + role: Required[Literal["user", "assistant", "system"]] + + metadata: Dict[str, Optional[object]] diff --git a/src/mobilerun_sdk/types/agents/chat_send_prompt_response.py b/src/mobilerun_sdk/types/agents/chat_send_prompt_response.py new file mode 100644 index 0000000..d081551 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat_send_prompt_response.py @@ -0,0 +1,7 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import TypeAlias + +__all__ = ["ChatSendPromptResponse"] + +ChatSendPromptResponse: TypeAlias = str diff --git a/src/mobilerun_sdk/types/agents/chat_subscribe_events_response.py b/src/mobilerun_sdk/types/agents/chat_subscribe_events_response.py new file mode 100644 index 0000000..0d74016 --- /dev/null +++ b/src/mobilerun_sdk/types/agents/chat_subscribe_events_response.py @@ -0,0 +1,7 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import TypeAlias + +__all__ = ["ChatSubscribeEventsResponse"] + +ChatSubscribeEventsResponse: TypeAlias = str diff --git a/tests/api_resources/agents/test_chat.py b/tests/api_resources/agents/test_chat.py index a5525f6..14da7a0 100644 --- a/tests/api_resources/agents/test_chat.py +++ b/tests/api_resources/agents/test_chat.py @@ -10,6 +10,7 @@ from tests.utils import assert_matches_type from mobilerun_sdk import Mobilerun, AsyncMobilerun from mobilerun_sdk.types.agents import ( + ChatSendMessageResponse, ChatGetChatStateResponse, ChatRehydrateChatResponse, ChatDeliverPermissionResponse, @@ -143,6 +144,148 @@ def test_streaming_response_rehydrate_chat(self, client: Mobilerun) -> None: assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_send_message(self, client: Mobilerun) -> None: + chat = client.agents.chat.send_message( + message="x", + ) + assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_send_message_with_all_params(self, client: Mobilerun) -> None: + chat = client.agents.chat.send_message( + message="x", + agent="agent", + ) + assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_send_message(self, client: Mobilerun) -> None: + response = client.agents.chat.with_raw_response.send_message( + message="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + chat = response.parse() + assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_send_message(self, client: Mobilerun) -> None: + with client.agents.chat.with_streaming_response.send_message( + message="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + chat = response.parse() + assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_send_prompt(self, client: Mobilerun) -> None: + chat_stream = client.agents.chat.send_prompt( + messages=[ + { + "id": "id", + "parts": [{"type": "type"}], + "role": "user", + } + ], + ) + chat_stream.response.close() + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_send_prompt_with_all_params(self, client: Mobilerun) -> None: + chat_stream = client.agents.chat.send_prompt( + messages=[ + { + "id": "id", + "parts": [{"type": "type"}], + "role": "user", + "metadata": {"foo": "bar"}, + } + ], + id="id", + agent="agent", + context="x", + file_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + metadata={"foo": "bar"}, + trigger="submit-message", + ) + chat_stream.response.close() + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_send_prompt(self, client: Mobilerun) -> None: + response = client.agents.chat.with_raw_response.send_prompt( + messages=[ + { + "id": "id", + "parts": [{"type": "type"}], + "role": "user", + } + ], + ) + + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + stream = response.parse() + stream.close() + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_send_prompt(self, client: Mobilerun) -> None: + with client.agents.chat.with_streaming_response.send_prompt( + messages=[ + { + "id": "id", + "parts": [{"type": "type"}], + "role": "user", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + stream = response.parse() + stream.close() + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_subscribe_events(self, client: Mobilerun) -> None: + chat_stream = client.agents.chat.subscribe_events() + chat_stream.response.close() + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_subscribe_events(self, client: Mobilerun) -> None: + response = client.agents.chat.with_raw_response.subscribe_events() + + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + stream = response.parse() + stream.close() + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_subscribe_events(self, client: Mobilerun) -> None: + with client.agents.chat.with_streaming_response.subscribe_events() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + stream = response.parse() + stream.close() + + assert cast(Any, response.is_closed) is True + class TestAsyncChat: parametrize = pytest.mark.parametrize( @@ -269,3 +412,145 @@ async def test_streaming_response_rehydrate_chat(self, async_client: AsyncMobile assert_matches_type(ChatRehydrateChatResponse, chat, path=["response"]) assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_send_message(self, async_client: AsyncMobilerun) -> None: + chat = await async_client.agents.chat.send_message( + message="x", + ) + assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_send_message_with_all_params(self, async_client: AsyncMobilerun) -> None: + chat = await async_client.agents.chat.send_message( + message="x", + agent="agent", + ) + assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_send_message(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.chat.with_raw_response.send_message( + message="x", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + chat = await response.parse() + assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_send_message(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.chat.with_streaming_response.send_message( + message="x", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + chat = await response.parse() + assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_send_prompt(self, async_client: AsyncMobilerun) -> None: + chat_stream = await async_client.agents.chat.send_prompt( + messages=[ + { + "id": "id", + "parts": [{"type": "type"}], + "role": "user", + } + ], + ) + await chat_stream.response.aclose() + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_send_prompt_with_all_params(self, async_client: AsyncMobilerun) -> None: + chat_stream = await async_client.agents.chat.send_prompt( + messages=[ + { + "id": "id", + "parts": [{"type": "type"}], + "role": "user", + "metadata": {"foo": "bar"}, + } + ], + id="id", + agent="agent", + context="x", + file_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + metadata={"foo": "bar"}, + trigger="submit-message", + ) + await chat_stream.response.aclose() + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_send_prompt(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.chat.with_raw_response.send_prompt( + messages=[ + { + "id": "id", + "parts": [{"type": "type"}], + "role": "user", + } + ], + ) + + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + stream = await response.parse() + await stream.close() + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_send_prompt(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.chat.with_streaming_response.send_prompt( + messages=[ + { + "id": "id", + "parts": [{"type": "type"}], + "role": "user", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + stream = await response.parse() + await stream.close() + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_subscribe_events(self, async_client: AsyncMobilerun) -> None: + chat_stream = await async_client.agents.chat.subscribe_events() + await chat_stream.response.aclose() + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_subscribe_events(self, async_client: AsyncMobilerun) -> None: + response = await async_client.agents.chat.with_raw_response.subscribe_events() + + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + stream = await response.parse() + await stream.close() + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_subscribe_events(self, async_client: AsyncMobilerun) -> None: + async with async_client.agents.chat.with_streaming_response.subscribe_events() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + stream = await response.parse() + await stream.close() + + assert cast(Any, response.is_closed) is True From f41d4d38786586b15ea97e741c33ec84214d6311 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 08:37:15 +0000 Subject: [PATCH 16/21] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index b0669d9..e7ee6c2 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 166 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-ebfd74bffdfad2397a31dad7ca8447317454ab771762a245bf02a3f5559c69a7.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-a9516ab2644d6614122b1e640a116fd5cdf0a99d0baf37543c544c43cdaf9f65.yml openapi_spec_hash: 29b62d198d5699a230afd5397359cecb -config_hash: 0db69001ab026b2a4733e3adb0366b8d +config_hash: e8c818057d67522c0c74e8234b76ae22 From f4a686769e877aef8cb6c28d97572b9775aa2bf4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 08:40:25 +0000 Subject: [PATCH 17/21] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index e7ee6c2..e5fabb9 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 166 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-a9516ab2644d6614122b1e640a116fd5cdf0a99d0baf37543c544c43cdaf9f65.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-2661ca791a782db1e0613e2eb45b61606e71014347847213b59e07a15d91ba86.yml openapi_spec_hash: 29b62d198d5699a230afd5397359cecb -config_hash: e8c818057d67522c0c74e8234b76ae22 +config_hash: f12cf7f74ee2471206a08e6601444d6e From 16e622e471e8043c80c30f9904eb74bd168f1b00 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 09:03:43 +0000 Subject: [PATCH 18/21] feat(api): manual updates --- .stats.yml | 6 +- README.md | 17 +- api.md | 66 +-- src/mobilerun_sdk/_client.py | 6 - .../resources/agents/__init__.py | 14 - src/mobilerun_sdk/resources/agents/agents.py | 101 ---- .../resources/agents/chat/chat.py | 273 +---------- .../resources/agents/telegram/__init__.py | 33 -- .../resources/agents/telegram/bots.py | 282 ------------ .../resources/agents/telegram/telegram.py | 222 --------- .../resources/devices/devices.py | 16 +- .../resources/devices/{esim => }/esim.py | 241 +--------- .../resources/devices/esim/__init__.py | 33 -- .../resources/devices/esim/apn.py | 429 ----------------- src/mobilerun_sdk/types/__init__.py | 1 - .../types/agent_list_response.py | 33 -- src/mobilerun_sdk/types/agents/__init__.py | 6 - .../types/agents/chat_send_message_params.py | 13 - .../agents/chat_send_message_response.py | 15 - .../types/agents/chat_send_prompt_params.py | 41 -- .../types/agents/chat_send_prompt_response.py | 7 - .../agents/chat_subscribe_events_response.py | 7 - .../types/agents/telegram/__init__.py | 7 - .../agents/telegram/bot_list_response.py | 31 -- .../telegram/bot_request_link_response.py | 15 - .../telegram/bot_revoke_link_response.py | 11 - .../agents/telegram_receive_update_params.py | 49 -- src/mobilerun_sdk/types/devices/__init__.py | 2 - .../types/devices/esim/__init__.py | 7 - .../types/devices/esim/apn_create_params.py | 29 -- .../types/devices/esim/apn_list_response.py | 35 -- .../types/devices/esim/apn_select_params.py | 17 - .../types/devices/esim_set_roaming_params.py | 15 - .../types/devices/esim_status_response.py | 35 -- .../api_resources/agents/telegram/__init__.py | 1 - .../agents/telegram/test_bots.py | 220 --------- tests/api_resources/agents/test_chat.py | 285 ------------ tests/api_resources/agents/test_telegram.py | 136 ------ tests/api_resources/devices/esim/__init__.py | 1 - tests/api_resources/devices/esim/test_apn.py | 430 ------------------ tests/api_resources/devices/test_esim.py | 215 --------- tests/api_resources/test_agents.py | 80 ---- 42 files changed, 36 insertions(+), 3447 deletions(-) delete mode 100644 src/mobilerun_sdk/resources/agents/telegram/__init__.py delete mode 100644 src/mobilerun_sdk/resources/agents/telegram/bots.py delete mode 100644 src/mobilerun_sdk/resources/agents/telegram/telegram.py rename src/mobilerun_sdk/resources/devices/{esim => }/esim.py (67%) delete mode 100644 src/mobilerun_sdk/resources/devices/esim/__init__.py delete mode 100644 src/mobilerun_sdk/resources/devices/esim/apn.py delete mode 100644 src/mobilerun_sdk/types/agent_list_response.py delete mode 100644 src/mobilerun_sdk/types/agents/chat_send_message_params.py delete mode 100644 src/mobilerun_sdk/types/agents/chat_send_message_response.py delete mode 100644 src/mobilerun_sdk/types/agents/chat_send_prompt_params.py delete mode 100644 src/mobilerun_sdk/types/agents/chat_send_prompt_response.py delete mode 100644 src/mobilerun_sdk/types/agents/chat_subscribe_events_response.py delete mode 100644 src/mobilerun_sdk/types/agents/telegram/__init__.py delete mode 100644 src/mobilerun_sdk/types/agents/telegram/bot_list_response.py delete mode 100644 src/mobilerun_sdk/types/agents/telegram/bot_request_link_response.py delete mode 100644 src/mobilerun_sdk/types/agents/telegram/bot_revoke_link_response.py delete mode 100644 src/mobilerun_sdk/types/agents/telegram_receive_update_params.py delete mode 100644 src/mobilerun_sdk/types/devices/esim/__init__.py delete mode 100644 src/mobilerun_sdk/types/devices/esim/apn_create_params.py delete mode 100644 src/mobilerun_sdk/types/devices/esim/apn_list_response.py delete mode 100644 src/mobilerun_sdk/types/devices/esim/apn_select_params.py delete mode 100644 src/mobilerun_sdk/types/devices/esim_set_roaming_params.py delete mode 100644 src/mobilerun_sdk/types/devices/esim_status_response.py delete mode 100644 tests/api_resources/agents/telegram/__init__.py delete mode 100644 tests/api_resources/agents/telegram/test_bots.py delete mode 100644 tests/api_resources/agents/test_telegram.py delete mode 100644 tests/api_resources/devices/esim/__init__.py delete mode 100644 tests/api_resources/devices/esim/test_apn.py delete mode 100644 tests/api_resources/test_agents.py diff --git a/.stats.yml b/.stats.yml index e5fabb9..46ffba2 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 166 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-2661ca791a782db1e0613e2eb45b61606e71014347847213b59e07a15d91ba86.yml +configured_endpoints: 153 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-08d5ad550dedf6fec547fd6b259a1b04ab6876041c9e3ad31603b4eb50234181.yml openapi_spec_hash: 29b62d198d5699a230afd5397359cecb -config_hash: f12cf7f74ee2471206a08e6601444d6e +config_hash: 5fba7bd3d1df1eac603dcfee428f8d1c diff --git a/README.md b/README.md index 7ca1fa3..73b8b1d 100644 --- a/README.md +++ b/README.md @@ -124,16 +124,17 @@ from mobilerun_sdk import Mobilerun client = Mobilerun() -client.agents.telegram.receive_update( - update_id=0, - message={ - "chat": { - "id": 0, - "type": "type", - }, - "message_id": 0, +device = client.devices.create( + carrier={ + "gsm_operator_alpha": "GsmOperatorAlpha", + "gsm_operator_numeric": 0, + "gsm_sim_operator_alpha": "GsmSimOperatorAlpha", + "gsm_sim_operator_iso_country": "GsmSimOperatorIsoCountry", + "gsm_sim_operator_numeric": 0, + "persist_sys_timezone": "PersistSysTimezone", }, ) +print(device.carrier) ``` ## File uploads diff --git a/api.md b/api.md index f1a2d2c..6bae274 100644 --- a/api.md +++ b/api.md @@ -16,16 +16,6 @@ from mobilerun_sdk.types import ( # Agents -Types: - -```python -from mobilerun_sdk.types import AgentListResponse -``` - -Methods: - -- client.agents.list() -> AgentListResponse - ## Chat Types: @@ -36,9 +26,6 @@ from mobilerun_sdk.types.agents import ( ChatGetChatStateResponse, ChatListSlashCommandsResponse, ChatRehydrateChatResponse, - ChatSendMessageResponse, - ChatSendPromptResponse, - ChatSubscribeEventsResponse, ) ``` @@ -48,9 +35,6 @@ Methods: - client.agents.chat.get_chat_state() -> ChatGetChatStateResponse - client.agents.chat.list_slash_commands() -> ChatListSlashCommandsResponse - client.agents.chat.rehydrate_chat() -> ChatRehydrateChatResponse -- client.agents.chat.send_message(\*\*params) -> ChatSendMessageResponse -- client.agents.chat.send_prompt(\*\*params) -> str -- client.agents.chat.subscribe_events() -> str ### Abort @@ -112,30 +96,6 @@ Methods: - client.agents.files.file_id.download_file() -> None - client.agents.files.file_id.update_metadata(\*\*params) -> FileIDUpdateMetadataResponse -## Telegram - -Methods: - -- client.agents.telegram.receive_update(\*\*params) -> None - -### Bots - -Types: - -```python -from mobilerun_sdk.types.agents.telegram import ( - BotListResponse, - BotRequestLinkResponse, - BotRevokeLinkResponse, -) -``` - -Methods: - -- client.agents.telegram.bots.list() -> BotListResponse -- client.agents.telegram.bots.request_link() -> BotRequestLinkResponse -- client.agents.telegram.bots.revoke_link(id) -> BotRevokeLinkResponse - # Apps Types: @@ -311,31 +271,15 @@ Methods: Types: ```python -from mobilerun_sdk.types.devices import EsimListResponse, EsimActivateResponse, EsimStatusResponse -``` - -Methods: - -- client.devices.esim.list(device_id) -> Optional[EsimListResponse] -- client.devices.esim.activate(device_id, \*\*params) -> EsimActivateResponse -- client.devices.esim.enable(device_id, \*\*params) -> None -- client.devices.esim.remove(device_id, \*\*params) -> None -- client.devices.esim.set_roaming(device_id, \*\*params) -> None -- client.devices.esim.status(device_id) -> Optional[EsimStatusResponse] - -### Apn - -Types: - -```python -from mobilerun_sdk.types.devices.esim import ApnListResponse +from mobilerun_sdk.types.devices import EsimListResponse, EsimActivateResponse ``` Methods: -- client.devices.esim.apn.create(device_id, \*\*params) -> None -- client.devices.esim.apn.list(device_id) -> Optional[ApnListResponse] -- client.devices.esim.apn.select(device_id, \*\*params) -> None +- client.devices.esim.list(device_id) -> Optional[EsimListResponse] +- client.devices.esim.activate(device_id, \*\*params) -> EsimActivateResponse +- client.devices.esim.enable(device_id, \*\*params) -> None +- client.devices.esim.remove(device_id, \*\*params) -> None ## Files diff --git a/src/mobilerun_sdk/_client.py b/src/mobilerun_sdk/_client.py index e43e45a..569a208 100644 --- a/src/mobilerun_sdk/_client.py +++ b/src/mobilerun_sdk/_client.py @@ -135,7 +135,6 @@ def __init__( @cached_property def agents(self) -> AgentsResource: - """Agents API""" from .resources.agents import AgentsResource return AgentsResource(self) @@ -392,7 +391,6 @@ def __init__( @cached_property def agents(self) -> AsyncAgentsResource: - """Agents API""" from .resources.agents import AsyncAgentsResource return AsyncAgentsResource(self) @@ -595,7 +593,6 @@ def __init__(self, client: Mobilerun) -> None: @cached_property def agents(self) -> agents.AgentsResourceWithRawResponse: - """Agents API""" from .resources.agents import AgentsResourceWithRawResponse return AgentsResourceWithRawResponse(self._client.agents) @@ -675,7 +672,6 @@ def __init__(self, client: AsyncMobilerun) -> None: @cached_property def agents(self) -> agents.AsyncAgentsResourceWithRawResponse: - """Agents API""" from .resources.agents import AsyncAgentsResourceWithRawResponse return AsyncAgentsResourceWithRawResponse(self._client.agents) @@ -755,7 +751,6 @@ def __init__(self, client: Mobilerun) -> None: @cached_property def agents(self) -> agents.AgentsResourceWithStreamingResponse: - """Agents API""" from .resources.agents import AgentsResourceWithStreamingResponse return AgentsResourceWithStreamingResponse(self._client.agents) @@ -835,7 +830,6 @@ def __init__(self, client: AsyncMobilerun) -> None: @cached_property def agents(self) -> agents.AsyncAgentsResourceWithStreamingResponse: - """Agents API""" from .resources.agents import AsyncAgentsResourceWithStreamingResponse return AsyncAgentsResourceWithStreamingResponse(self._client.agents) diff --git a/src/mobilerun_sdk/resources/agents/__init__.py b/src/mobilerun_sdk/resources/agents/__init__.py index 1ac6c3b..8cd1035 100644 --- a/src/mobilerun_sdk/resources/agents/__init__.py +++ b/src/mobilerun_sdk/resources/agents/__init__.py @@ -24,14 +24,6 @@ AgentsResourceWithStreamingResponse, AsyncAgentsResourceWithStreamingResponse, ) -from .telegram import ( - TelegramResource, - AsyncTelegramResource, - TelegramResourceWithRawResponse, - AsyncTelegramResourceWithRawResponse, - TelegramResourceWithStreamingResponse, - AsyncTelegramResourceWithStreamingResponse, -) __all__ = [ "ChatResource", @@ -46,12 +38,6 @@ "AsyncFilesResourceWithRawResponse", "FilesResourceWithStreamingResponse", "AsyncFilesResourceWithStreamingResponse", - "TelegramResource", - "AsyncTelegramResource", - "TelegramResourceWithRawResponse", - "AsyncTelegramResourceWithRawResponse", - "TelegramResourceWithStreamingResponse", - "AsyncTelegramResourceWithStreamingResponse", "AgentsResource", "AsyncAgentsResource", "AgentsResourceWithRawResponse", diff --git a/src/mobilerun_sdk/resources/agents/agents.py b/src/mobilerun_sdk/resources/agents/agents.py index c6d5492..1d6053a 100644 --- a/src/mobilerun_sdk/resources/agents/agents.py +++ b/src/mobilerun_sdk/resources/agents/agents.py @@ -2,9 +2,6 @@ from __future__ import annotations -import httpx - -from ..._types import Body, Query, Headers, NotGiven, not_given from ..._compat import cached_property from .chat.chat import ( ChatResource, @@ -15,12 +12,6 @@ AsyncChatResourceWithStreamingResponse, ) from ..._resource import SyncAPIResource, AsyncAPIResource -from ..._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) from .files.files import ( FilesResource, AsyncFilesResource, @@ -29,23 +20,11 @@ FilesResourceWithStreamingResponse, AsyncFilesResourceWithStreamingResponse, ) -from ..._base_client import make_request_options -from .telegram.telegram import ( - TelegramResource, - AsyncTelegramResource, - TelegramResourceWithRawResponse, - AsyncTelegramResourceWithRawResponse, - TelegramResourceWithStreamingResponse, - AsyncTelegramResourceWithStreamingResponse, -) -from ...types.agent_list_response import AgentListResponse __all__ = ["AgentsResource", "AsyncAgentsResource"] class AgentsResource(SyncAPIResource): - """Agents API""" - @cached_property def chat(self) -> ChatResource: return ChatResource(self._client) @@ -54,10 +33,6 @@ def chat(self) -> ChatResource: def files(self) -> FilesResource: return FilesResource(self._client) - @cached_property - def telegram(self) -> TelegramResource: - return TelegramResource(self._client) - @cached_property def with_raw_response(self) -> AgentsResourceWithRawResponse: """ @@ -77,29 +52,8 @@ def with_streaming_response(self) -> AgentsResourceWithStreamingResponse: """ return AgentsResourceWithStreamingResponse(self) - def list( - self, - *, - # 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, - ) -> AgentListResponse: - """List all available agents with their default configurations.""" - return self._get( - "/agents", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=AgentListResponse, - ) - class AsyncAgentsResource(AsyncAPIResource): - """Agents API""" - @cached_property def chat(self) -> AsyncChatResource: return AsyncChatResource(self._client) @@ -108,10 +62,6 @@ def chat(self) -> AsyncChatResource: def files(self) -> AsyncFilesResource: return AsyncFilesResource(self._client) - @cached_property - def telegram(self) -> AsyncTelegramResource: - return AsyncTelegramResource(self._client) - @cached_property def with_raw_response(self) -> AsyncAgentsResourceWithRawResponse: """ @@ -131,34 +81,11 @@ def with_streaming_response(self) -> AsyncAgentsResourceWithStreamingResponse: """ return AsyncAgentsResourceWithStreamingResponse(self) - async def list( - self, - *, - # 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, - ) -> AgentListResponse: - """List all available agents with their default configurations.""" - return await self._get( - "/agents", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=AgentListResponse, - ) - class AgentsResourceWithRawResponse: def __init__(self, agents: AgentsResource) -> None: self._agents = agents - self.list = to_raw_response_wrapper( - agents.list, - ) - @cached_property def chat(self) -> ChatResourceWithRawResponse: return ChatResourceWithRawResponse(self._agents.chat) @@ -167,19 +94,11 @@ def chat(self) -> ChatResourceWithRawResponse: def files(self) -> FilesResourceWithRawResponse: return FilesResourceWithRawResponse(self._agents.files) - @cached_property - def telegram(self) -> TelegramResourceWithRawResponse: - return TelegramResourceWithRawResponse(self._agents.telegram) - class AsyncAgentsResourceWithRawResponse: def __init__(self, agents: AsyncAgentsResource) -> None: self._agents = agents - self.list = async_to_raw_response_wrapper( - agents.list, - ) - @cached_property def chat(self) -> AsyncChatResourceWithRawResponse: return AsyncChatResourceWithRawResponse(self._agents.chat) @@ -188,19 +107,11 @@ def chat(self) -> AsyncChatResourceWithRawResponse: def files(self) -> AsyncFilesResourceWithRawResponse: return AsyncFilesResourceWithRawResponse(self._agents.files) - @cached_property - def telegram(self) -> AsyncTelegramResourceWithRawResponse: - return AsyncTelegramResourceWithRawResponse(self._agents.telegram) - class AgentsResourceWithStreamingResponse: def __init__(self, agents: AgentsResource) -> None: self._agents = agents - self.list = to_streamed_response_wrapper( - agents.list, - ) - @cached_property def chat(self) -> ChatResourceWithStreamingResponse: return ChatResourceWithStreamingResponse(self._agents.chat) @@ -209,19 +120,11 @@ def chat(self) -> ChatResourceWithStreamingResponse: def files(self) -> FilesResourceWithStreamingResponse: return FilesResourceWithStreamingResponse(self._agents.files) - @cached_property - def telegram(self) -> TelegramResourceWithStreamingResponse: - return TelegramResourceWithStreamingResponse(self._agents.telegram) - class AsyncAgentsResourceWithStreamingResponse: def __init__(self, agents: AsyncAgentsResource) -> None: self._agents = agents - self.list = async_to_streamed_response_wrapper( - agents.list, - ) - @cached_property def chat(self) -> AsyncChatResourceWithStreamingResponse: return AsyncChatResourceWithStreamingResponse(self._agents.chat) @@ -229,7 +132,3 @@ def chat(self) -> AsyncChatResourceWithStreamingResponse: @cached_property def files(self) -> AsyncFilesResourceWithStreamingResponse: return AsyncFilesResourceWithStreamingResponse(self._agents.files) - - @cached_property - def telegram(self) -> AsyncTelegramResourceWithStreamingResponse: - return AsyncTelegramResourceWithStreamingResponse(self._agents.telegram) diff --git a/src/mobilerun_sdk/resources/agents/chat/chat.py b/src/mobilerun_sdk/resources/agents/chat/chat.py index c4a7968..ed91b94 100644 --- a/src/mobilerun_sdk/resources/agents/chat/chat.py +++ b/src/mobilerun_sdk/resources/agents/chat/chat.py @@ -2,7 +2,6 @@ from __future__ import annotations -from typing import Dict, Iterable, Optional from typing_extensions import Literal import httpx @@ -23,7 +22,7 @@ QuestionResourceWithStreamingResponse, AsyncQuestionResourceWithStreamingResponse, ) -from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given +from ...._types import Body, Query, Headers, NotGiven, not_given from ...._utils import maybe_transform, async_maybe_transform from ...._compat import cached_property from ...._resource import SyncAPIResource, AsyncAPIResource @@ -33,14 +32,10 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ...._streaming import Stream, AsyncStream from ...._base_client import make_request_options -from ....types.agents import chat_send_prompt_params, chat_send_message_params, chat_deliver_permission_params -from ....types.agents.chat_send_prompt_response import ChatSendPromptResponse -from ....types.agents.chat_send_message_response import ChatSendMessageResponse +from ....types.agents import chat_deliver_permission_params from ....types.agents.chat_get_chat_state_response import ChatGetChatStateResponse from ....types.agents.chat_rehydrate_chat_response import ChatRehydrateChatResponse -from ....types.agents.chat_subscribe_events_response import ChatSubscribeEventsResponse from ....types.agents.chat_deliver_permission_response import ChatDeliverPermissionResponse from ....types.agents.chat_list_slash_commands_response import ChatListSlashCommandsResponse @@ -176,120 +171,6 @@ def rehydrate_chat( cast_to=ChatRehydrateChatResponse, ) - def send_message( - self, - *, - message: str, - agent: 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, - ) -> ChatSendMessageResponse: - """Send a single user message (direct API). - - Content-negotiated: SSE or JSON. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._post( - "/agents/chat/message", - body=maybe_transform( - { - "message": message, - "agent": agent, - }, - chat_send_message_params.ChatSendMessageParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=ChatSendMessageResponse, - ) - - def send_prompt( - self, - *, - messages: Iterable[chat_send_prompt_params.Message], - id: str | Omit = omit, - agent: str | Omit = omit, - context: str | Omit = omit, - file_ids: SequenceNotStr[str] | Omit = omit, - metadata: Dict[str, Optional[object]] | Omit = omit, - trigger: Literal["submit-message", "regenerate-message"] | 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, - ) -> Stream[ChatSendPromptResponse]: - """ - Send a chat prompt; streams agent events. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - extra_headers = {"Accept": "text/event-stream", **(extra_headers or {})} - return self._post( - "/agents/chat/prompt", - body=maybe_transform( - { - "messages": messages, - "id": id, - "agent": agent, - "context": context, - "file_ids": file_ids, - "metadata": metadata, - "trigger": trigger, - }, - chat_send_prompt_params.ChatSendPromptParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=str, - stream=True, - stream_cls=Stream[ChatSendPromptResponse], - ) - - def subscribe_events( - self, - *, - # 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, - ) -> Stream[ChatSubscribeEventsResponse]: - """SSE channel for chat-change notifications.""" - extra_headers = {"Accept": "text/event-stream", **(extra_headers or {})} - return self._get( - "/agents/chat/events", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=str, - stream=True, - stream_cls=Stream[ChatSubscribeEventsResponse], - ) - class AsyncChatResource(AsyncAPIResource): @cached_property @@ -420,120 +301,6 @@ async def rehydrate_chat( cast_to=ChatRehydrateChatResponse, ) - async def send_message( - self, - *, - message: str, - agent: 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, - ) -> ChatSendMessageResponse: - """Send a single user message (direct API). - - Content-negotiated: SSE or JSON. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return await self._post( - "/agents/chat/message", - body=await async_maybe_transform( - { - "message": message, - "agent": agent, - }, - chat_send_message_params.ChatSendMessageParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=ChatSendMessageResponse, - ) - - async def send_prompt( - self, - *, - messages: Iterable[chat_send_prompt_params.Message], - id: str | Omit = omit, - agent: str | Omit = omit, - context: str | Omit = omit, - file_ids: SequenceNotStr[str] | Omit = omit, - metadata: Dict[str, Optional[object]] | Omit = omit, - trigger: Literal["submit-message", "regenerate-message"] | 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, - ) -> AsyncStream[ChatSendPromptResponse]: - """ - Send a chat prompt; streams agent events. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - extra_headers = {"Accept": "text/event-stream", **(extra_headers or {})} - return await self._post( - "/agents/chat/prompt", - body=await async_maybe_transform( - { - "messages": messages, - "id": id, - "agent": agent, - "context": context, - "file_ids": file_ids, - "metadata": metadata, - "trigger": trigger, - }, - chat_send_prompt_params.ChatSendPromptParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=str, - stream=True, - stream_cls=AsyncStream[ChatSendPromptResponse], - ) - - async def subscribe_events( - self, - *, - # 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, - ) -> AsyncStream[ChatSubscribeEventsResponse]: - """SSE channel for chat-change notifications.""" - extra_headers = {"Accept": "text/event-stream", **(extra_headers or {})} - return await self._get( - "/agents/chat/events", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=str, - stream=True, - stream_cls=AsyncStream[ChatSubscribeEventsResponse], - ) - class ChatResourceWithRawResponse: def __init__(self, chat: ChatResource) -> None: @@ -551,15 +318,6 @@ def __init__(self, chat: ChatResource) -> None: self.rehydrate_chat = to_raw_response_wrapper( chat.rehydrate_chat, ) - self.send_message = to_raw_response_wrapper( - chat.send_message, - ) - self.send_prompt = to_raw_response_wrapper( - chat.send_prompt, - ) - self.subscribe_events = to_raw_response_wrapper( - chat.subscribe_events, - ) @cached_property def abort(self) -> AbortResourceWithRawResponse: @@ -586,15 +344,6 @@ def __init__(self, chat: AsyncChatResource) -> None: self.rehydrate_chat = async_to_raw_response_wrapper( chat.rehydrate_chat, ) - self.send_message = async_to_raw_response_wrapper( - chat.send_message, - ) - self.send_prompt = async_to_raw_response_wrapper( - chat.send_prompt, - ) - self.subscribe_events = async_to_raw_response_wrapper( - chat.subscribe_events, - ) @cached_property def abort(self) -> AsyncAbortResourceWithRawResponse: @@ -621,15 +370,6 @@ def __init__(self, chat: ChatResource) -> None: self.rehydrate_chat = to_streamed_response_wrapper( chat.rehydrate_chat, ) - self.send_message = to_streamed_response_wrapper( - chat.send_message, - ) - self.send_prompt = to_streamed_response_wrapper( - chat.send_prompt, - ) - self.subscribe_events = to_streamed_response_wrapper( - chat.subscribe_events, - ) @cached_property def abort(self) -> AbortResourceWithStreamingResponse: @@ -656,15 +396,6 @@ def __init__(self, chat: AsyncChatResource) -> None: self.rehydrate_chat = async_to_streamed_response_wrapper( chat.rehydrate_chat, ) - self.send_message = async_to_streamed_response_wrapper( - chat.send_message, - ) - self.send_prompt = async_to_streamed_response_wrapper( - chat.send_prompt, - ) - self.subscribe_events = async_to_streamed_response_wrapper( - chat.subscribe_events, - ) @cached_property def abort(self) -> AsyncAbortResourceWithStreamingResponse: diff --git a/src/mobilerun_sdk/resources/agents/telegram/__init__.py b/src/mobilerun_sdk/resources/agents/telegram/__init__.py deleted file mode 100644 index 712a44e..0000000 --- a/src/mobilerun_sdk/resources/agents/telegram/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from .bots import ( - BotsResource, - AsyncBotsResource, - BotsResourceWithRawResponse, - AsyncBotsResourceWithRawResponse, - BotsResourceWithStreamingResponse, - AsyncBotsResourceWithStreamingResponse, -) -from .telegram import ( - TelegramResource, - AsyncTelegramResource, - TelegramResourceWithRawResponse, - AsyncTelegramResourceWithRawResponse, - TelegramResourceWithStreamingResponse, - AsyncTelegramResourceWithStreamingResponse, -) - -__all__ = [ - "BotsResource", - "AsyncBotsResource", - "BotsResourceWithRawResponse", - "AsyncBotsResourceWithRawResponse", - "BotsResourceWithStreamingResponse", - "AsyncBotsResourceWithStreamingResponse", - "TelegramResource", - "AsyncTelegramResource", - "TelegramResourceWithRawResponse", - "AsyncTelegramResourceWithRawResponse", - "TelegramResourceWithStreamingResponse", - "AsyncTelegramResourceWithStreamingResponse", -] diff --git a/src/mobilerun_sdk/resources/agents/telegram/bots.py b/src/mobilerun_sdk/resources/agents/telegram/bots.py deleted file mode 100644 index 473baa6..0000000 --- a/src/mobilerun_sdk/resources/agents/telegram/bots.py +++ /dev/null @@ -1,282 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import httpx - -from ...._types import Body, Query, Headers, NotGiven, not_given -from ...._utils import path_template -from ...._compat import cached_property -from ...._resource import SyncAPIResource, AsyncAPIResource -from ...._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ...._base_client import make_request_options -from ....types.agents.telegram.bot_list_response import BotListResponse -from ....types.agents.telegram.bot_revoke_link_response import BotRevokeLinkResponse -from ....types.agents.telegram.bot_request_link_response import BotRequestLinkResponse - -__all__ = ["BotsResource", "AsyncBotsResource"] - - -class BotsResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> BotsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return BotsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> BotsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return BotsResourceWithStreamingResponse(self) - - def list( - self, - *, - # 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, - ) -> BotListResponse: - """List the current user's Telegram link rows""" - return self._get( - "/agents/telegram/bots", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=BotListResponse, - ) - - def request_link( - self, - *, - # 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, - ) -> BotRequestLinkResponse: - """ - Issues a one-shot deeplink (`t.me/?start=`) for the - operator-owned shared bot. The user opens the link, taps `Start`, and the - webhook binds their Telegram account to this droidrun user. No bot token is - needed from the user — the operator owns the bot. - """ - return self._post( - "/agents/telegram/bots/connect", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=BotRequestLinkResponse, - ) - - def revoke_link( - self, - id: str, - *, - # 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, - ) -> BotRevokeLinkResponse: - """Disables the link. - - Future inbound messages from this Telegram account get the - welcome reply. The existing chat history is NOT wiped — start a fresh chat from - the UI if you suspect compromise. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not id: - raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - return self._post( - path_template("/agents/telegram/bots/{id}/revoke", id=id), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=BotRevokeLinkResponse, - ) - - -class AsyncBotsResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncBotsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return AsyncBotsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncBotsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return AsyncBotsResourceWithStreamingResponse(self) - - async def list( - self, - *, - # 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, - ) -> BotListResponse: - """List the current user's Telegram link rows""" - return await self._get( - "/agents/telegram/bots", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=BotListResponse, - ) - - async def request_link( - self, - *, - # 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, - ) -> BotRequestLinkResponse: - """ - Issues a one-shot deeplink (`t.me/?start=`) for the - operator-owned shared bot. The user opens the link, taps `Start`, and the - webhook binds their Telegram account to this droidrun user. No bot token is - needed from the user — the operator owns the bot. - """ - return await self._post( - "/agents/telegram/bots/connect", - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=BotRequestLinkResponse, - ) - - async def revoke_link( - self, - id: str, - *, - # 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, - ) -> BotRevokeLinkResponse: - """Disables the link. - - Future inbound messages from this Telegram account get the - welcome reply. The existing chat history is NOT wiped — start a fresh chat from - the UI if you suspect compromise. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not id: - raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") - return await self._post( - path_template("/agents/telegram/bots/{id}/revoke", id=id), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=BotRevokeLinkResponse, - ) - - -class BotsResourceWithRawResponse: - def __init__(self, bots: BotsResource) -> None: - self._bots = bots - - self.list = to_raw_response_wrapper( - bots.list, - ) - self.request_link = to_raw_response_wrapper( - bots.request_link, - ) - self.revoke_link = to_raw_response_wrapper( - bots.revoke_link, - ) - - -class AsyncBotsResourceWithRawResponse: - def __init__(self, bots: AsyncBotsResource) -> None: - self._bots = bots - - self.list = async_to_raw_response_wrapper( - bots.list, - ) - self.request_link = async_to_raw_response_wrapper( - bots.request_link, - ) - self.revoke_link = async_to_raw_response_wrapper( - bots.revoke_link, - ) - - -class BotsResourceWithStreamingResponse: - def __init__(self, bots: BotsResource) -> None: - self._bots = bots - - self.list = to_streamed_response_wrapper( - bots.list, - ) - self.request_link = to_streamed_response_wrapper( - bots.request_link, - ) - self.revoke_link = to_streamed_response_wrapper( - bots.revoke_link, - ) - - -class AsyncBotsResourceWithStreamingResponse: - def __init__(self, bots: AsyncBotsResource) -> None: - self._bots = bots - - self.list = async_to_streamed_response_wrapper( - bots.list, - ) - self.request_link = async_to_streamed_response_wrapper( - bots.request_link, - ) - self.revoke_link = async_to_streamed_response_wrapper( - bots.revoke_link, - ) diff --git a/src/mobilerun_sdk/resources/agents/telegram/telegram.py b/src/mobilerun_sdk/resources/agents/telegram/telegram.py deleted file mode 100644 index c41e885..0000000 --- a/src/mobilerun_sdk/resources/agents/telegram/telegram.py +++ /dev/null @@ -1,222 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import httpx - -from .bots import ( - BotsResource, - AsyncBotsResource, - BotsResourceWithRawResponse, - AsyncBotsResourceWithRawResponse, - BotsResourceWithStreamingResponse, - AsyncBotsResourceWithStreamingResponse, -) -from ...._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given -from ...._utils import maybe_transform, async_maybe_transform -from ...._compat import cached_property -from ...._resource import SyncAPIResource, AsyncAPIResource -from ...._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ...._base_client import make_request_options -from ....types.agents import telegram_receive_update_params - -__all__ = ["TelegramResource", "AsyncTelegramResource"] - - -class TelegramResource(SyncAPIResource): - @cached_property - def bots(self) -> BotsResource: - return BotsResource(self._client) - - @cached_property - def with_raw_response(self) -> TelegramResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return TelegramResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> TelegramResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return TelegramResourceWithStreamingResponse(self) - - def receive_update( - self, - *, - update_id: float, - message: telegram_receive_update_params.Message | 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, - ) -> None: - """ - Public endpoint called by Telegram's servers for the operator-owned shared bot. - One fixed URL, one fixed secret: the orchestrator compares - `X-Telegram-Bot-Api-Secret-Token` against `env.TELEGRAM_WEBHOOK_SECRET` with a - constant-time check. Inbound routing keys on `message.from.id` (Telegram user - id) → active link row → droidrun user. Returns 200 for ignorable events (group - chats, dedup hits, unrecognized senders) to avoid Telegram retry storms; 401 - only for missing/wrong secret; 400 for malformed bodies. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - return self._post( - "/agents/telegram/webhook", - body=maybe_transform( - { - "update_id": update_id, - "message": message, - }, - telegram_receive_update_params.TelegramReceiveUpdateParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=NoneType, - ) - - -class AsyncTelegramResource(AsyncAPIResource): - @cached_property - def bots(self) -> AsyncBotsResource: - return AsyncBotsResource(self._client) - - @cached_property - def with_raw_response(self) -> AsyncTelegramResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return AsyncTelegramResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncTelegramResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return AsyncTelegramResourceWithStreamingResponse(self) - - async def receive_update( - self, - *, - update_id: float, - message: telegram_receive_update_params.Message | 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, - ) -> None: - """ - Public endpoint called by Telegram's servers for the operator-owned shared bot. - One fixed URL, one fixed secret: the orchestrator compares - `X-Telegram-Bot-Api-Secret-Token` against `env.TELEGRAM_WEBHOOK_SECRET` with a - constant-time check. Inbound routing keys on `message.from.id` (Telegram user - id) → active link row → droidrun user. Returns 200 for ignorable events (group - chats, dedup hits, unrecognized senders) to avoid Telegram retry storms; 401 - only for missing/wrong secret; 400 for malformed bodies. - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - return await self._post( - "/agents/telegram/webhook", - body=await async_maybe_transform( - { - "update_id": update_id, - "message": message, - }, - telegram_receive_update_params.TelegramReceiveUpdateParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=NoneType, - ) - - -class TelegramResourceWithRawResponse: - def __init__(self, telegram: TelegramResource) -> None: - self._telegram = telegram - - self.receive_update = to_raw_response_wrapper( - telegram.receive_update, - ) - - @cached_property - def bots(self) -> BotsResourceWithRawResponse: - return BotsResourceWithRawResponse(self._telegram.bots) - - -class AsyncTelegramResourceWithRawResponse: - def __init__(self, telegram: AsyncTelegramResource) -> None: - self._telegram = telegram - - self.receive_update = async_to_raw_response_wrapper( - telegram.receive_update, - ) - - @cached_property - def bots(self) -> AsyncBotsResourceWithRawResponse: - return AsyncBotsResourceWithRawResponse(self._telegram.bots) - - -class TelegramResourceWithStreamingResponse: - def __init__(self, telegram: TelegramResource) -> None: - self._telegram = telegram - - self.receive_update = to_streamed_response_wrapper( - telegram.receive_update, - ) - - @cached_property - def bots(self) -> BotsResourceWithStreamingResponse: - return BotsResourceWithStreamingResponse(self._telegram.bots) - - -class AsyncTelegramResourceWithStreamingResponse: - def __init__(self, telegram: AsyncTelegramResource) -> None: - self._telegram = telegram - - self.receive_update = async_to_streamed_response_wrapper( - telegram.receive_update, - ) - - @cached_property - def bots(self) -> AsyncBotsResourceWithStreamingResponse: - return AsyncBotsResourceWithStreamingResponse(self._telegram.bots) diff --git a/src/mobilerun_sdk/resources/devices/devices.py b/src/mobilerun_sdk/resources/devices/devices.py index cc71aa2..9837a6f 100644 --- a/src/mobilerun_sdk/resources/devices/devices.py +++ b/src/mobilerun_sdk/resources/devices/devices.py @@ -16,6 +16,14 @@ AppsResourceWithStreamingResponse, AsyncAppsResourceWithStreamingResponse, ) +from .esim import ( + EsimResource, + AsyncEsimResource, + EsimResourceWithRawResponse, + AsyncEsimResourceWithRawResponse, + EsimResourceWithStreamingResponse, + AsyncEsimResourceWithStreamingResponse, +) from .files import ( FilesResource, AsyncFilesResource, @@ -108,14 +116,6 @@ AsyncTimezoneResourceWithStreamingResponse, ) from ..._compat import cached_property -from .esim.esim import ( - EsimResource, - AsyncEsimResource, - EsimResourceWithRawResponse, - AsyncEsimResourceWithRawResponse, - EsimResourceWithStreamingResponse, - AsyncEsimResourceWithStreamingResponse, -) from ..._resource import SyncAPIResource, AsyncAPIResource from ..._response import ( to_raw_response_wrapper, diff --git a/src/mobilerun_sdk/resources/devices/esim/esim.py b/src/mobilerun_sdk/resources/devices/esim.py similarity index 67% rename from src/mobilerun_sdk/resources/devices/esim/esim.py rename to src/mobilerun_sdk/resources/devices/esim.py index 9693e2e..ba2d38e 100644 --- a/src/mobilerun_sdk/resources/devices/esim/esim.py +++ b/src/mobilerun_sdk/resources/devices/esim.py @@ -6,38 +6,25 @@ import httpx -from .apn import ( - ApnResource, - AsyncApnResource, - ApnResourceWithRawResponse, - AsyncApnResourceWithRawResponse, - ApnResourceWithStreamingResponse, - AsyncApnResourceWithStreamingResponse, -) -from ...._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given -from ...._utils import is_given, path_template, maybe_transform, strip_not_given, async_maybe_transform -from ...._compat import cached_property -from ...._resource import SyncAPIResource, AsyncAPIResource -from ...._response import ( +from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given +from ..._utils import is_given, path_template, maybe_transform, strip_not_given, async_maybe_transform +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( to_raw_response_wrapper, to_streamed_response_wrapper, async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ...._base_client import make_request_options -from ....types.devices import esim_enable_params, esim_remove_params, esim_activate_params, esim_set_roaming_params -from ....types.devices.esim_list_response import EsimListResponse -from ....types.devices.esim_status_response import EsimStatusResponse -from ....types.devices.esim_activate_response import EsimActivateResponse +from ..._base_client import make_request_options +from ...types.devices import esim_enable_params, esim_remove_params, esim_activate_params +from ...types.devices.esim_list_response import EsimListResponse +from ...types.devices.esim_activate_response import EsimActivateResponse __all__ = ["EsimResource", "AsyncEsimResource"] class EsimResource(SyncAPIResource): - @cached_property - def apn(self) -> ApnResource: - return ApnResource(self._client) - @cached_property def with_raw_response(self) -> EsimResourceWithRawResponse: """ @@ -243,95 +230,8 @@ def remove( cast_to=NoneType, ) - def set_roaming( - self, - device_id: str, - *, - enabled: bool, - x_device_display_id: int | 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, - ) -> None: - """ - Toggle eSIM data roaming - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not device_id: - raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - extra_headers = { - **strip_not_given( - {"X-Device-Display-ID": str(x_device_display_id) if is_given(x_device_display_id) else not_given} - ), - **(extra_headers or {}), - } - return self._put( - 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 - ), - cast_to=NoneType, - ) - - def status( - self, - device_id: str, - *, - x_device_display_id: int | 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, - ) -> Optional[EsimStatusResponse]: - """ - Get eSIM connectivity status - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not device_id: - raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") - extra_headers = { - **strip_not_given( - {"X-Device-Display-ID": str(x_device_display_id) if is_given(x_device_display_id) else not_given} - ), - **(extra_headers or {}), - } - return self._get( - path_template("/devices/{device_id}/esim/status", device_id=device_id), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=EsimStatusResponse, - ) - class AsyncEsimResource(AsyncAPIResource): - @cached_property - def apn(self) -> AsyncApnResource: - return AsyncApnResource(self._client) - @cached_property def with_raw_response(self) -> AsyncEsimResourceWithRawResponse: """ @@ -537,89 +437,6 @@ async def remove( cast_to=NoneType, ) - async def set_roaming( - self, - device_id: str, - *, - enabled: bool, - x_device_display_id: int | 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, - ) -> None: - """ - Toggle eSIM data roaming - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not device_id: - raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - extra_headers = { - **strip_not_given( - {"X-Device-Display-ID": str(x_device_display_id) if is_given(x_device_display_id) else not_given} - ), - **(extra_headers or {}), - } - return await self._put( - 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 - ), - cast_to=NoneType, - ) - - async def status( - self, - device_id: str, - *, - x_device_display_id: int | 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, - ) -> Optional[EsimStatusResponse]: - """ - Get eSIM connectivity status - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not device_id: - raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") - extra_headers = { - **strip_not_given( - {"X-Device-Display-ID": str(x_device_display_id) if is_given(x_device_display_id) else not_given} - ), - **(extra_headers or {}), - } - return await self._get( - path_template("/devices/{device_id}/esim/status", device_id=device_id), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=EsimStatusResponse, - ) - class EsimResourceWithRawResponse: def __init__(self, esim: EsimResource) -> None: @@ -637,16 +454,6 @@ def __init__(self, esim: EsimResource) -> None: self.remove = to_raw_response_wrapper( esim.remove, ) - self.set_roaming = to_raw_response_wrapper( - esim.set_roaming, - ) - self.status = to_raw_response_wrapper( - esim.status, - ) - - @cached_property - def apn(self) -> ApnResourceWithRawResponse: - return ApnResourceWithRawResponse(self._esim.apn) class AsyncEsimResourceWithRawResponse: @@ -665,16 +472,6 @@ def __init__(self, esim: AsyncEsimResource) -> None: self.remove = async_to_raw_response_wrapper( esim.remove, ) - self.set_roaming = async_to_raw_response_wrapper( - esim.set_roaming, - ) - self.status = async_to_raw_response_wrapper( - esim.status, - ) - - @cached_property - def apn(self) -> AsyncApnResourceWithRawResponse: - return AsyncApnResourceWithRawResponse(self._esim.apn) class EsimResourceWithStreamingResponse: @@ -693,16 +490,6 @@ def __init__(self, esim: EsimResource) -> None: self.remove = to_streamed_response_wrapper( esim.remove, ) - self.set_roaming = to_streamed_response_wrapper( - esim.set_roaming, - ) - self.status = to_streamed_response_wrapper( - esim.status, - ) - - @cached_property - def apn(self) -> ApnResourceWithStreamingResponse: - return ApnResourceWithStreamingResponse(self._esim.apn) class AsyncEsimResourceWithStreamingResponse: @@ -721,13 +508,3 @@ def __init__(self, esim: AsyncEsimResource) -> None: self.remove = async_to_streamed_response_wrapper( esim.remove, ) - self.set_roaming = async_to_streamed_response_wrapper( - esim.set_roaming, - ) - self.status = async_to_streamed_response_wrapper( - esim.status, - ) - - @cached_property - def apn(self) -> AsyncApnResourceWithStreamingResponse: - return AsyncApnResourceWithStreamingResponse(self._esim.apn) diff --git a/src/mobilerun_sdk/resources/devices/esim/__init__.py b/src/mobilerun_sdk/resources/devices/esim/__init__.py deleted file mode 100644 index 12056c7..0000000 --- a/src/mobilerun_sdk/resources/devices/esim/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from .apn import ( - ApnResource, - AsyncApnResource, - ApnResourceWithRawResponse, - AsyncApnResourceWithRawResponse, - ApnResourceWithStreamingResponse, - AsyncApnResourceWithStreamingResponse, -) -from .esim import ( - EsimResource, - AsyncEsimResource, - EsimResourceWithRawResponse, - AsyncEsimResourceWithRawResponse, - EsimResourceWithStreamingResponse, - AsyncEsimResourceWithStreamingResponse, -) - -__all__ = [ - "ApnResource", - "AsyncApnResource", - "ApnResourceWithRawResponse", - "AsyncApnResourceWithRawResponse", - "ApnResourceWithStreamingResponse", - "AsyncApnResourceWithStreamingResponse", - "EsimResource", - "AsyncEsimResource", - "EsimResourceWithRawResponse", - "AsyncEsimResourceWithRawResponse", - "EsimResourceWithStreamingResponse", - "AsyncEsimResourceWithStreamingResponse", -] diff --git a/src/mobilerun_sdk/resources/devices/esim/apn.py b/src/mobilerun_sdk/resources/devices/esim/apn.py deleted file mode 100644 index c732e52..0000000 --- a/src/mobilerun_sdk/resources/devices/esim/apn.py +++ /dev/null @@ -1,429 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Optional - -import httpx - -from ...._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given -from ...._utils import is_given, path_template, maybe_transform, strip_not_given, async_maybe_transform -from ...._compat import cached_property -from ...._resource import SyncAPIResource, AsyncAPIResource -from ...._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from ...._base_client import make_request_options -from ....types.devices.esim import apn_create_params, apn_select_params -from ....types.devices.esim.apn_list_response import ApnListResponse - -__all__ = ["ApnResource", "AsyncApnResource"] - - -class ApnResource(SyncAPIResource): - @cached_property - def with_raw_response(self) -> ApnResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return ApnResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> ApnResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return ApnResourceWithStreamingResponse(self) - - def create( - self, - device_id: str, - *, - apn: str, - mcc: str, - mnc: str, - name: str, - protocol: str, - roaming_protocol: str, - sub_id: int, - type: str, - x_device_display_id: int | 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, - ) -> None: - """ - Create and set an APN for an eSIM subscription - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not device_id: - raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - extra_headers = { - **strip_not_given( - {"X-Device-Display-ID": str(x_device_display_id) if is_given(x_device_display_id) else not_given} - ), - **(extra_headers or {}), - } - return self._post( - path_template("/devices/{device_id}/esim/apn", device_id=device_id), - body=maybe_transform( - { - "apn": apn, - "mcc": mcc, - "mnc": mnc, - "name": name, - "protocol": protocol, - "roaming_protocol": roaming_protocol, - "sub_id": sub_id, - "type": type, - }, - apn_create_params.ApnCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=NoneType, - ) - - def list( - self, - device_id: str, - *, - x_device_display_id: int | 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, - ) -> Optional[ApnListResponse]: - """ - List APNs for active subscriptions - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not device_id: - raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") - extra_headers = { - **strip_not_given( - {"X-Device-Display-ID": str(x_device_display_id) if is_given(x_device_display_id) else not_given} - ), - **(extra_headers or {}), - } - return self._get( - path_template("/devices/{device_id}/esim/apn", device_id=device_id), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=ApnListResponse, - ) - - def select( - self, - device_id: str, - *, - apn_id: int, - sub_id: int, - x_device_display_id: int | 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, - ) -> None: - """ - Select an existing APN as preferred - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not device_id: - raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - extra_headers = { - **strip_not_given( - {"X-Device-Display-ID": str(x_device_display_id) if is_given(x_device_display_id) else not_given} - ), - **(extra_headers or {}), - } - return self._put( - path_template("/devices/{device_id}/esim/apn", device_id=device_id), - body=maybe_transform( - { - "apn_id": apn_id, - "sub_id": sub_id, - }, - apn_select_params.ApnSelectParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=NoneType, - ) - - -class AsyncApnResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncApnResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers - """ - return AsyncApnResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncApnResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response - """ - return AsyncApnResourceWithStreamingResponse(self) - - async def create( - self, - device_id: str, - *, - apn: str, - mcc: str, - mnc: str, - name: str, - protocol: str, - roaming_protocol: str, - sub_id: int, - type: str, - x_device_display_id: int | 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, - ) -> None: - """ - Create and set an APN for an eSIM subscription - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not device_id: - raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - extra_headers = { - **strip_not_given( - {"X-Device-Display-ID": str(x_device_display_id) if is_given(x_device_display_id) else not_given} - ), - **(extra_headers or {}), - } - return await self._post( - path_template("/devices/{device_id}/esim/apn", device_id=device_id), - body=await async_maybe_transform( - { - "apn": apn, - "mcc": mcc, - "mnc": mnc, - "name": name, - "protocol": protocol, - "roaming_protocol": roaming_protocol, - "sub_id": sub_id, - "type": type, - }, - apn_create_params.ApnCreateParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=NoneType, - ) - - async def list( - self, - device_id: str, - *, - x_device_display_id: int | 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, - ) -> Optional[ApnListResponse]: - """ - List APNs for active subscriptions - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not device_id: - raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") - extra_headers = { - **strip_not_given( - {"X-Device-Display-ID": str(x_device_display_id) if is_given(x_device_display_id) else not_given} - ), - **(extra_headers or {}), - } - return await self._get( - path_template("/devices/{device_id}/esim/apn", device_id=device_id), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=ApnListResponse, - ) - - async def select( - self, - device_id: str, - *, - apn_id: int, - sub_id: int, - x_device_display_id: int | 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, - ) -> None: - """ - Select an existing APN as preferred - - Args: - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not device_id: - raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}") - extra_headers = {"Accept": "*/*", **(extra_headers or {})} - extra_headers = { - **strip_not_given( - {"X-Device-Display-ID": str(x_device_display_id) if is_given(x_device_display_id) else not_given} - ), - **(extra_headers or {}), - } - return await self._put( - path_template("/devices/{device_id}/esim/apn", device_id=device_id), - body=await async_maybe_transform( - { - "apn_id": apn_id, - "sub_id": sub_id, - }, - apn_select_params.ApnSelectParams, - ), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=NoneType, - ) - - -class ApnResourceWithRawResponse: - def __init__(self, apn: ApnResource) -> None: - self._apn = apn - - self.create = to_raw_response_wrapper( - apn.create, - ) - self.list = to_raw_response_wrapper( - apn.list, - ) - self.select = to_raw_response_wrapper( - apn.select, - ) - - -class AsyncApnResourceWithRawResponse: - def __init__(self, apn: AsyncApnResource) -> None: - self._apn = apn - - self.create = async_to_raw_response_wrapper( - apn.create, - ) - self.list = async_to_raw_response_wrapper( - apn.list, - ) - self.select = async_to_raw_response_wrapper( - apn.select, - ) - - -class ApnResourceWithStreamingResponse: - def __init__(self, apn: ApnResource) -> None: - self._apn = apn - - self.create = to_streamed_response_wrapper( - apn.create, - ) - self.list = to_streamed_response_wrapper( - apn.list, - ) - self.select = to_streamed_response_wrapper( - apn.select, - ) - - -class AsyncApnResourceWithStreamingResponse: - def __init__(self, apn: AsyncApnResource) -> None: - self._apn = apn - - self.create = async_to_streamed_response_wrapper( - apn.create, - ) - self.list = async_to_streamed_response_wrapper( - apn.list, - ) - self.select = async_to_streamed_response_wrapper( - apn.select, - ) diff --git a/src/mobilerun_sdk/types/__init__.py b/src/mobilerun_sdk/types/__init__.py index e641405..2b5082d 100644 --- a/src/mobilerun_sdk/types/__init__.py +++ b/src/mobilerun_sdk/types/__init__.py @@ -36,7 +36,6 @@ from .hook_update_params import HookUpdateParams as HookUpdateParams from .task_list_response import TaskListResponse as TaskListResponse from .task_stop_response import TaskStopResponse as TaskStopResponse -from .agent_list_response import AgentListResponse as AgentListResponse from .app_delete_response import AppDeleteResponse as AppDeleteResponse from .carrier_list_params import CarrierListParams as CarrierListParams from .hook_perform_params import HookPerformParams as HookPerformParams diff --git a/src/mobilerun_sdk/types/agent_list_response.py b/src/mobilerun_sdk/types/agent_list_response.py deleted file mode 100644 index fc366d6..0000000 --- a/src/mobilerun_sdk/types/agent_list_response.py +++ /dev/null @@ -1,33 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List, Optional -from typing_extensions import TypeAlias - -from pydantic import Field as FieldInfo - -from .._models import BaseModel - -__all__ = ["AgentListResponse", "AgentListResponseItem"] - - -class AgentListResponseItem(BaseModel): - id: int - - description: Optional[str] = None - - icon: str - - llm_model: str = FieldInfo(alias="llmModel") - - max_steps: int = FieldInfo(alias="maxSteps") - - name: str - - reasoning: bool - - subagent_model: Optional[str] = FieldInfo(alias="subagentModel", default=None) - - vision: bool - - -AgentListResponse: TypeAlias = List[AgentListResponseItem] diff --git a/src/mobilerun_sdk/types/agents/__init__.py b/src/mobilerun_sdk/types/agents/__init__.py index b04d567..f8cfbf9 100644 --- a/src/mobilerun_sdk/types/agents/__init__.py +++ b/src/mobilerun_sdk/types/agents/__init__.py @@ -3,17 +3,11 @@ from __future__ import annotations from .file_list_files_params import FileListFilesParams as FileListFilesParams -from .chat_send_prompt_params import ChatSendPromptParams as ChatSendPromptParams -from .chat_send_message_params import ChatSendMessageParams as ChatSendMessageParams from .file_list_files_response import FileListFilesResponse as FileListFilesResponse -from .chat_send_prompt_response import ChatSendPromptResponse as ChatSendPromptResponse -from .chat_send_message_response import ChatSendMessageResponse as ChatSendMessageResponse from .file_mint_upload_url_params import FileMintUploadURLParams as FileMintUploadURLParams from .chat_get_chat_state_response import ChatGetChatStateResponse as ChatGetChatStateResponse from .chat_rehydrate_chat_response import ChatRehydrateChatResponse as ChatRehydrateChatResponse from .file_mint_upload_url_response import FileMintUploadURLResponse as FileMintUploadURLResponse from .chat_deliver_permission_params import ChatDeliverPermissionParams as ChatDeliverPermissionParams -from .chat_subscribe_events_response import ChatSubscribeEventsResponse as ChatSubscribeEventsResponse -from .telegram_receive_update_params import TelegramReceiveUpdateParams as TelegramReceiveUpdateParams from .chat_deliver_permission_response import ChatDeliverPermissionResponse as ChatDeliverPermissionResponse from .chat_list_slash_commands_response import ChatListSlashCommandsResponse as ChatListSlashCommandsResponse diff --git a/src/mobilerun_sdk/types/agents/chat_send_message_params.py b/src/mobilerun_sdk/types/agents/chat_send_message_params.py deleted file mode 100644 index e39c7dd..0000000 --- a/src/mobilerun_sdk/types/agents/chat_send_message_params.py +++ /dev/null @@ -1,13 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, TypedDict - -__all__ = ["ChatSendMessageParams"] - - -class ChatSendMessageParams(TypedDict, total=False): - message: Required[str] - - agent: str diff --git a/src/mobilerun_sdk/types/agents/chat_send_message_response.py b/src/mobilerun_sdk/types/agents/chat_send_message_response.py deleted file mode 100644 index 3ad7cb8..0000000 --- a/src/mobilerun_sdk/types/agents/chat_send_message_response.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import Optional - -from pydantic import Field as FieldInfo - -from ..._models import BaseModel - -__all__ = ["ChatSendMessageResponse"] - - -class ChatSendMessageResponse(BaseModel): - assistant_text: str = FieldInfo(alias="assistantText") - - error_text: Optional[str] = FieldInfo(alias="errorText", default=None) diff --git a/src/mobilerun_sdk/types/agents/chat_send_prompt_params.py b/src/mobilerun_sdk/types/agents/chat_send_prompt_params.py deleted file mode 100644 index 69f5188..0000000 --- a/src/mobilerun_sdk/types/agents/chat_send_prompt_params.py +++ /dev/null @@ -1,41 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Dict, Iterable, Optional -from typing_extensions import Literal, Required, Annotated, TypedDict - -from ..._types import SequenceNotStr -from ..._utils import PropertyInfo - -__all__ = ["ChatSendPromptParams", "Message", "MessagePart"] - - -class ChatSendPromptParams(TypedDict, total=False): - messages: Required[Iterable[Message]] - - id: str - - agent: str - - context: str - - file_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="fileIds")] - - metadata: Dict[str, Optional[object]] - - trigger: Literal["submit-message", "regenerate-message"] - - -class MessagePart(TypedDict, total=False, extra_items=Optional[object]): # type: ignore[call-arg] - type: Required[str] - - -class Message(TypedDict, total=False): - id: Required[str] - - parts: Required[Iterable[MessagePart]] - - role: Required[Literal["user", "assistant", "system"]] - - metadata: Dict[str, Optional[object]] diff --git a/src/mobilerun_sdk/types/agents/chat_send_prompt_response.py b/src/mobilerun_sdk/types/agents/chat_send_prompt_response.py deleted file mode 100644 index d081551..0000000 --- a/src/mobilerun_sdk/types/agents/chat_send_prompt_response.py +++ /dev/null @@ -1,7 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import TypeAlias - -__all__ = ["ChatSendPromptResponse"] - -ChatSendPromptResponse: TypeAlias = str diff --git a/src/mobilerun_sdk/types/agents/chat_subscribe_events_response.py b/src/mobilerun_sdk/types/agents/chat_subscribe_events_response.py deleted file mode 100644 index 0d74016..0000000 --- a/src/mobilerun_sdk/types/agents/chat_subscribe_events_response.py +++ /dev/null @@ -1,7 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import TypeAlias - -__all__ = ["ChatSubscribeEventsResponse"] - -ChatSubscribeEventsResponse: TypeAlias = str diff --git a/src/mobilerun_sdk/types/agents/telegram/__init__.py b/src/mobilerun_sdk/types/agents/telegram/__init__.py deleted file mode 100644 index b6a23cd..0000000 --- a/src/mobilerun_sdk/types/agents/telegram/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from .bot_list_response import BotListResponse as BotListResponse -from .bot_revoke_link_response import BotRevokeLinkResponse as BotRevokeLinkResponse -from .bot_request_link_response import BotRequestLinkResponse as BotRequestLinkResponse diff --git a/src/mobilerun_sdk/types/agents/telegram/bot_list_response.py b/src/mobilerun_sdk/types/agents/telegram/bot_list_response.py deleted file mode 100644 index 72f70d8..0000000 --- a/src/mobilerun_sdk/types/agents/telegram/bot_list_response.py +++ /dev/null @@ -1,31 +0,0 @@ -# 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__ = ["BotListResponse", "Bot"] - - -class Bot(BaseModel): - id: str - - bot_username: str = FieldInfo(alias="botUsername") - - created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None) - - last_message_at: Optional[datetime] = FieldInfo(alias="lastMessageAt", default=None) - - link_code_expires_at: Optional[datetime] = FieldInfo(alias="linkCodeExpiresAt", default=None) - - owner_telegram_user_id: Optional[int] = FieldInfo(alias="ownerTelegramUserId", default=None) - - status: Literal["pending", "active", "disabled"] - - -class BotListResponse(BaseModel): - bots: List[Bot] diff --git a/src/mobilerun_sdk/types/agents/telegram/bot_request_link_response.py b/src/mobilerun_sdk/types/agents/telegram/bot_request_link_response.py deleted file mode 100644 index 98bc329..0000000 --- a/src/mobilerun_sdk/types/agents/telegram/bot_request_link_response.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from pydantic import Field as FieldInfo - -from ...._models import BaseModel - -__all__ = ["BotRequestLinkResponse"] - - -class BotRequestLinkResponse(BaseModel): - id: str - - bot_username: str = FieldInfo(alias="botUsername") - - deep_link: str = FieldInfo(alias="deepLink") diff --git a/src/mobilerun_sdk/types/agents/telegram/bot_revoke_link_response.py b/src/mobilerun_sdk/types/agents/telegram/bot_revoke_link_response.py deleted file mode 100644 index 0ff50b6..0000000 --- a/src/mobilerun_sdk/types/agents/telegram/bot_revoke_link_response.py +++ /dev/null @@ -1,11 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal - -from ...._models import BaseModel - -__all__ = ["BotRevokeLinkResponse"] - - -class BotRevokeLinkResponse(BaseModel): - revoked: Literal[True] diff --git a/src/mobilerun_sdk/types/agents/telegram_receive_update_params.py b/src/mobilerun_sdk/types/agents/telegram_receive_update_params.py deleted file mode 100644 index 549300e..0000000 --- a/src/mobilerun_sdk/types/agents/telegram_receive_update_params.py +++ /dev/null @@ -1,49 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Optional -from typing_extensions import Required, TypedDict - -__all__ = ["TelegramReceiveUpdateParams", "Message", "MessageChat", "MessageFrom"] - - -class TelegramReceiveUpdateParams(TypedDict, total=False): - update_id: Required[float] - - message: Message - - -class MessageChat(TypedDict, total=False, extra_items=Optional[object]): # type: ignore[call-arg] - id: Required[float] - - type: Required[str] - - -class MessageFrom(TypedDict, total=False, extra_items=Optional[object]): # type: ignore[call-arg] - id: Required[float] - - first_name: str - - is_bot: bool - - username: str - - -_MessageReservedKeywords = TypedDict( - "_MessageReservedKeywords", - { - "from": MessageFrom, - }, - total=False, -) - - -class Message(_MessageReservedKeywords, total=False, extra_items=Optional[object]): # type: ignore[call-arg] - chat: Required[MessageChat] - - message_id: Required[float] - - caption: str - - text: str diff --git a/src/mobilerun_sdk/types/devices/__init__.py b/src/mobilerun_sdk/types/devices/__init__.py index 8d4f005..ab80387 100644 --- a/src/mobilerun_sdk/types/devices/__init__.py +++ b/src/mobilerun_sdk/types/devices/__init__.py @@ -30,7 +30,6 @@ from .timezone_set_params import TimezoneSetParams as TimezoneSetParams from .action_global_params import ActionGlobalParams as ActionGlobalParams from .esim_activate_params import EsimActivateParams as EsimActivateParams -from .esim_status_response import EsimStatusResponse as EsimStatusResponse from .file_download_params import FileDownloadParams as FileDownloadParams from .proxy_connect_params import ProxyConnectParams as ProxyConnectParams from .keyboard_write_params import KeyboardWriteParams as KeyboardWriteParams @@ -41,7 +40,6 @@ from .timezone_get_response import TimezoneGetResponse as TimezoneGetResponse from .esim_activate_response import EsimActivateResponse as EsimActivateResponse from .file_download_response import FileDownloadResponse as FileDownloadResponse -from .esim_set_roaming_params import EsimSetRoamingParams as EsimSetRoamingParams from .state_screenshot_params import StateScreenshotParams as StateScreenshotParams from .state_screenshot_response import StateScreenshotResponse as StateScreenshotResponse from .action_overlay_visible_response import ActionOverlayVisibleResponse as ActionOverlayVisibleResponse diff --git a/src/mobilerun_sdk/types/devices/esim/__init__.py b/src/mobilerun_sdk/types/devices/esim/__init__.py deleted file mode 100644 index 7fb2236..0000000 --- a/src/mobilerun_sdk/types/devices/esim/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from .apn_create_params import ApnCreateParams as ApnCreateParams -from .apn_list_response import ApnListResponse as ApnListResponse -from .apn_select_params import ApnSelectParams as ApnSelectParams diff --git a/src/mobilerun_sdk/types/devices/esim/apn_create_params.py b/src/mobilerun_sdk/types/devices/esim/apn_create_params.py deleted file mode 100644 index ffb2434..0000000 --- a/src/mobilerun_sdk/types/devices/esim/apn_create_params.py +++ /dev/null @@ -1,29 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, Annotated, TypedDict - -from ...._utils import PropertyInfo - -__all__ = ["ApnCreateParams"] - - -class ApnCreateParams(TypedDict, total=False): - apn: Required[str] - - mcc: Required[str] - - mnc: Required[str] - - name: Required[str] - - protocol: Required[str] - - roaming_protocol: Required[Annotated[str, PropertyInfo(alias="roamingProtocol")]] - - sub_id: Required[Annotated[int, PropertyInfo(alias="subId")]] - - type: Required[str] - - x_device_display_id: Annotated[int, PropertyInfo(alias="X-Device-Display-ID")] diff --git a/src/mobilerun_sdk/types/devices/esim/apn_list_response.py b/src/mobilerun_sdk/types/devices/esim/apn_list_response.py deleted file mode 100644 index 41bd145..0000000 --- a/src/mobilerun_sdk/types/devices/esim/apn_list_response.py +++ /dev/null @@ -1,35 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List -from typing_extensions import TypeAlias - -from pydantic import Field as FieldInfo - -from ...._models import BaseModel - -__all__ = ["ApnListResponse", "ApnListResponseItem"] - - -class ApnListResponseItem(BaseModel): - id: int - - apn: str - - is_preferred: bool = FieldInfo(alias="isPreferred") - - mcc: str - - mnc: str - - name: str - - protocol: str - - roaming_protocol: str = FieldInfo(alias="roamingProtocol") - - sub_id: int = FieldInfo(alias="subId") - - type: str - - -ApnListResponse: TypeAlias = List[ApnListResponseItem] diff --git a/src/mobilerun_sdk/types/devices/esim/apn_select_params.py b/src/mobilerun_sdk/types/devices/esim/apn_select_params.py deleted file mode 100644 index ca44100..0000000 --- a/src/mobilerun_sdk/types/devices/esim/apn_select_params.py +++ /dev/null @@ -1,17 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, Annotated, TypedDict - -from ...._utils import PropertyInfo - -__all__ = ["ApnSelectParams"] - - -class ApnSelectParams(TypedDict, total=False): - apn_id: Required[Annotated[int, PropertyInfo(alias="apnId")]] - - sub_id: Required[Annotated[int, PropertyInfo(alias="subId")]] - - x_device_display_id: Annotated[int, PropertyInfo(alias="X-Device-Display-ID")] diff --git a/src/mobilerun_sdk/types/devices/esim_set_roaming_params.py b/src/mobilerun_sdk/types/devices/esim_set_roaming_params.py deleted file mode 100644 index 218544c..0000000 --- a/src/mobilerun_sdk/types/devices/esim_set_roaming_params.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing_extensions import Required, Annotated, TypedDict - -from ..._utils import PropertyInfo - -__all__ = ["EsimSetRoamingParams"] - - -class EsimSetRoamingParams(TypedDict, total=False): - enabled: Required[bool] - - x_device_display_id: Annotated[int, PropertyInfo(alias="X-Device-Display-ID")] diff --git a/src/mobilerun_sdk/types/devices/esim_status_response.py b/src/mobilerun_sdk/types/devices/esim_status_response.py deleted file mode 100644 index 9a42b6e..0000000 --- a/src/mobilerun_sdk/types/devices/esim_status_response.py +++ /dev/null @@ -1,35 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing import List -from typing_extensions import TypeAlias - -from pydantic import Field as FieldInfo - -from ..._models import BaseModel - -__all__ = ["EsimStatusResponse", "EsimStatusResponseItem"] - - -class EsimStatusResponseItem(BaseModel): - carrier: str - - data_roaming_enabled: bool = FieldInfo(alias="dataRoamingEnabled") - - data_state: str = FieldInfo(alias="dataState") - - is_roaming: bool = FieldInfo(alias="isRoaming") - - mobile_data_enabled: bool = FieldInfo(alias="mobileDataEnabled") - - network_type: str = FieldInfo(alias="networkType") - - operator: str - - phone_type: str = FieldInfo(alias="phoneType") - - sim_state: str = FieldInfo(alias="simState") - - sub_id: int = FieldInfo(alias="subId") - - -EsimStatusResponse: TypeAlias = List[EsimStatusResponseItem] diff --git a/tests/api_resources/agents/telegram/__init__.py b/tests/api_resources/agents/telegram/__init__.py deleted file mode 100644 index fd8019a..0000000 --- a/tests/api_resources/agents/telegram/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/agents/telegram/test_bots.py b/tests/api_resources/agents/telegram/test_bots.py deleted file mode 100644 index 524c869..0000000 --- a/tests/api_resources/agents/telegram/test_bots.py +++ /dev/null @@ -1,220 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from tests.utils import assert_matches_type -from mobilerun_sdk import Mobilerun, AsyncMobilerun -from mobilerun_sdk.types.agents.telegram import BotListResponse, BotRevokeLinkResponse, BotRequestLinkResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestBots: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_list(self, client: Mobilerun) -> None: - bot = client.agents.telegram.bots.list() - assert_matches_type(BotListResponse, bot, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_list(self, client: Mobilerun) -> None: - response = client.agents.telegram.bots.with_raw_response.list() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - bot = response.parse() - assert_matches_type(BotListResponse, bot, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_list(self, client: Mobilerun) -> None: - with client.agents.telegram.bots.with_streaming_response.list() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - bot = response.parse() - assert_matches_type(BotListResponse, bot, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_request_link(self, client: Mobilerun) -> None: - bot = client.agents.telegram.bots.request_link() - assert_matches_type(BotRequestLinkResponse, bot, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_request_link(self, client: Mobilerun) -> None: - response = client.agents.telegram.bots.with_raw_response.request_link() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - bot = response.parse() - assert_matches_type(BotRequestLinkResponse, bot, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_request_link(self, client: Mobilerun) -> None: - with client.agents.telegram.bots.with_streaming_response.request_link() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - bot = response.parse() - assert_matches_type(BotRequestLinkResponse, bot, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_revoke_link(self, client: Mobilerun) -> None: - bot = client.agents.telegram.bots.revoke_link( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(BotRevokeLinkResponse, bot, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_revoke_link(self, client: Mobilerun) -> None: - response = client.agents.telegram.bots.with_raw_response.revoke_link( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - bot = response.parse() - assert_matches_type(BotRevokeLinkResponse, bot, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_revoke_link(self, client: Mobilerun) -> None: - with client.agents.telegram.bots.with_streaming_response.revoke_link( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - bot = response.parse() - assert_matches_type(BotRevokeLinkResponse, bot, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_revoke_link(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): - client.agents.telegram.bots.with_raw_response.revoke_link( - "", - ) - - -class TestAsyncBots: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_list(self, async_client: AsyncMobilerun) -> None: - bot = await async_client.agents.telegram.bots.list() - assert_matches_type(BotListResponse, bot, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: - response = await async_client.agents.telegram.bots.with_raw_response.list() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - bot = await response.parse() - assert_matches_type(BotListResponse, bot, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: - async with async_client.agents.telegram.bots.with_streaming_response.list() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - bot = await response.parse() - assert_matches_type(BotListResponse, bot, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_request_link(self, async_client: AsyncMobilerun) -> None: - bot = await async_client.agents.telegram.bots.request_link() - assert_matches_type(BotRequestLinkResponse, bot, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_request_link(self, async_client: AsyncMobilerun) -> None: - response = await async_client.agents.telegram.bots.with_raw_response.request_link() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - bot = await response.parse() - assert_matches_type(BotRequestLinkResponse, bot, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_request_link(self, async_client: AsyncMobilerun) -> None: - async with async_client.agents.telegram.bots.with_streaming_response.request_link() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - bot = await response.parse() - assert_matches_type(BotRequestLinkResponse, bot, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_revoke_link(self, async_client: AsyncMobilerun) -> None: - bot = await async_client.agents.telegram.bots.revoke_link( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(BotRevokeLinkResponse, bot, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_revoke_link(self, async_client: AsyncMobilerun) -> None: - response = await async_client.agents.telegram.bots.with_raw_response.revoke_link( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - bot = await response.parse() - assert_matches_type(BotRevokeLinkResponse, bot, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_revoke_link(self, async_client: AsyncMobilerun) -> None: - async with async_client.agents.telegram.bots.with_streaming_response.revoke_link( - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - bot = await response.parse() - assert_matches_type(BotRevokeLinkResponse, bot, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_revoke_link(self, async_client: AsyncMobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): - await async_client.agents.telegram.bots.with_raw_response.revoke_link( - "", - ) diff --git a/tests/api_resources/agents/test_chat.py b/tests/api_resources/agents/test_chat.py index 14da7a0..a5525f6 100644 --- a/tests/api_resources/agents/test_chat.py +++ b/tests/api_resources/agents/test_chat.py @@ -10,7 +10,6 @@ from tests.utils import assert_matches_type from mobilerun_sdk import Mobilerun, AsyncMobilerun from mobilerun_sdk.types.agents import ( - ChatSendMessageResponse, ChatGetChatStateResponse, ChatRehydrateChatResponse, ChatDeliverPermissionResponse, @@ -144,148 +143,6 @@ def test_streaming_response_rehydrate_chat(self, client: Mobilerun) -> None: assert cast(Any, response.is_closed) is True - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_send_message(self, client: Mobilerun) -> None: - chat = client.agents.chat.send_message( - message="x", - ) - assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_send_message_with_all_params(self, client: Mobilerun) -> None: - chat = client.agents.chat.send_message( - message="x", - agent="agent", - ) - assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_send_message(self, client: Mobilerun) -> None: - response = client.agents.chat.with_raw_response.send_message( - message="x", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - chat = response.parse() - assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_send_message(self, client: Mobilerun) -> None: - with client.agents.chat.with_streaming_response.send_message( - message="x", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - chat = response.parse() - assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_send_prompt(self, client: Mobilerun) -> None: - chat_stream = client.agents.chat.send_prompt( - messages=[ - { - "id": "id", - "parts": [{"type": "type"}], - "role": "user", - } - ], - ) - chat_stream.response.close() - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_send_prompt_with_all_params(self, client: Mobilerun) -> None: - chat_stream = client.agents.chat.send_prompt( - messages=[ - { - "id": "id", - "parts": [{"type": "type"}], - "role": "user", - "metadata": {"foo": "bar"}, - } - ], - id="id", - agent="agent", - context="x", - file_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - metadata={"foo": "bar"}, - trigger="submit-message", - ) - chat_stream.response.close() - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_send_prompt(self, client: Mobilerun) -> None: - response = client.agents.chat.with_raw_response.send_prompt( - messages=[ - { - "id": "id", - "parts": [{"type": "type"}], - "role": "user", - } - ], - ) - - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - stream = response.parse() - stream.close() - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_send_prompt(self, client: Mobilerun) -> None: - with client.agents.chat.with_streaming_response.send_prompt( - messages=[ - { - "id": "id", - "parts": [{"type": "type"}], - "role": "user", - } - ], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - stream = response.parse() - stream.close() - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_subscribe_events(self, client: Mobilerun) -> None: - chat_stream = client.agents.chat.subscribe_events() - chat_stream.response.close() - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_subscribe_events(self, client: Mobilerun) -> None: - response = client.agents.chat.with_raw_response.subscribe_events() - - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - stream = response.parse() - stream.close() - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_subscribe_events(self, client: Mobilerun) -> None: - with client.agents.chat.with_streaming_response.subscribe_events() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - stream = response.parse() - stream.close() - - assert cast(Any, response.is_closed) is True - class TestAsyncChat: parametrize = pytest.mark.parametrize( @@ -412,145 +269,3 @@ async def test_streaming_response_rehydrate_chat(self, async_client: AsyncMobile assert_matches_type(ChatRehydrateChatResponse, chat, path=["response"]) assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_send_message(self, async_client: AsyncMobilerun) -> None: - chat = await async_client.agents.chat.send_message( - message="x", - ) - assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_send_message_with_all_params(self, async_client: AsyncMobilerun) -> None: - chat = await async_client.agents.chat.send_message( - message="x", - agent="agent", - ) - assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_send_message(self, async_client: AsyncMobilerun) -> None: - response = await async_client.agents.chat.with_raw_response.send_message( - message="x", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - chat = await response.parse() - assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_send_message(self, async_client: AsyncMobilerun) -> None: - async with async_client.agents.chat.with_streaming_response.send_message( - message="x", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - chat = await response.parse() - assert_matches_type(ChatSendMessageResponse, chat, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_send_prompt(self, async_client: AsyncMobilerun) -> None: - chat_stream = await async_client.agents.chat.send_prompt( - messages=[ - { - "id": "id", - "parts": [{"type": "type"}], - "role": "user", - } - ], - ) - await chat_stream.response.aclose() - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_send_prompt_with_all_params(self, async_client: AsyncMobilerun) -> None: - chat_stream = await async_client.agents.chat.send_prompt( - messages=[ - { - "id": "id", - "parts": [{"type": "type"}], - "role": "user", - "metadata": {"foo": "bar"}, - } - ], - id="id", - agent="agent", - context="x", - file_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], - metadata={"foo": "bar"}, - trigger="submit-message", - ) - await chat_stream.response.aclose() - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_send_prompt(self, async_client: AsyncMobilerun) -> None: - response = await async_client.agents.chat.with_raw_response.send_prompt( - messages=[ - { - "id": "id", - "parts": [{"type": "type"}], - "role": "user", - } - ], - ) - - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - stream = await response.parse() - await stream.close() - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_send_prompt(self, async_client: AsyncMobilerun) -> None: - async with async_client.agents.chat.with_streaming_response.send_prompt( - messages=[ - { - "id": "id", - "parts": [{"type": "type"}], - "role": "user", - } - ], - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - stream = await response.parse() - await stream.close() - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_subscribe_events(self, async_client: AsyncMobilerun) -> None: - chat_stream = await async_client.agents.chat.subscribe_events() - await chat_stream.response.aclose() - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_subscribe_events(self, async_client: AsyncMobilerun) -> None: - response = await async_client.agents.chat.with_raw_response.subscribe_events() - - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - stream = await response.parse() - await stream.close() - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_subscribe_events(self, async_client: AsyncMobilerun) -> None: - async with async_client.agents.chat.with_streaming_response.subscribe_events() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - stream = await response.parse() - await stream.close() - - assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/agents/test_telegram.py b/tests/api_resources/agents/test_telegram.py deleted file mode 100644 index c052107..0000000 --- a/tests/api_resources/agents/test_telegram.py +++ /dev/null @@ -1,136 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from mobilerun_sdk import Mobilerun, AsyncMobilerun - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestTelegram: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_receive_update(self, client: Mobilerun) -> None: - telegram = client.agents.telegram.receive_update( - update_id=0, - ) - assert telegram is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_receive_update_with_all_params(self, client: Mobilerun) -> None: - telegram = client.agents.telegram.receive_update( - update_id=0, - message={ - "chat": { - "id": 0, - "type": "type", - }, - "message_id": 0, - "caption": "caption", - "from": { - "id": 0, - "first_name": "first_name", - "is_bot": True, - "username": "username", - }, - "text": "text", - }, - ) - assert telegram is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_receive_update(self, client: Mobilerun) -> None: - response = client.agents.telegram.with_raw_response.receive_update( - update_id=0, - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - telegram = response.parse() - assert telegram is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_receive_update(self, client: Mobilerun) -> None: - with client.agents.telegram.with_streaming_response.receive_update( - update_id=0, - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - telegram = response.parse() - assert telegram is None - - assert cast(Any, response.is_closed) is True - - -class TestAsyncTelegram: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_receive_update(self, async_client: AsyncMobilerun) -> None: - telegram = await async_client.agents.telegram.receive_update( - update_id=0, - ) - assert telegram is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_receive_update_with_all_params(self, async_client: AsyncMobilerun) -> None: - telegram = await async_client.agents.telegram.receive_update( - update_id=0, - message={ - "chat": { - "id": 0, - "type": "type", - }, - "message_id": 0, - "caption": "caption", - "from": { - "id": 0, - "first_name": "first_name", - "is_bot": True, - "username": "username", - }, - "text": "text", - }, - ) - assert telegram is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_receive_update(self, async_client: AsyncMobilerun) -> None: - response = await async_client.agents.telegram.with_raw_response.receive_update( - update_id=0, - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - telegram = await response.parse() - assert telegram is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_receive_update(self, async_client: AsyncMobilerun) -> None: - async with async_client.agents.telegram.with_streaming_response.receive_update( - update_id=0, - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - telegram = await response.parse() - assert telegram is None - - assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/devices/esim/__init__.py b/tests/api_resources/devices/esim/__init__.py deleted file mode 100644 index fd8019a..0000000 --- a/tests/api_resources/devices/esim/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/devices/esim/test_apn.py b/tests/api_resources/devices/esim/test_apn.py deleted file mode 100644 index d538cf7..0000000 --- a/tests/api_resources/devices/esim/test_apn.py +++ /dev/null @@ -1,430 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, Optional, cast - -import pytest - -from tests.utils import assert_matches_type -from mobilerun_sdk import Mobilerun, AsyncMobilerun -from mobilerun_sdk.types.devices.esim import ApnListResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestApn: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create(self, client: Mobilerun) -> None: - apn = client.devices.esim.apn.create( - device_id="deviceId", - apn="apn", - mcc="mcc", - mnc="mnc", - name="name", - protocol="protocol", - roaming_protocol="roamingProtocol", - sub_id=0, - type="type", - ) - assert apn is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_create_with_all_params(self, client: Mobilerun) -> None: - apn = client.devices.esim.apn.create( - device_id="deviceId", - apn="apn", - mcc="mcc", - mnc="mnc", - name="name", - protocol="protocol", - roaming_protocol="roamingProtocol", - sub_id=0, - type="type", - x_device_display_id=0, - ) - assert apn is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_create(self, client: Mobilerun) -> None: - response = client.devices.esim.apn.with_raw_response.create( - device_id="deviceId", - apn="apn", - mcc="mcc", - mnc="mnc", - name="name", - protocol="protocol", - roaming_protocol="roamingProtocol", - sub_id=0, - type="type", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - apn = response.parse() - assert apn is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_create(self, client: Mobilerun) -> None: - with client.devices.esim.apn.with_streaming_response.create( - device_id="deviceId", - apn="apn", - mcc="mcc", - mnc="mnc", - name="name", - protocol="protocol", - roaming_protocol="roamingProtocol", - sub_id=0, - type="type", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - apn = response.parse() - assert apn is None - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - 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.esim.apn.with_raw_response.create( - device_id="", - apn="apn", - mcc="mcc", - mnc="mnc", - name="name", - protocol="protocol", - roaming_protocol="roamingProtocol", - sub_id=0, - type="type", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_list(self, client: Mobilerun) -> None: - apn = client.devices.esim.apn.list( - device_id="deviceId", - ) - assert_matches_type(Optional[ApnListResponse], apn, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_list_with_all_params(self, client: Mobilerun) -> None: - apn = client.devices.esim.apn.list( - device_id="deviceId", - x_device_display_id=0, - ) - assert_matches_type(Optional[ApnListResponse], apn, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_list(self, client: Mobilerun) -> None: - response = client.devices.esim.apn.with_raw_response.list( - device_id="deviceId", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - apn = response.parse() - assert_matches_type(Optional[ApnListResponse], apn, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_list(self, client: Mobilerun) -> None: - with client.devices.esim.apn.with_streaming_response.list( - device_id="deviceId", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - apn = response.parse() - assert_matches_type(Optional[ApnListResponse], apn, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_list(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `device_id` but received ''"): - client.devices.esim.apn.with_raw_response.list( - device_id="", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_select(self, client: Mobilerun) -> None: - apn = client.devices.esim.apn.select( - device_id="deviceId", - apn_id=0, - sub_id=0, - ) - assert apn is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_select_with_all_params(self, client: Mobilerun) -> None: - apn = client.devices.esim.apn.select( - device_id="deviceId", - apn_id=0, - sub_id=0, - x_device_display_id=0, - ) - assert apn is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_select(self, client: Mobilerun) -> None: - response = client.devices.esim.apn.with_raw_response.select( - device_id="deviceId", - apn_id=0, - sub_id=0, - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - apn = response.parse() - assert apn is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_select(self, client: Mobilerun) -> None: - with client.devices.esim.apn.with_streaming_response.select( - device_id="deviceId", - apn_id=0, - sub_id=0, - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - apn = response.parse() - assert apn is None - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_select(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `device_id` but received ''"): - client.devices.esim.apn.with_raw_response.select( - device_id="", - apn_id=0, - sub_id=0, - ) - - -class TestAsyncApn: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create(self, async_client: AsyncMobilerun) -> None: - apn = await async_client.devices.esim.apn.create( - device_id="deviceId", - apn="apn", - mcc="mcc", - mnc="mnc", - name="name", - protocol="protocol", - roaming_protocol="roamingProtocol", - sub_id=0, - type="type", - ) - assert apn is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_create_with_all_params(self, async_client: AsyncMobilerun) -> None: - apn = await async_client.devices.esim.apn.create( - device_id="deviceId", - apn="apn", - mcc="mcc", - mnc="mnc", - name="name", - protocol="protocol", - roaming_protocol="roamingProtocol", - sub_id=0, - type="type", - x_device_display_id=0, - ) - assert apn is None - - @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.devices.esim.apn.with_raw_response.create( - device_id="deviceId", - apn="apn", - mcc="mcc", - mnc="mnc", - name="name", - protocol="protocol", - roaming_protocol="roamingProtocol", - sub_id=0, - type="type", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - apn = await response.parse() - assert apn is 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.devices.esim.apn.with_streaming_response.create( - device_id="deviceId", - apn="apn", - mcc="mcc", - mnc="mnc", - name="name", - protocol="protocol", - roaming_protocol="roamingProtocol", - sub_id=0, - type="type", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - apn = await response.parse() - assert apn is None - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - 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.esim.apn.with_raw_response.create( - device_id="", - apn="apn", - mcc="mcc", - mnc="mnc", - name="name", - protocol="protocol", - roaming_protocol="roamingProtocol", - sub_id=0, - type="type", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_list(self, async_client: AsyncMobilerun) -> None: - apn = await async_client.devices.esim.apn.list( - device_id="deviceId", - ) - assert_matches_type(Optional[ApnListResponse], apn, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: - apn = await async_client.devices.esim.apn.list( - device_id="deviceId", - x_device_display_id=0, - ) - assert_matches_type(Optional[ApnListResponse], apn, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: - response = await async_client.devices.esim.apn.with_raw_response.list( - device_id="deviceId", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - apn = await response.parse() - assert_matches_type(Optional[ApnListResponse], apn, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: - async with async_client.devices.esim.apn.with_streaming_response.list( - device_id="deviceId", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - apn = await response.parse() - assert_matches_type(Optional[ApnListResponse], apn, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_list(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.esim.apn.with_raw_response.list( - device_id="", - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_select(self, async_client: AsyncMobilerun) -> None: - apn = await async_client.devices.esim.apn.select( - device_id="deviceId", - apn_id=0, - sub_id=0, - ) - assert apn is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_select_with_all_params(self, async_client: AsyncMobilerun) -> None: - apn = await async_client.devices.esim.apn.select( - device_id="deviceId", - apn_id=0, - sub_id=0, - x_device_display_id=0, - ) - assert apn is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_select(self, async_client: AsyncMobilerun) -> None: - response = await async_client.devices.esim.apn.with_raw_response.select( - device_id="deviceId", - apn_id=0, - sub_id=0, - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - apn = await response.parse() - assert apn is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_select(self, async_client: AsyncMobilerun) -> None: - async with async_client.devices.esim.apn.with_streaming_response.select( - device_id="deviceId", - apn_id=0, - sub_id=0, - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - apn = await response.parse() - assert apn is None - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_select(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.esim.apn.with_raw_response.select( - device_id="", - apn_id=0, - sub_id=0, - ) diff --git a/tests/api_resources/devices/test_esim.py b/tests/api_resources/devices/test_esim.py index 82541c2..3ff9449 100644 --- a/tests/api_resources/devices/test_esim.py +++ b/tests/api_resources/devices/test_esim.py @@ -11,7 +11,6 @@ from mobilerun_sdk import Mobilerun, AsyncMobilerun from mobilerun_sdk.types.devices import ( EsimListResponse, - EsimStatusResponse, EsimActivateResponse, ) @@ -247,113 +246,6 @@ def test_path_params_remove(self, client: Mobilerun) -> None: sub_id=0, ) - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_set_roaming(self, client: Mobilerun) -> None: - esim = client.devices.esim.set_roaming( - device_id="deviceId", - enabled=True, - ) - assert esim is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_set_roaming_with_all_params(self, client: Mobilerun) -> None: - esim = client.devices.esim.set_roaming( - device_id="deviceId", - enabled=True, - x_device_display_id=0, - ) - assert esim is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_set_roaming(self, client: Mobilerun) -> None: - response = client.devices.esim.with_raw_response.set_roaming( - device_id="deviceId", - enabled=True, - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - esim = response.parse() - assert esim is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_set_roaming(self, client: Mobilerun) -> None: - with client.devices.esim.with_streaming_response.set_roaming( - device_id="deviceId", - enabled=True, - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - esim = response.parse() - assert esim is None - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_set_roaming(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `device_id` but received ''"): - client.devices.esim.with_raw_response.set_roaming( - device_id="", - enabled=True, - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_status(self, client: Mobilerun) -> None: - esim = client.devices.esim.status( - device_id="deviceId", - ) - assert_matches_type(Optional[EsimStatusResponse], esim, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_status_with_all_params(self, client: Mobilerun) -> None: - esim = client.devices.esim.status( - device_id="deviceId", - x_device_display_id=0, - ) - assert_matches_type(Optional[EsimStatusResponse], esim, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_status(self, client: Mobilerun) -> None: - response = client.devices.esim.with_raw_response.status( - device_id="deviceId", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - esim = response.parse() - assert_matches_type(Optional[EsimStatusResponse], esim, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_status(self, client: Mobilerun) -> None: - with client.devices.esim.with_streaming_response.status( - device_id="deviceId", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - esim = response.parse() - assert_matches_type(Optional[EsimStatusResponse], esim, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_path_params_status(self, client: Mobilerun) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `device_id` but received ''"): - client.devices.esim.with_raw_response.status( - device_id="", - ) - class TestAsyncEsim: parametrize = pytest.mark.parametrize( @@ -585,110 +477,3 @@ async def test_path_params_remove(self, async_client: AsyncMobilerun) -> None: device_id="", sub_id=0, ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_set_roaming(self, async_client: AsyncMobilerun) -> None: - esim = await async_client.devices.esim.set_roaming( - device_id="deviceId", - enabled=True, - ) - assert esim is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_set_roaming_with_all_params(self, async_client: AsyncMobilerun) -> None: - esim = await async_client.devices.esim.set_roaming( - device_id="deviceId", - enabled=True, - x_device_display_id=0, - ) - assert esim is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_set_roaming(self, async_client: AsyncMobilerun) -> None: - response = await async_client.devices.esim.with_raw_response.set_roaming( - device_id="deviceId", - enabled=True, - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - esim = await response.parse() - assert esim is None - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_set_roaming(self, async_client: AsyncMobilerun) -> None: - async with async_client.devices.esim.with_streaming_response.set_roaming( - device_id="deviceId", - enabled=True, - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - esim = await response.parse() - assert esim is None - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_set_roaming(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.esim.with_raw_response.set_roaming( - device_id="", - enabled=True, - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_status(self, async_client: AsyncMobilerun) -> None: - esim = await async_client.devices.esim.status( - device_id="deviceId", - ) - assert_matches_type(Optional[EsimStatusResponse], esim, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_status_with_all_params(self, async_client: AsyncMobilerun) -> None: - esim = await async_client.devices.esim.status( - device_id="deviceId", - x_device_display_id=0, - ) - assert_matches_type(Optional[EsimStatusResponse], esim, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_status(self, async_client: AsyncMobilerun) -> None: - response = await async_client.devices.esim.with_raw_response.status( - device_id="deviceId", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - esim = await response.parse() - assert_matches_type(Optional[EsimStatusResponse], esim, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_status(self, async_client: AsyncMobilerun) -> None: - async with async_client.devices.esim.with_streaming_response.status( - device_id="deviceId", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - esim = await response.parse() - assert_matches_type(Optional[EsimStatusResponse], esim, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_path_params_status(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.esim.with_raw_response.status( - device_id="", - ) diff --git a/tests/api_resources/test_agents.py b/tests/api_resources/test_agents.py deleted file mode 100644 index 8087dea..0000000 --- a/tests/api_resources/test_agents.py +++ /dev/null @@ -1,80 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from tests.utils import assert_matches_type -from mobilerun_sdk import Mobilerun, AsyncMobilerun -from mobilerun_sdk.types import AgentListResponse - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestAgents: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_list(self, client: Mobilerun) -> None: - agent = client.agents.list() - assert_matches_type(AgentListResponse, agent, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_list(self, client: Mobilerun) -> None: - response = client.agents.with_raw_response.list() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - agent = response.parse() - assert_matches_type(AgentListResponse, agent, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_list(self, client: Mobilerun) -> None: - with client.agents.with_streaming_response.list() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - agent = response.parse() - assert_matches_type(AgentListResponse, agent, path=["response"]) - - assert cast(Any, response.is_closed) is True - - -class TestAsyncAgents: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_list(self, async_client: AsyncMobilerun) -> None: - agent = await async_client.agents.list() - assert_matches_type(AgentListResponse, agent, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: - response = await async_client.agents.with_raw_response.list() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - agent = await response.parse() - assert_matches_type(AgentListResponse, agent, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: - async with async_client.agents.with_streaming_response.list() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - agent = await response.parse() - assert_matches_type(AgentListResponse, agent, path=["response"]) - - assert cast(Any, response.is_closed) is True From 785695138d9ad132ef6ea86802c6b26d89ed9337 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 09:09:22 +0000 Subject: [PATCH 19/21] feat(api): mobilerun connect endpoints --- .stats.yml | 6 +- api.md | 60 ++ src/mobilerun_sdk/_client.py | 38 + src/mobilerun_sdk/resources/__init__.py | 14 + .../resources/connect/__init__.py | 61 ++ .../resources/connect/connect.py | 166 ++++ .../resources/connect/countries.py | 201 ++++ .../resources/connect/proxies.py | 849 +++++++++++++++++ src/mobilerun_sdk/resources/connect/users.py | 869 ++++++++++++++++++ src/mobilerun_sdk/types/connect/__init__.py | 23 + .../types/connect/country_list_params.py | 20 + .../types/connect/country_list_response.py | 51 + .../types/connect/proxy_buy_params.py | 14 + .../types/connect/proxy_buy_response.py | 48 + .../connect/proxy_list_connections_params.py | 101 ++ .../proxy_list_connections_response.py | 106 +++ .../types/connect/proxy_list_params.py | 20 + .../types/connect/proxy_list_response.py | 71 ++ .../types/connect/proxy_ping_response.py | 50 + .../types/connect/proxy_retrieve_response.py | 48 + .../types/connect/user_create_params.py | 20 + .../types/connect/user_create_response.py | 28 + .../connect/user_list_connections_params.py | 101 ++ .../connect/user_list_connections_response.py | 106 +++ .../types/connect/user_list_params.py | 23 + .../types/connect/user_list_response.py | 54 ++ .../types/connect/user_retrieve_response.py | 28 + .../types/connect/user_update_params.py | 19 + .../types/connect/user_update_response.py | 23 + tests/api_resources/connect/__init__.py | 1 + tests/api_resources/connect/test_countries.py | 100 ++ tests/api_resources/connect/test_proxies.py | 595 ++++++++++++ tests/api_resources/connect/test_users.py | 603 ++++++++++++ 33 files changed, 4514 insertions(+), 3 deletions(-) create mode 100644 src/mobilerun_sdk/resources/connect/__init__.py create mode 100644 src/mobilerun_sdk/resources/connect/connect.py create mode 100644 src/mobilerun_sdk/resources/connect/countries.py create mode 100644 src/mobilerun_sdk/resources/connect/proxies.py create mode 100644 src/mobilerun_sdk/resources/connect/users.py create mode 100644 src/mobilerun_sdk/types/connect/__init__.py create mode 100644 src/mobilerun_sdk/types/connect/country_list_params.py create mode 100644 src/mobilerun_sdk/types/connect/country_list_response.py create mode 100644 src/mobilerun_sdk/types/connect/proxy_buy_params.py create mode 100644 src/mobilerun_sdk/types/connect/proxy_buy_response.py create mode 100644 src/mobilerun_sdk/types/connect/proxy_list_connections_params.py create mode 100644 src/mobilerun_sdk/types/connect/proxy_list_connections_response.py create mode 100644 src/mobilerun_sdk/types/connect/proxy_list_params.py create mode 100644 src/mobilerun_sdk/types/connect/proxy_list_response.py create mode 100644 src/mobilerun_sdk/types/connect/proxy_ping_response.py create mode 100644 src/mobilerun_sdk/types/connect/proxy_retrieve_response.py create mode 100644 src/mobilerun_sdk/types/connect/user_create_params.py create mode 100644 src/mobilerun_sdk/types/connect/user_create_response.py create mode 100644 src/mobilerun_sdk/types/connect/user_list_connections_params.py create mode 100644 src/mobilerun_sdk/types/connect/user_list_connections_response.py create mode 100644 src/mobilerun_sdk/types/connect/user_list_params.py create mode 100644 src/mobilerun_sdk/types/connect/user_list_response.py create mode 100644 src/mobilerun_sdk/types/connect/user_retrieve_response.py create mode 100644 src/mobilerun_sdk/types/connect/user_update_params.py create mode 100644 src/mobilerun_sdk/types/connect/user_update_response.py create mode 100644 tests/api_resources/connect/__init__.py create mode 100644 tests/api_resources/connect/test_countries.py create mode 100644 tests/api_resources/connect/test_proxies.py create mode 100644 tests/api_resources/connect/test_users.py diff --git a/.stats.yml b/.stats.yml index 46ffba2..d21fd02 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 153 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-08d5ad550dedf6fec547fd6b259a1b04ab6876041c9e3ad31603b4eb50234181.yml +configured_endpoints: 166 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-af0cf78a9ffb5f93cb988ae03eb409a9810d24056f193d48d7b8394c2ffa398f.yml openapi_spec_hash: 29b62d198d5699a230afd5397359cecb -config_hash: 5fba7bd3d1df1eac603dcfee428f8d1c +config_hash: 7eee71321886b0cd05bdbd017f9d06ec diff --git a/api.md b/api.md index 6bae274..6511b2d 100644 --- a/api.md +++ b/api.md @@ -482,6 +482,66 @@ Methods: - client.proxies.delete(proxy_id) -> ProxyDeleteResponse - client.proxies.lookup(\*\*params) -> ProxyLookupResponse +# Connect + +## Countries + +Types: + +```python +from mobilerun_sdk.types.connect import CountryListResponse +``` + +Methods: + +- client.connect.countries.list(\*\*params) -> CountryListResponse + +## Proxies + +Types: + +```python +from mobilerun_sdk.types.connect import ( + ProxyRetrieveResponse, + ProxyListResponse, + ProxyBuyResponse, + ProxyListConnectionsResponse, + ProxyPingResponse, +) +``` + +Methods: + +- client.connect.proxies.retrieve(id) -> ProxyRetrieveResponse +- client.connect.proxies.list(\*\*params) -> ProxyListResponse +- client.connect.proxies.buy(\*\*params) -> ProxyBuyResponse +- client.connect.proxies.cancel(id) -> None +- client.connect.proxies.list_connections(id, \*\*params) -> ProxyListConnectionsResponse +- client.connect.proxies.ping(id) -> ProxyPingResponse + +## Users + +Types: + +```python +from mobilerun_sdk.types.connect import ( + UserCreateResponse, + UserRetrieveResponse, + UserUpdateResponse, + UserListResponse, + UserListConnectionsResponse, +) +``` + +Methods: + +- client.connect.users.create(\*\*params) -> UserCreateResponse +- client.connect.users.retrieve(id) -> UserRetrieveResponse +- client.connect.users.update(id, \*\*params) -> UserUpdateResponse +- client.connect.users.list(\*\*params) -> UserListResponse +- client.connect.users.delete(id) -> None +- client.connect.users.list_connections(id, \*\*params) -> UserListConnectionsResponse + # Tasks Types: diff --git a/src/mobilerun_sdk/_client.py b/src/mobilerun_sdk/_client.py index 569a208..152574a 100644 --- a/src/mobilerun_sdk/_client.py +++ b/src/mobilerun_sdk/_client.py @@ -42,6 +42,7 @@ tasks, agents, models, + connect, devices, proxies, carriers, @@ -57,6 +58,7 @@ from .resources.profiles import ProfilesResource, AsyncProfilesResource from .resources.tasks.tasks import TasksResource, AsyncTasksResource from .resources.agents.agents import AgentsResource, AsyncAgentsResource + from .resources.connect.connect import ConnectResource, AsyncConnectResource from .resources.devices.devices import DevicesResource, AsyncDevicesResource from .resources.workflows.workflows import WorkflowsResource, AsyncWorkflowsResource from .resources.credentials.credentials import CredentialsResource, AsyncCredentialsResource @@ -192,6 +194,12 @@ def proxies(self) -> ProxiesResource: return ProxiesResource(self) + @cached_property + def connect(self) -> ConnectResource: + from .resources.connect import ConnectResource + + return ConnectResource(self) + @cached_property def tasks(self) -> TasksResource: """Tasks API""" @@ -448,6 +456,12 @@ def proxies(self) -> AsyncProxiesResource: return AsyncProxiesResource(self) + @cached_property + def connect(self) -> AsyncConnectResource: + from .resources.connect import AsyncConnectResource + + return AsyncConnectResource(self) + @cached_property def tasks(self) -> AsyncTasksResource: """Tasks API""" @@ -650,6 +664,12 @@ def proxies(self) -> proxies.ProxiesResourceWithRawResponse: return ProxiesResourceWithRawResponse(self._client.proxies) + @cached_property + def connect(self) -> connect.ConnectResourceWithRawResponse: + from .resources.connect import ConnectResourceWithRawResponse + + return ConnectResourceWithRawResponse(self._client.connect) + @cached_property def tasks(self) -> tasks.TasksResourceWithRawResponse: """Tasks API""" @@ -729,6 +749,12 @@ def proxies(self) -> proxies.AsyncProxiesResourceWithRawResponse: return AsyncProxiesResourceWithRawResponse(self._client.proxies) + @cached_property + def connect(self) -> connect.AsyncConnectResourceWithRawResponse: + from .resources.connect import AsyncConnectResourceWithRawResponse + + return AsyncConnectResourceWithRawResponse(self._client.connect) + @cached_property def tasks(self) -> tasks.AsyncTasksResourceWithRawResponse: """Tasks API""" @@ -808,6 +834,12 @@ def proxies(self) -> proxies.ProxiesResourceWithStreamingResponse: return ProxiesResourceWithStreamingResponse(self._client.proxies) + @cached_property + def connect(self) -> connect.ConnectResourceWithStreamingResponse: + from .resources.connect import ConnectResourceWithStreamingResponse + + return ConnectResourceWithStreamingResponse(self._client.connect) + @cached_property def tasks(self) -> tasks.TasksResourceWithStreamingResponse: """Tasks API""" @@ -887,6 +919,12 @@ def proxies(self) -> proxies.AsyncProxiesResourceWithStreamingResponse: return AsyncProxiesResourceWithStreamingResponse(self._client.proxies) + @cached_property + def connect(self) -> connect.AsyncConnectResourceWithStreamingResponse: + from .resources.connect import AsyncConnectResourceWithStreamingResponse + + return AsyncConnectResourceWithStreamingResponse(self._client.connect) + @cached_property def tasks(self) -> tasks.AsyncTasksResourceWithStreamingResponse: """Tasks API""" diff --git a/src/mobilerun_sdk/resources/__init__.py b/src/mobilerun_sdk/resources/__init__.py index 39e06ee..c28ea9f 100644 --- a/src/mobilerun_sdk/resources/__init__.py +++ b/src/mobilerun_sdk/resources/__init__.py @@ -40,6 +40,14 @@ ModelsResourceWithStreamingResponse, AsyncModelsResourceWithStreamingResponse, ) +from .connect import ( + ConnectResource, + AsyncConnectResource, + ConnectResourceWithRawResponse, + AsyncConnectResourceWithRawResponse, + ConnectResourceWithStreamingResponse, + AsyncConnectResourceWithStreamingResponse, +) from .devices import ( DevicesResource, AsyncDevicesResource, @@ -144,6 +152,12 @@ "AsyncProxiesResourceWithRawResponse", "ProxiesResourceWithStreamingResponse", "AsyncProxiesResourceWithStreamingResponse", + "ConnectResource", + "AsyncConnectResource", + "ConnectResourceWithRawResponse", + "AsyncConnectResourceWithRawResponse", + "ConnectResourceWithStreamingResponse", + "AsyncConnectResourceWithStreamingResponse", "TasksResource", "AsyncTasksResource", "TasksResourceWithRawResponse", diff --git a/src/mobilerun_sdk/resources/connect/__init__.py b/src/mobilerun_sdk/resources/connect/__init__.py new file mode 100644 index 0000000..65fca6b --- /dev/null +++ b/src/mobilerun_sdk/resources/connect/__init__.py @@ -0,0 +1,61 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .users import ( + UsersResource, + AsyncUsersResource, + UsersResourceWithRawResponse, + AsyncUsersResourceWithRawResponse, + UsersResourceWithStreamingResponse, + AsyncUsersResourceWithStreamingResponse, +) +from .connect import ( + ConnectResource, + AsyncConnectResource, + ConnectResourceWithRawResponse, + AsyncConnectResourceWithRawResponse, + ConnectResourceWithStreamingResponse, + AsyncConnectResourceWithStreamingResponse, +) +from .proxies import ( + ProxiesResource, + AsyncProxiesResource, + ProxiesResourceWithRawResponse, + AsyncProxiesResourceWithRawResponse, + ProxiesResourceWithStreamingResponse, + AsyncProxiesResourceWithStreamingResponse, +) +from .countries import ( + CountriesResource, + AsyncCountriesResource, + CountriesResourceWithRawResponse, + AsyncCountriesResourceWithRawResponse, + CountriesResourceWithStreamingResponse, + AsyncCountriesResourceWithStreamingResponse, +) + +__all__ = [ + "CountriesResource", + "AsyncCountriesResource", + "CountriesResourceWithRawResponse", + "AsyncCountriesResourceWithRawResponse", + "CountriesResourceWithStreamingResponse", + "AsyncCountriesResourceWithStreamingResponse", + "ProxiesResource", + "AsyncProxiesResource", + "ProxiesResourceWithRawResponse", + "AsyncProxiesResourceWithRawResponse", + "ProxiesResourceWithStreamingResponse", + "AsyncProxiesResourceWithStreamingResponse", + "UsersResource", + "AsyncUsersResource", + "UsersResourceWithRawResponse", + "AsyncUsersResourceWithRawResponse", + "UsersResourceWithStreamingResponse", + "AsyncUsersResourceWithStreamingResponse", + "ConnectResource", + "AsyncConnectResource", + "ConnectResourceWithRawResponse", + "AsyncConnectResourceWithRawResponse", + "ConnectResourceWithStreamingResponse", + "AsyncConnectResourceWithStreamingResponse", +] diff --git a/src/mobilerun_sdk/resources/connect/connect.py b/src/mobilerun_sdk/resources/connect/connect.py new file mode 100644 index 0000000..67c2d65 --- /dev/null +++ b/src/mobilerun_sdk/resources/connect/connect.py @@ -0,0 +1,166 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .users import ( + UsersResource, + AsyncUsersResource, + UsersResourceWithRawResponse, + AsyncUsersResourceWithRawResponse, + UsersResourceWithStreamingResponse, + AsyncUsersResourceWithStreamingResponse, +) +from .proxies import ( + ProxiesResource, + AsyncProxiesResource, + ProxiesResourceWithRawResponse, + AsyncProxiesResourceWithRawResponse, + ProxiesResourceWithStreamingResponse, + AsyncProxiesResourceWithStreamingResponse, +) +from ..._compat import cached_property +from .countries import ( + CountriesResource, + AsyncCountriesResource, + CountriesResourceWithRawResponse, + AsyncCountriesResourceWithRawResponse, + CountriesResourceWithStreamingResponse, + AsyncCountriesResourceWithStreamingResponse, +) +from ..._resource import SyncAPIResource, AsyncAPIResource + +__all__ = ["ConnectResource", "AsyncConnectResource"] + + +class ConnectResource(SyncAPIResource): + @cached_property + def countries(self) -> CountriesResource: + return CountriesResource(self._client) + + @cached_property + def proxies(self) -> ProxiesResource: + return ProxiesResource(self._client) + + @cached_property + def users(self) -> UsersResource: + return UsersResource(self._client) + + @cached_property + def with_raw_response(self) -> ConnectResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return ConnectResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ConnectResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return ConnectResourceWithStreamingResponse(self) + + +class AsyncConnectResource(AsyncAPIResource): + @cached_property + def countries(self) -> AsyncCountriesResource: + return AsyncCountriesResource(self._client) + + @cached_property + def proxies(self) -> AsyncProxiesResource: + return AsyncProxiesResource(self._client) + + @cached_property + def users(self) -> AsyncUsersResource: + return AsyncUsersResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncConnectResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncConnectResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncConnectResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncConnectResourceWithStreamingResponse(self) + + +class ConnectResourceWithRawResponse: + def __init__(self, connect: ConnectResource) -> None: + self._connect = connect + + @cached_property + def countries(self) -> CountriesResourceWithRawResponse: + return CountriesResourceWithRawResponse(self._connect.countries) + + @cached_property + def proxies(self) -> ProxiesResourceWithRawResponse: + return ProxiesResourceWithRawResponse(self._connect.proxies) + + @cached_property + def users(self) -> UsersResourceWithRawResponse: + return UsersResourceWithRawResponse(self._connect.users) + + +class AsyncConnectResourceWithRawResponse: + def __init__(self, connect: AsyncConnectResource) -> None: + self._connect = connect + + @cached_property + def countries(self) -> AsyncCountriesResourceWithRawResponse: + return AsyncCountriesResourceWithRawResponse(self._connect.countries) + + @cached_property + def proxies(self) -> AsyncProxiesResourceWithRawResponse: + return AsyncProxiesResourceWithRawResponse(self._connect.proxies) + + @cached_property + def users(self) -> AsyncUsersResourceWithRawResponse: + return AsyncUsersResourceWithRawResponse(self._connect.users) + + +class ConnectResourceWithStreamingResponse: + def __init__(self, connect: ConnectResource) -> None: + self._connect = connect + + @cached_property + def countries(self) -> CountriesResourceWithStreamingResponse: + return CountriesResourceWithStreamingResponse(self._connect.countries) + + @cached_property + def proxies(self) -> ProxiesResourceWithStreamingResponse: + return ProxiesResourceWithStreamingResponse(self._connect.proxies) + + @cached_property + def users(self) -> UsersResourceWithStreamingResponse: + return UsersResourceWithStreamingResponse(self._connect.users) + + +class AsyncConnectResourceWithStreamingResponse: + def __init__(self, connect: AsyncConnectResource) -> None: + self._connect = connect + + @cached_property + def countries(self) -> AsyncCountriesResourceWithStreamingResponse: + return AsyncCountriesResourceWithStreamingResponse(self._connect.countries) + + @cached_property + def proxies(self) -> AsyncProxiesResourceWithStreamingResponse: + return AsyncProxiesResourceWithStreamingResponse(self._connect.proxies) + + @cached_property + def users(self) -> AsyncUsersResourceWithStreamingResponse: + return AsyncUsersResourceWithStreamingResponse(self._connect.users) diff --git a/src/mobilerun_sdk/resources/connect/countries.py b/src/mobilerun_sdk/resources/connect/countries.py new file mode 100644 index 0000000..d6d0bf0 --- /dev/null +++ b/src/mobilerun_sdk/resources/connect/countries.py @@ -0,0 +1,201 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal + +import httpx + +from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ..._utils import maybe_transform, async_maybe_transform +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._base_client import make_request_options +from ...types.connect import country_list_params +from ...types.connect.country_list_response import CountryListResponse + +__all__ = ["CountriesResource", "AsyncCountriesResource"] + + +class CountriesResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> CountriesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return CountriesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> CountriesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return CountriesResourceWithStreamingResponse(self) + + def list( + self, + *, + page: int | Omit = omit, + page_size: int | Omit = omit, + type: Literal["residential"] | 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, + ) -> CountryListResponse: + """ + Lookup of countries that can be selected when creating a proxy. + + Args: + page: Page number (1-based). + + page_size: Number of items per page. + + type: Filter to countries offering this proxy type. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get( + "/connect/countries", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "page_size": page_size, + "type": type, + }, + country_list_params.CountryListParams, + ), + ), + cast_to=CountryListResponse, + ) + + +class AsyncCountriesResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncCountriesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncCountriesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncCountriesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncCountriesResourceWithStreamingResponse(self) + + async def list( + self, + *, + page: int | Omit = omit, + page_size: int | Omit = omit, + type: Literal["residential"] | 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, + ) -> CountryListResponse: + """ + Lookup of countries that can be selected when creating a proxy. + + Args: + page: Page number (1-based). + + page_size: Number of items per page. + + type: Filter to countries offering this proxy type. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._get( + "/connect/countries", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "page": page, + "page_size": page_size, + "type": type, + }, + country_list_params.CountryListParams, + ), + ), + cast_to=CountryListResponse, + ) + + +class CountriesResourceWithRawResponse: + def __init__(self, countries: CountriesResource) -> None: + self._countries = countries + + self.list = to_raw_response_wrapper( + countries.list, + ) + + +class AsyncCountriesResourceWithRawResponse: + def __init__(self, countries: AsyncCountriesResource) -> None: + self._countries = countries + + self.list = async_to_raw_response_wrapper( + countries.list, + ) + + +class CountriesResourceWithStreamingResponse: + def __init__(self, countries: CountriesResource) -> None: + self._countries = countries + + self.list = to_streamed_response_wrapper( + countries.list, + ) + + +class AsyncCountriesResourceWithStreamingResponse: + def __init__(self, countries: AsyncCountriesResource) -> None: + self._countries = countries + + self.list = async_to_streamed_response_wrapper( + countries.list, + ) diff --git a/src/mobilerun_sdk/resources/connect/proxies.py b/src/mobilerun_sdk/resources/connect/proxies.py new file mode 100644 index 0000000..48d5db0 --- /dev/null +++ b/src/mobilerun_sdk/resources/connect/proxies.py @@ -0,0 +1,849 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime +from typing_extensions import Literal + +import httpx + +from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given +from ..._utils import path_template, maybe_transform, async_maybe_transform +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._base_client import make_request_options +from ...types.connect import proxy_buy_params, proxy_list_params, proxy_list_connections_params +from ...types.connect.proxy_buy_response import ProxyBuyResponse +from ...types.connect.proxy_list_response import ProxyListResponse +from ...types.connect.proxy_ping_response import ProxyPingResponse +from ...types.connect.proxy_retrieve_response import ProxyRetrieveResponse +from ...types.connect.proxy_list_connections_response import ProxyListConnectionsResponse + +__all__ = ["ProxiesResource", "AsyncProxiesResource"] + + +class ProxiesResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> ProxiesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return ProxiesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ProxiesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return ProxiesResourceWithStreamingResponse(self) + + def retrieve( + self, + id: str, + *, + # 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, + ) -> ProxyRetrieveResponse: + """ + Get a proxy by ID, including its password + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._get( + 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 + ), + cast_to=ProxyRetrieveResponse, + ) + + def list( + self, + *, + country: str | Omit = omit, + page: int | Omit = omit, + page_size: int | 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, + ) -> ProxyListResponse: + """ + Returns proxies owned by the user identified by the X-User-ID header. + Credentials are omitted from the list. + + Args: + country: Filter to proxies in this country (ISO 3166-1 alpha-2, lowercase). + + page: Page number (1-based). + + page_size: Number of items per page. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get( + "/connect/proxies", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "country": country, + "page": page, + "page_size": page_size, + }, + proxy_list_params.ProxyListParams, + ), + ), + cast_to=ProxyListResponse, + ) + + def buy( + self, + *, + country: str, + type: Literal["residential"] | 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, + ) -> ProxyBuyResponse: + """ + Provisions a proxy for the caller in the selected country. + + Args: + country: ISO 3166-1 alpha-2 country code to provision the proxy in. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/connect/proxies", + body=maybe_transform( + { + "country": country, + "type": type, + }, + proxy_buy_params.ProxyBuyParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ProxyBuyResponse, + ) + + def cancel( + self, + id: str, + *, + # 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, + ) -> None: + """ + Delete a proxy + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + 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 + ), + cast_to=NoneType, + ) + + def list_connections( + self, + id: str, + *, + close_reason: str | Omit = omit, + country: str | Omit = omit, + dst_host: str | Omit = omit, + dst_port: int | Omit = omit, + ended_after: Union[str, datetime] | Omit = omit, + ended_before: Union[str, datetime] | Omit = omit, + max_bytes_in: int | Omit = omit, + max_bytes_out: int | Omit = omit, + max_duration_ms: int | Omit = omit, + max_total_bytes: int | Omit = omit, + min_bytes_in: int | Omit = omit, + min_bytes_out: int | Omit = omit, + min_duration_ms: int | Omit = omit, + min_total_bytes: int | Omit = omit, + order: Literal["asc", "desc"] | Omit = omit, + order_by: Literal["startedAt", "endedAt", "bytesIn", "bytesOut", "totalBytes", "durationMs"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + protocol: Literal["tcp", "udp", "unknown"] | Omit = omit, + provider: str | Omit = omit, + session_id: str | Omit = omit, + started_after: Union[str, datetime] | Omit = omit, + started_before: Union[str, datetime] | Omit = omit, + status: Literal["active", "closed"] | Omit = omit, + user_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, + ) -> ProxyListConnectionsResponse: + """ + Returns the connection history recorded for this proxy, one item per connection + (aggregated across the connection's lifetime). Supports filtering on every + property plus ordering and pagination. Returns 503 when the connection-insights + backend is disabled or unreachable. + + Args: + close_reason: Filter to connections that closed with this reason (closed connections only). + + country: Filter to connections served from this upstream country (ISO 3166-1 alpha-2). + + dst_host: Filter to connections to this destination host (exact match). + + dst_port: Filter to connections to this destination port. + + ended_after: Filter to connections whose last activity was at or after this time (inclusive). + + ended_before: Filter to connections whose last activity was at or before this time + (inclusive). + + max_bytes_in: Filter to connections with at most this many bytes received from upstream. + + max_bytes_out: Filter to connections with at most this many bytes sent to upstream. + + max_duration_ms: Filter to connections lasting at most this many milliseconds. + + max_total_bytes: Filter to connections with at most this much total traffic (bytesIn + bytesOut). + + min_bytes_in: Filter to connections with at least this many bytes received from upstream. + + min_bytes_out: Filter to connections with at least this many bytes sent to upstream. + + min_duration_ms: Filter to connections lasting at least this many milliseconds. + + min_total_bytes: Filter to connections with at least this much total traffic (bytesIn + + bytesOut). + + order: Sort direction. + + order_by: Property to order the results by. + + page: Page number (1-based). + + page_size: Number of items per page. + + protocol: Filter to connections of this transport protocol. + + provider: Filter to connections served by this upstream provider. + + session_id: Filter to a single connection by its session id. + + started_after: Filter to connections that started at or after this time (inclusive). + + started_before: Filter to connections that started at or before this time (inclusive). + + status: Filter by connection status. + + user_id: Filter to connections made by this user. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._get( + path_template("/connect/proxies/{id}/connections", id=id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "close_reason": close_reason, + "country": country, + "dst_host": dst_host, + "dst_port": dst_port, + "ended_after": ended_after, + "ended_before": ended_before, + "max_bytes_in": max_bytes_in, + "max_bytes_out": max_bytes_out, + "max_duration_ms": max_duration_ms, + "max_total_bytes": max_total_bytes, + "min_bytes_in": min_bytes_in, + "min_bytes_out": min_bytes_out, + "min_duration_ms": min_duration_ms, + "min_total_bytes": min_total_bytes, + "order": order, + "order_by": order_by, + "page": page, + "page_size": page_size, + "protocol": protocol, + "provider": provider, + "session_id": session_id, + "started_after": started_after, + "started_before": started_before, + "status": status, + "user_id": user_id, + }, + proxy_list_connections_params.ProxyListConnectionsParams, + ), + ), + cast_to=ProxyListConnectionsResponse, + ) + + def ping( + self, + id: str, + *, + # 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, + ) -> ProxyPingResponse: + """ + Returns the most recent cached network-latency measurement for the proxy, + sampled periodically by connecting through the proxy to a fixed target. + `latency` is null when no measurement is available yet (e.g. the proxy is not + active, or it has not been sampled since coming online). + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._get( + path_template("/connect/proxies/{id}/ping", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ProxyPingResponse, + ) + + +class AsyncProxiesResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncProxiesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncProxiesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncProxiesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncProxiesResourceWithStreamingResponse(self) + + async def retrieve( + self, + id: str, + *, + # 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, + ) -> ProxyRetrieveResponse: + """ + Get a proxy by ID, including its password + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._get( + 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 + ), + cast_to=ProxyRetrieveResponse, + ) + + async def list( + self, + *, + country: str | Omit = omit, + page: int | Omit = omit, + page_size: int | 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, + ) -> ProxyListResponse: + """ + Returns proxies owned by the user identified by the X-User-ID header. + Credentials are omitted from the list. + + Args: + country: Filter to proxies in this country (ISO 3166-1 alpha-2, lowercase). + + page: Page number (1-based). + + page_size: Number of items per page. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._get( + "/connect/proxies", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "country": country, + "page": page, + "page_size": page_size, + }, + proxy_list_params.ProxyListParams, + ), + ), + cast_to=ProxyListResponse, + ) + + async def buy( + self, + *, + country: str, + type: Literal["residential"] | 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, + ) -> ProxyBuyResponse: + """ + Provisions a proxy for the caller in the selected country. + + Args: + country: ISO 3166-1 alpha-2 country code to provision the proxy in. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/connect/proxies", + body=await async_maybe_transform( + { + "country": country, + "type": type, + }, + proxy_buy_params.ProxyBuyParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ProxyBuyResponse, + ) + + async def cancel( + self, + id: str, + *, + # 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, + ) -> None: + """ + Delete a proxy + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + 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 + ), + cast_to=NoneType, + ) + + async def list_connections( + self, + id: str, + *, + close_reason: str | Omit = omit, + country: str | Omit = omit, + dst_host: str | Omit = omit, + dst_port: int | Omit = omit, + ended_after: Union[str, datetime] | Omit = omit, + ended_before: Union[str, datetime] | Omit = omit, + max_bytes_in: int | Omit = omit, + max_bytes_out: int | Omit = omit, + max_duration_ms: int | Omit = omit, + max_total_bytes: int | Omit = omit, + min_bytes_in: int | Omit = omit, + min_bytes_out: int | Omit = omit, + min_duration_ms: int | Omit = omit, + min_total_bytes: int | Omit = omit, + order: Literal["asc", "desc"] | Omit = omit, + order_by: Literal["startedAt", "endedAt", "bytesIn", "bytesOut", "totalBytes", "durationMs"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + protocol: Literal["tcp", "udp", "unknown"] | Omit = omit, + provider: str | Omit = omit, + session_id: str | Omit = omit, + started_after: Union[str, datetime] | Omit = omit, + started_before: Union[str, datetime] | Omit = omit, + status: Literal["active", "closed"] | Omit = omit, + user_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, + ) -> ProxyListConnectionsResponse: + """ + Returns the connection history recorded for this proxy, one item per connection + (aggregated across the connection's lifetime). Supports filtering on every + property plus ordering and pagination. Returns 503 when the connection-insights + backend is disabled or unreachable. + + Args: + close_reason: Filter to connections that closed with this reason (closed connections only). + + country: Filter to connections served from this upstream country (ISO 3166-1 alpha-2). + + dst_host: Filter to connections to this destination host (exact match). + + dst_port: Filter to connections to this destination port. + + ended_after: Filter to connections whose last activity was at or after this time (inclusive). + + ended_before: Filter to connections whose last activity was at or before this time + (inclusive). + + max_bytes_in: Filter to connections with at most this many bytes received from upstream. + + max_bytes_out: Filter to connections with at most this many bytes sent to upstream. + + max_duration_ms: Filter to connections lasting at most this many milliseconds. + + max_total_bytes: Filter to connections with at most this much total traffic (bytesIn + bytesOut). + + min_bytes_in: Filter to connections with at least this many bytes received from upstream. + + min_bytes_out: Filter to connections with at least this many bytes sent to upstream. + + min_duration_ms: Filter to connections lasting at least this many milliseconds. + + min_total_bytes: Filter to connections with at least this much total traffic (bytesIn + + bytesOut). + + order: Sort direction. + + order_by: Property to order the results by. + + page: Page number (1-based). + + page_size: Number of items per page. + + protocol: Filter to connections of this transport protocol. + + provider: Filter to connections served by this upstream provider. + + session_id: Filter to a single connection by its session id. + + started_after: Filter to connections that started at or after this time (inclusive). + + started_before: Filter to connections that started at or before this time (inclusive). + + status: Filter by connection status. + + user_id: Filter to connections made by this user. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._get( + path_template("/connect/proxies/{id}/connections", id=id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "close_reason": close_reason, + "country": country, + "dst_host": dst_host, + "dst_port": dst_port, + "ended_after": ended_after, + "ended_before": ended_before, + "max_bytes_in": max_bytes_in, + "max_bytes_out": max_bytes_out, + "max_duration_ms": max_duration_ms, + "max_total_bytes": max_total_bytes, + "min_bytes_in": min_bytes_in, + "min_bytes_out": min_bytes_out, + "min_duration_ms": min_duration_ms, + "min_total_bytes": min_total_bytes, + "order": order, + "order_by": order_by, + "page": page, + "page_size": page_size, + "protocol": protocol, + "provider": provider, + "session_id": session_id, + "started_after": started_after, + "started_before": started_before, + "status": status, + "user_id": user_id, + }, + proxy_list_connections_params.ProxyListConnectionsParams, + ), + ), + cast_to=ProxyListConnectionsResponse, + ) + + async def ping( + self, + id: str, + *, + # 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, + ) -> ProxyPingResponse: + """ + Returns the most recent cached network-latency measurement for the proxy, + sampled periodically by connecting through the proxy to a fixed target. + `latency` is null when no measurement is available yet (e.g. the proxy is not + active, or it has not been sampled since coming online). + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._get( + path_template("/connect/proxies/{id}/ping", id=id), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ProxyPingResponse, + ) + + +class ProxiesResourceWithRawResponse: + def __init__(self, proxies: ProxiesResource) -> None: + self._proxies = proxies + + self.retrieve = to_raw_response_wrapper( + proxies.retrieve, + ) + self.list = to_raw_response_wrapper( + proxies.list, + ) + self.buy = to_raw_response_wrapper( + proxies.buy, + ) + self.cancel = to_raw_response_wrapper( + proxies.cancel, + ) + self.list_connections = to_raw_response_wrapper( + proxies.list_connections, + ) + self.ping = to_raw_response_wrapper( + proxies.ping, + ) + + +class AsyncProxiesResourceWithRawResponse: + def __init__(self, proxies: AsyncProxiesResource) -> None: + self._proxies = proxies + + self.retrieve = async_to_raw_response_wrapper( + proxies.retrieve, + ) + self.list = async_to_raw_response_wrapper( + proxies.list, + ) + self.buy = async_to_raw_response_wrapper( + proxies.buy, + ) + self.cancel = async_to_raw_response_wrapper( + proxies.cancel, + ) + self.list_connections = async_to_raw_response_wrapper( + proxies.list_connections, + ) + self.ping = async_to_raw_response_wrapper( + proxies.ping, + ) + + +class ProxiesResourceWithStreamingResponse: + def __init__(self, proxies: ProxiesResource) -> None: + self._proxies = proxies + + self.retrieve = to_streamed_response_wrapper( + proxies.retrieve, + ) + self.list = to_streamed_response_wrapper( + proxies.list, + ) + self.buy = to_streamed_response_wrapper( + proxies.buy, + ) + self.cancel = to_streamed_response_wrapper( + proxies.cancel, + ) + self.list_connections = to_streamed_response_wrapper( + proxies.list_connections, + ) + self.ping = to_streamed_response_wrapper( + proxies.ping, + ) + + +class AsyncProxiesResourceWithStreamingResponse: + def __init__(self, proxies: AsyncProxiesResource) -> None: + self._proxies = proxies + + self.retrieve = async_to_streamed_response_wrapper( + proxies.retrieve, + ) + self.list = async_to_streamed_response_wrapper( + proxies.list, + ) + self.buy = async_to_streamed_response_wrapper( + proxies.buy, + ) + self.cancel = async_to_streamed_response_wrapper( + proxies.cancel, + ) + self.list_connections = async_to_streamed_response_wrapper( + proxies.list_connections, + ) + self.ping = async_to_streamed_response_wrapper( + proxies.ping, + ) diff --git a/src/mobilerun_sdk/resources/connect/users.py b/src/mobilerun_sdk/resources/connect/users.py new file mode 100644 index 0000000..9f7fa63 --- /dev/null +++ b/src/mobilerun_sdk/resources/connect/users.py @@ -0,0 +1,869 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union, Optional +from datetime import datetime +from typing_extensions import Literal + +import httpx + +from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given +from ..._utils import path_template, maybe_transform, async_maybe_transform +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..._base_client import make_request_options +from ...types.connect import user_list_params, user_create_params, user_update_params, user_list_connections_params +from ...types.connect.user_list_response import UserListResponse +from ...types.connect.user_create_response import UserCreateResponse +from ...types.connect.user_update_response import UserUpdateResponse +from ...types.connect.user_retrieve_response import UserRetrieveResponse +from ...types.connect.user_list_connections_response import UserListConnectionsResponse + +__all__ = ["UsersResource", "AsyncUsersResource"] + + +class UsersResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> UsersResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return UsersResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> UsersResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return UsersResourceWithStreamingResponse(self) + + def create( + self, + *, + password: str | Omit = omit, + proxy_id: str | Omit = omit, + username: 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, + ) -> UserCreateResponse: + """ + Creates a SOCKS5 credential, optionally bound to a proxy for dedicated routing. + Username and password are generated when omitted. + + Args: + password: Desired SOCKS5 password, 1-255 bytes (RFC 1929). Generated when omitted. + + proxy_id: Proxy to bind the user to for dedicated routing. + + username: Desired SOCKS5 username, 1-255 bytes (RFC 1929). Generated when omitted. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/connect/users", + body=maybe_transform( + { + "password": password, + "proxy_id": proxy_id, + "username": username, + }, + user_create_params.UserCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UserCreateResponse, + ) + + def retrieve( + self, + id: str, + *, + # 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, + ) -> UserRetrieveResponse: + """ + Get a SOCKS5 user by ID, including its password + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._get( + 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 + ), + cast_to=UserRetrieveResponse, + ) + + def update( + self, + id: str, + *, + proxy_id: Optional[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, + ) -> UserUpdateResponse: + """ + Rebind the user to a different proxy (or detach it by passing null). + + Args: + proxy_id: Proxy to rebind to, or null to detach. Omit to leave the user's current binding + unchanged — only an explicit null detaches. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._patch( + 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 + ), + cast_to=UserUpdateResponse, + ) + + def list( + self, + *, + page: int | Omit = omit, + page_size: int | Omit = omit, + proxy_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, + ) -> UserListResponse: + """Returns SOCKS5 users owned by the caller. + + Passwords are omitted from the list. + + Args: + page: Page number (1-based). + + page_size: Number of items per page. + + proxy_id: Filter to users bound to this proxy. Users not bound to it (including unbound + users) are excluded. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get( + "/connect/users", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "page": page, + "page_size": page_size, + "proxy_id": proxy_id, + }, + user_list_params.UserListParams, + ), + ), + cast_to=UserListResponse, + ) + + def delete( + self, + id: str, + *, + # 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, + ) -> None: + """ + Delete a SOCKS5 user + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + 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 + ), + cast_to=NoneType, + ) + + def list_connections( + self, + id: str, + *, + close_reason: str | Omit = omit, + country: str | Omit = omit, + dst_host: str | Omit = omit, + dst_port: int | Omit = omit, + ended_after: Union[str, datetime] | Omit = omit, + ended_before: Union[str, datetime] | Omit = omit, + max_bytes_in: int | Omit = omit, + max_bytes_out: int | Omit = omit, + max_duration_ms: int | Omit = omit, + max_total_bytes: int | Omit = omit, + min_bytes_in: int | Omit = omit, + min_bytes_out: int | Omit = omit, + min_duration_ms: int | Omit = omit, + min_total_bytes: int | Omit = omit, + order: Literal["asc", "desc"] | Omit = omit, + order_by: Literal["startedAt", "endedAt", "bytesIn", "bytesOut", "totalBytes", "durationMs"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + protocol: Literal["tcp", "udp", "unknown"] | Omit = omit, + provider: str | Omit = omit, + proxy_id: str | Omit = omit, + session_id: str | Omit = omit, + started_after: Union[str, datetime] | Omit = omit, + started_before: Union[str, datetime] | Omit = omit, + status: Literal["active", "closed"] | 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, + ) -> UserListConnectionsResponse: + """ + Returns the connection history recorded for this user, one item per connection + (aggregated across the connection's lifetime). Supports filtering on every + property plus ordering and pagination. Returns 503 when the connection-insights + backend is disabled or unreachable. + + Args: + close_reason: Filter to connections that closed with this reason (closed connections only). + + country: Filter to connections served from this upstream country (ISO 3166-1 alpha-2). + + dst_host: Filter to connections to this destination host (exact match). + + dst_port: Filter to connections to this destination port. + + ended_after: Filter to connections whose last activity was at or after this time (inclusive). + + ended_before: Filter to connections whose last activity was at or before this time + (inclusive). + + max_bytes_in: Filter to connections with at most this many bytes received from upstream. + + max_bytes_out: Filter to connections with at most this many bytes sent to upstream. + + max_duration_ms: Filter to connections lasting at most this many milliseconds. + + max_total_bytes: Filter to connections with at most this much total traffic (bytesIn + bytesOut). + + min_bytes_in: Filter to connections with at least this many bytes received from upstream. + + min_bytes_out: Filter to connections with at least this many bytes sent to upstream. + + min_duration_ms: Filter to connections lasting at least this many milliseconds. + + min_total_bytes: Filter to connections with at least this much total traffic (bytesIn + + bytesOut). + + order: Sort direction. + + order_by: Property to order the results by. + + page: Page number (1-based). + + page_size: Number of items per page. + + protocol: Filter to connections of this transport protocol. + + provider: Filter to connections served by this upstream provider. + + proxy_id: Filter to connections routed through this proxy. + + session_id: Filter to a single connection by its session id. + + started_after: Filter to connections that started at or after this time (inclusive). + + started_before: Filter to connections that started at or before this time (inclusive). + + status: Filter by connection status. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._get( + path_template("/connect/users/{id}/connections", id=id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "close_reason": close_reason, + "country": country, + "dst_host": dst_host, + "dst_port": dst_port, + "ended_after": ended_after, + "ended_before": ended_before, + "max_bytes_in": max_bytes_in, + "max_bytes_out": max_bytes_out, + "max_duration_ms": max_duration_ms, + "max_total_bytes": max_total_bytes, + "min_bytes_in": min_bytes_in, + "min_bytes_out": min_bytes_out, + "min_duration_ms": min_duration_ms, + "min_total_bytes": min_total_bytes, + "order": order, + "order_by": order_by, + "page": page, + "page_size": page_size, + "protocol": protocol, + "provider": provider, + "proxy_id": proxy_id, + "session_id": session_id, + "started_after": started_after, + "started_before": started_before, + "status": status, + }, + user_list_connections_params.UserListConnectionsParams, + ), + ), + cast_to=UserListConnectionsResponse, + ) + + +class AsyncUsersResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncUsersResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncUsersResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncUsersResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/droidrun/mobilerun-sdk-python#with_streaming_response + """ + return AsyncUsersResourceWithStreamingResponse(self) + + async def create( + self, + *, + password: str | Omit = omit, + proxy_id: str | Omit = omit, + username: 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, + ) -> UserCreateResponse: + """ + Creates a SOCKS5 credential, optionally bound to a proxy for dedicated routing. + Username and password are generated when omitted. + + Args: + password: Desired SOCKS5 password, 1-255 bytes (RFC 1929). Generated when omitted. + + proxy_id: Proxy to bind the user to for dedicated routing. + + username: Desired SOCKS5 username, 1-255 bytes (RFC 1929). Generated when omitted. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/connect/users", + body=await async_maybe_transform( + { + "password": password, + "proxy_id": proxy_id, + "username": username, + }, + user_create_params.UserCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UserCreateResponse, + ) + + async def retrieve( + self, + id: str, + *, + # 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, + ) -> UserRetrieveResponse: + """ + Get a SOCKS5 user by ID, including its password + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._get( + 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 + ), + cast_to=UserRetrieveResponse, + ) + + async def update( + self, + id: str, + *, + proxy_id: Optional[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, + ) -> UserUpdateResponse: + """ + Rebind the user to a different proxy (or detach it by passing null). + + Args: + proxy_id: Proxy to rebind to, or null to detach. Omit to leave the user's current binding + unchanged — only an explicit null detaches. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._patch( + 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 + ), + cast_to=UserUpdateResponse, + ) + + async def list( + self, + *, + page: int | Omit = omit, + page_size: int | Omit = omit, + proxy_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, + ) -> UserListResponse: + """Returns SOCKS5 users owned by the caller. + + Passwords are omitted from the list. + + Args: + page: Page number (1-based). + + page_size: Number of items per page. + + proxy_id: Filter to users bound to this proxy. Users not bound to it (including unbound + users) are excluded. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._get( + "/connect/users", + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "page": page, + "page_size": page_size, + "proxy_id": proxy_id, + }, + user_list_params.UserListParams, + ), + ), + cast_to=UserListResponse, + ) + + async def delete( + self, + id: str, + *, + # 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, + ) -> None: + """ + Delete a SOCKS5 user + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + extra_headers = {"Accept": "*/*", **(extra_headers or {})} + 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 + ), + cast_to=NoneType, + ) + + async def list_connections( + self, + id: str, + *, + close_reason: str | Omit = omit, + country: str | Omit = omit, + dst_host: str | Omit = omit, + dst_port: int | Omit = omit, + ended_after: Union[str, datetime] | Omit = omit, + ended_before: Union[str, datetime] | Omit = omit, + max_bytes_in: int | Omit = omit, + max_bytes_out: int | Omit = omit, + max_duration_ms: int | Omit = omit, + max_total_bytes: int | Omit = omit, + min_bytes_in: int | Omit = omit, + min_bytes_out: int | Omit = omit, + min_duration_ms: int | Omit = omit, + min_total_bytes: int | Omit = omit, + order: Literal["asc", "desc"] | Omit = omit, + order_by: Literal["startedAt", "endedAt", "bytesIn", "bytesOut", "totalBytes", "durationMs"] | Omit = omit, + page: int | Omit = omit, + page_size: int | Omit = omit, + protocol: Literal["tcp", "udp", "unknown"] | Omit = omit, + provider: str | Omit = omit, + proxy_id: str | Omit = omit, + session_id: str | Omit = omit, + started_after: Union[str, datetime] | Omit = omit, + started_before: Union[str, datetime] | Omit = omit, + status: Literal["active", "closed"] | 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, + ) -> UserListConnectionsResponse: + """ + Returns the connection history recorded for this user, one item per connection + (aggregated across the connection's lifetime). Supports filtering on every + property plus ordering and pagination. Returns 503 when the connection-insights + backend is disabled or unreachable. + + Args: + close_reason: Filter to connections that closed with this reason (closed connections only). + + country: Filter to connections served from this upstream country (ISO 3166-1 alpha-2). + + dst_host: Filter to connections to this destination host (exact match). + + dst_port: Filter to connections to this destination port. + + ended_after: Filter to connections whose last activity was at or after this time (inclusive). + + ended_before: Filter to connections whose last activity was at or before this time + (inclusive). + + max_bytes_in: Filter to connections with at most this many bytes received from upstream. + + max_bytes_out: Filter to connections with at most this many bytes sent to upstream. + + max_duration_ms: Filter to connections lasting at most this many milliseconds. + + max_total_bytes: Filter to connections with at most this much total traffic (bytesIn + bytesOut). + + min_bytes_in: Filter to connections with at least this many bytes received from upstream. + + min_bytes_out: Filter to connections with at least this many bytes sent to upstream. + + min_duration_ms: Filter to connections lasting at least this many milliseconds. + + min_total_bytes: Filter to connections with at least this much total traffic (bytesIn + + bytesOut). + + order: Sort direction. + + order_by: Property to order the results by. + + page: Page number (1-based). + + page_size: Number of items per page. + + protocol: Filter to connections of this transport protocol. + + provider: Filter to connections served by this upstream provider. + + proxy_id: Filter to connections routed through this proxy. + + session_id: Filter to a single connection by its session id. + + started_after: Filter to connections that started at or after this time (inclusive). + + started_before: Filter to connections that started at or before this time (inclusive). + + status: Filter by connection status. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._get( + path_template("/connect/users/{id}/connections", id=id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "close_reason": close_reason, + "country": country, + "dst_host": dst_host, + "dst_port": dst_port, + "ended_after": ended_after, + "ended_before": ended_before, + "max_bytes_in": max_bytes_in, + "max_bytes_out": max_bytes_out, + "max_duration_ms": max_duration_ms, + "max_total_bytes": max_total_bytes, + "min_bytes_in": min_bytes_in, + "min_bytes_out": min_bytes_out, + "min_duration_ms": min_duration_ms, + "min_total_bytes": min_total_bytes, + "order": order, + "order_by": order_by, + "page": page, + "page_size": page_size, + "protocol": protocol, + "provider": provider, + "proxy_id": proxy_id, + "session_id": session_id, + "started_after": started_after, + "started_before": started_before, + "status": status, + }, + user_list_connections_params.UserListConnectionsParams, + ), + ), + cast_to=UserListConnectionsResponse, + ) + + +class UsersResourceWithRawResponse: + def __init__(self, users: UsersResource) -> None: + self._users = users + + self.create = to_raw_response_wrapper( + users.create, + ) + self.retrieve = to_raw_response_wrapper( + users.retrieve, + ) + self.update = to_raw_response_wrapper( + users.update, + ) + self.list = to_raw_response_wrapper( + users.list, + ) + self.delete = to_raw_response_wrapper( + users.delete, + ) + self.list_connections = to_raw_response_wrapper( + users.list_connections, + ) + + +class AsyncUsersResourceWithRawResponse: + def __init__(self, users: AsyncUsersResource) -> None: + self._users = users + + self.create = async_to_raw_response_wrapper( + users.create, + ) + self.retrieve = async_to_raw_response_wrapper( + users.retrieve, + ) + self.update = async_to_raw_response_wrapper( + users.update, + ) + self.list = async_to_raw_response_wrapper( + users.list, + ) + self.delete = async_to_raw_response_wrapper( + users.delete, + ) + self.list_connections = async_to_raw_response_wrapper( + users.list_connections, + ) + + +class UsersResourceWithStreamingResponse: + def __init__(self, users: UsersResource) -> None: + self._users = users + + self.create = to_streamed_response_wrapper( + users.create, + ) + self.retrieve = to_streamed_response_wrapper( + users.retrieve, + ) + self.update = to_streamed_response_wrapper( + users.update, + ) + self.list = to_streamed_response_wrapper( + users.list, + ) + self.delete = to_streamed_response_wrapper( + users.delete, + ) + self.list_connections = to_streamed_response_wrapper( + users.list_connections, + ) + + +class AsyncUsersResourceWithStreamingResponse: + def __init__(self, users: AsyncUsersResource) -> None: + self._users = users + + self.create = async_to_streamed_response_wrapper( + users.create, + ) + self.retrieve = async_to_streamed_response_wrapper( + users.retrieve, + ) + self.update = async_to_streamed_response_wrapper( + users.update, + ) + self.list = async_to_streamed_response_wrapper( + users.list, + ) + self.delete = async_to_streamed_response_wrapper( + users.delete, + ) + self.list_connections = async_to_streamed_response_wrapper( + users.list_connections, + ) diff --git a/src/mobilerun_sdk/types/connect/__init__.py b/src/mobilerun_sdk/types/connect/__init__.py new file mode 100644 index 0000000..bc194ec --- /dev/null +++ b/src/mobilerun_sdk/types/connect/__init__.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .proxy_buy_params import ProxyBuyParams as ProxyBuyParams +from .user_list_params import UserListParams as UserListParams +from .proxy_list_params import ProxyListParams as ProxyListParams +from .proxy_buy_response import ProxyBuyResponse as ProxyBuyResponse +from .user_create_params import UserCreateParams as UserCreateParams +from .user_list_response import UserListResponse as UserListResponse +from .user_update_params import UserUpdateParams as UserUpdateParams +from .country_list_params import CountryListParams as CountryListParams +from .proxy_list_response import ProxyListResponse as ProxyListResponse +from .proxy_ping_response import ProxyPingResponse as ProxyPingResponse +from .user_create_response import UserCreateResponse as UserCreateResponse +from .user_update_response import UserUpdateResponse as UserUpdateResponse +from .country_list_response import CountryListResponse as CountryListResponse +from .user_retrieve_response import UserRetrieveResponse as UserRetrieveResponse +from .proxy_retrieve_response import ProxyRetrieveResponse as ProxyRetrieveResponse +from .user_list_connections_params import UserListConnectionsParams as UserListConnectionsParams +from .proxy_list_connections_params import ProxyListConnectionsParams as ProxyListConnectionsParams +from .user_list_connections_response import UserListConnectionsResponse as UserListConnectionsResponse +from .proxy_list_connections_response import ProxyListConnectionsResponse as ProxyListConnectionsResponse diff --git a/src/mobilerun_sdk/types/connect/country_list_params.py b/src/mobilerun_sdk/types/connect/country_list_params.py new file mode 100644 index 0000000..b3819a9 --- /dev/null +++ b/src/mobilerun_sdk/types/connect/country_list_params.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["CountryListParams"] + + +class CountryListParams(TypedDict, total=False): + page: int + """Page number (1-based).""" + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + """Number of items per page.""" + + type: Literal["residential"] + """Filter to countries offering this proxy type.""" diff --git a/src/mobilerun_sdk/types/connect/country_list_response.py b/src/mobilerun_sdk/types/connect/country_list_response.py new file mode 100644 index 0000000..cc2b650 --- /dev/null +++ b/src/mobilerun_sdk/types/connect/country_list_response.py @@ -0,0 +1,51 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["CountryListResponse", "Item", "Pagination"] + + +class Item(BaseModel): + code: str + """ISO 3166-1 alpha-2 country code (lowercase).""" + + name: str + + proxy_types: List[Literal["residential"]] = FieldInfo(alias="proxyTypes") + """Proxy types available to provision in this country.""" + + +class Pagination(BaseModel): + """Pagination metadata for a list response.""" + + has_next: bool = FieldInfo(alias="hasNext") + """Whether a next page exists.""" + + has_prev: bool = FieldInfo(alias="hasPrev") + """Whether a previous page exists.""" + + page: int + """Current page number (1-based).""" + + pages: int + """Total number of pages.""" + + page_size: int = FieldInfo(alias="pageSize") + """Number of items per page.""" + + total: int + """Total number of items across all pages.""" + + +class CountryListResponse(BaseModel): + """A page of countries.""" + + items: List[Item] + + pagination: Pagination + """Pagination metadata for a list response.""" diff --git a/src/mobilerun_sdk/types/connect/proxy_buy_params.py b/src/mobilerun_sdk/types/connect/proxy_buy_params.py new file mode 100644 index 0000000..77b9ded --- /dev/null +++ b/src/mobilerun_sdk/types/connect/proxy_buy_params.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["ProxyBuyParams"] + + +class ProxyBuyParams(TypedDict, total=False): + country: Required[str] + """ISO 3166-1 alpha-2 country code to provision the proxy in.""" + + type: Literal["residential"] diff --git a/src/mobilerun_sdk/types/connect/proxy_buy_response.py b/src/mobilerun_sdk/types/connect/proxy_buy_response.py new file mode 100644 index 0000000..52cf24d --- /dev/null +++ b/src/mobilerun_sdk/types/connect/proxy_buy_response.py @@ -0,0 +1,48 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["ProxyBuyResponse"] + + +class ProxyBuyResponse(BaseModel): + """A proxy including its password. Returned only on create and single-proxy reads.""" + + id: str + + country: str + """ISO 3166-1 alpha-2 country code (lowercase).""" + + created_at: datetime = FieldInfo(alias="createdAt") + + host: str + + password: str + + port: int + + status: Literal["pending_payment", "provisioning", "active", "cancelling", "ended", "error"] + """Lifecycle of a proxy. + + A freshly created proxy is `provisioning` — or `pending_payment` until the + customer completes checkout — and becomes `active` once its upstream is + assigned. `cancelling` retains full access through the paid period; when the + subscription expires the proxy is `ended`. `error` marks a failed provisioning + attempt. + """ + + type: Literal["residential"] + + username: str + + payment_url: Optional[str] = FieldInfo(alias="paymentUrl", default=None) + """Checkout URL to complete payment while status is `pending_payment`. + + Null once paid or when no payment was required. + """ diff --git a/src/mobilerun_sdk/types/connect/proxy_list_connections_params.py b/src/mobilerun_sdk/types/connect/proxy_list_connections_params.py new file mode 100644 index 0000000..f921bb2 --- /dev/null +++ b/src/mobilerun_sdk/types/connect/proxy_list_connections_params.py @@ -0,0 +1,101 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime +from typing_extensions import Literal, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["ProxyListConnectionsParams"] + + +class ProxyListConnectionsParams(TypedDict, total=False): + close_reason: Annotated[str, PropertyInfo(alias="closeReason")] + """Filter to connections that closed with this reason (closed connections only).""" + + country: str + """Filter to connections served from this upstream country (ISO 3166-1 alpha-2).""" + + dst_host: Annotated[str, PropertyInfo(alias="dstHost")] + """Filter to connections to this destination host (exact match).""" + + dst_port: Annotated[int, PropertyInfo(alias="dstPort")] + """Filter to connections to this destination port.""" + + ended_after: Annotated[Union[str, datetime], PropertyInfo(alias="endedAfter", format="iso8601")] + """ + Filter to connections whose last activity was at or after this time (inclusive). + """ + + ended_before: Annotated[Union[str, datetime], PropertyInfo(alias="endedBefore", format="iso8601")] + """ + Filter to connections whose last activity was at or before this time + (inclusive). + """ + + max_bytes_in: Annotated[int, PropertyInfo(alias="maxBytesIn")] + """Filter to connections with at most this many bytes received from upstream.""" + + max_bytes_out: Annotated[int, PropertyInfo(alias="maxBytesOut")] + """Filter to connections with at most this many bytes sent to upstream.""" + + max_duration_ms: Annotated[int, PropertyInfo(alias="maxDurationMs")] + """Filter to connections lasting at most this many milliseconds.""" + + max_total_bytes: Annotated[int, PropertyInfo(alias="maxTotalBytes")] + """ + Filter to connections with at most this much total traffic (bytesIn + bytesOut). + """ + + min_bytes_in: Annotated[int, PropertyInfo(alias="minBytesIn")] + """Filter to connections with at least this many bytes received from upstream.""" + + min_bytes_out: Annotated[int, PropertyInfo(alias="minBytesOut")] + """Filter to connections with at least this many bytes sent to upstream.""" + + min_duration_ms: Annotated[int, PropertyInfo(alias="minDurationMs")] + """Filter to connections lasting at least this many milliseconds.""" + + min_total_bytes: Annotated[int, PropertyInfo(alias="minTotalBytes")] + """ + Filter to connections with at least this much total traffic (bytesIn + + bytesOut). + """ + + order: Literal["asc", "desc"] + """Sort direction.""" + + order_by: Annotated[ + Literal["startedAt", "endedAt", "bytesIn", "bytesOut", "totalBytes", "durationMs"], + PropertyInfo(alias="orderBy"), + ] + """Property to order the results by.""" + + page: int + """Page number (1-based).""" + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + """Number of items per page.""" + + protocol: Literal["tcp", "udp", "unknown"] + """Filter to connections of this transport protocol.""" + + provider: str + """Filter to connections served by this upstream provider.""" + + session_id: Annotated[str, PropertyInfo(alias="sessionId")] + """Filter to a single connection by its session id.""" + + started_after: Annotated[Union[str, datetime], PropertyInfo(alias="startedAfter", format="iso8601")] + """Filter to connections that started at or after this time (inclusive).""" + + started_before: Annotated[Union[str, datetime], PropertyInfo(alias="startedBefore", format="iso8601")] + """Filter to connections that started at or before this time (inclusive).""" + + status: Literal["active", "closed"] + """Filter by connection status.""" + + user_id: Annotated[str, PropertyInfo(alias="userId")] + """Filter to connections made by this user.""" diff --git a/src/mobilerun_sdk/types/connect/proxy_list_connections_response.py b/src/mobilerun_sdk/types/connect/proxy_list_connections_response.py new file mode 100644 index 0000000..bf9a9c4 --- /dev/null +++ b/src/mobilerun_sdk/types/connect/proxy_list_connections_response.py @@ -0,0 +1,106 @@ +# 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__ = ["ProxyListConnectionsResponse", "Item", "Pagination"] + + +class Item(BaseModel): + """A single proxy connection, aggregated across its lifetime. + + Byte counts are totals for the whole connection. + """ + + bytes_in: int = FieldInfo(alias="bytesIn") + """Total bytes received from upstream over the connection's lifetime.""" + + bytes_out: int = FieldInfo(alias="bytesOut") + """Total bytes sent to upstream over the connection's lifetime.""" + + country: str + """Upstream country code (ISO 3166-1 alpha-2), or empty if unknown.""" + + dst_host: str = FieldInfo(alias="dstHost") + """Destination host the client connected to.""" + + dst_port: int = FieldInfo(alias="dstPort") + """Destination port the client connected to.""" + + duration_ms: int = FieldInfo(alias="durationMs") + """Elapsed time between startedAt and endedAt, in milliseconds.""" + + ended_at: datetime = FieldInfo(alias="endedAt") + """Time of the connection's last recorded activity (close time once closed).""" + + protocol: Literal["tcp", "udp", "unknown"] + """Transport protocol of a connection.""" + + provider: str + """Upstream provider that served the connection.""" + + proxy_id: str = FieldInfo(alias="proxyId") + """The proxy the connection was routed through. + + All-zero when the upstream was unresolved at capture time. + """ + + session_id: str = FieldInfo(alias="sessionId") + """Unique id of this connection.""" + + src_ip: str = FieldInfo(alias="srcIp") + """Client source IP address.""" + + started_at: datetime = FieldInfo(alias="startedAt") + """When the connection started.""" + + status: Literal["active", "closed"] + """ + `active` while the connection is still open (no terminal record yet); `closed` + once it has ended. + """ + + total_bytes: int = FieldInfo(alias="totalBytes") + """bytesIn + bytesOut.""" + + user_id: str = FieldInfo(alias="userId") + """The user that made the connection.""" + + close_reason: Optional[str] = FieldInfo(alias="closeReason", default=None) + """Why the connection closed; null while still active.""" + + +class Pagination(BaseModel): + """Pagination metadata for a list response.""" + + has_next: bool = FieldInfo(alias="hasNext") + """Whether a next page exists.""" + + has_prev: bool = FieldInfo(alias="hasPrev") + """Whether a previous page exists.""" + + page: int + """Current page number (1-based).""" + + pages: int + """Total number of pages.""" + + page_size: int = FieldInfo(alias="pageSize") + """Number of items per page.""" + + total: int + """Total number of items across all pages.""" + + +class ProxyListConnectionsResponse(BaseModel): + """A page of connections.""" + + items: List[Item] + + pagination: Pagination + """Pagination metadata for a list response.""" diff --git a/src/mobilerun_sdk/types/connect/proxy_list_params.py b/src/mobilerun_sdk/types/connect/proxy_list_params.py new file mode 100644 index 0000000..58dec10 --- /dev/null +++ b/src/mobilerun_sdk/types/connect/proxy_list_params.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["ProxyListParams"] + + +class ProxyListParams(TypedDict, total=False): + country: str + """Filter to proxies in this country (ISO 3166-1 alpha-2, lowercase).""" + + page: int + """Page number (1-based).""" + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + """Number of items per page.""" diff --git a/src/mobilerun_sdk/types/connect/proxy_list_response.py b/src/mobilerun_sdk/types/connect/proxy_list_response.py new file mode 100644 index 0000000..b46e7ec --- /dev/null +++ b/src/mobilerun_sdk/types/connect/proxy_list_response.py @@ -0,0 +1,71 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List +from datetime import datetime +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["ProxyListResponse", "Item", "Pagination"] + + +class Item(BaseModel): + """A provisioned proxy without its credentials.""" + + id: str + + country: str + """ISO 3166-1 alpha-2 country code (lowercase).""" + + created_at: datetime = FieldInfo(alias="createdAt") + + host: str + + port: int + + status: Literal["pending_payment", "provisioning", "active", "cancelling", "ended", "error"] + """Lifecycle of a proxy. + + A freshly created proxy is `provisioning` — or `pending_payment` until the + customer completes checkout — and becomes `active` once its upstream is + assigned. `cancelling` retains full access through the paid period; when the + subscription expires the proxy is `ended`. `error` marks a failed provisioning + attempt. + """ + + type: Literal["residential"] + + username: str + + +class Pagination(BaseModel): + """Pagination metadata for a list response.""" + + has_next: bool = FieldInfo(alias="hasNext") + """Whether a next page exists.""" + + has_prev: bool = FieldInfo(alias="hasPrev") + """Whether a previous page exists.""" + + page: int + """Current page number (1-based).""" + + pages: int + """Total number of pages.""" + + page_size: int = FieldInfo(alias="pageSize") + """Number of items per page.""" + + total: int + """Total number of items across all pages.""" + + +class ProxyListResponse(BaseModel): + """A page of proxies.""" + + items: List[Item] + + pagination: Pagination + """Pagination metadata for a list response.""" diff --git a/src/mobilerun_sdk/types/connect/proxy_ping_response.py b/src/mobilerun_sdk/types/connect/proxy_ping_response.py new file mode 100644 index 0000000..8ad5243 --- /dev/null +++ b/src/mobilerun_sdk/types/connect/proxy_ping_response.py @@ -0,0 +1,50 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["ProxyPingResponse", "Latency"] + + +class Latency(BaseModel): + """An aggregated latency measurement taken through the proxy.""" + + avg_ms: int = FieldInfo(alias="avgMs") + """Mean round-trip time over successful probes, in milliseconds.""" + + jitter_ms: int = FieldInfo(alias="jitterMs") + """Round-trip time spread (max - min) over successful probes, in milliseconds.""" + + max_ms: int = FieldInfo(alias="maxMs") + """Maximum round-trip time over successful probes, in milliseconds.""" + + measured_at: datetime = FieldInfo(alias="measuredAt") + """When this measurement was taken.""" + + min_ms: int = FieldInfo(alias="minMs") + """Minimum round-trip time over successful probes, in milliseconds.""" + + packet_loss: float = FieldInfo(alias="packetLoss") + """ + Fraction of probes that failed, 0..1 (1 means the proxy was unreachable; rtt + fields are 0). + """ + + samples: int + """Number of probes taken in this measurement.""" + + target: str + """The host:port the latency was measured against, through the proxy.""" + + +class ProxyPingResponse(BaseModel): + """The latest cached latency reading for a proxy.""" + + latency: Optional[Latency] = None + """An aggregated latency measurement taken through the proxy.""" + + proxy_id: str = FieldInfo(alias="proxyId") diff --git a/src/mobilerun_sdk/types/connect/proxy_retrieve_response.py b/src/mobilerun_sdk/types/connect/proxy_retrieve_response.py new file mode 100644 index 0000000..f594cb5 --- /dev/null +++ b/src/mobilerun_sdk/types/connect/proxy_retrieve_response.py @@ -0,0 +1,48 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["ProxyRetrieveResponse"] + + +class ProxyRetrieveResponse(BaseModel): + """A proxy including its password. Returned only on create and single-proxy reads.""" + + id: str + + country: str + """ISO 3166-1 alpha-2 country code (lowercase).""" + + created_at: datetime = FieldInfo(alias="createdAt") + + host: str + + password: str + + port: int + + status: Literal["pending_payment", "provisioning", "active", "cancelling", "ended", "error"] + """Lifecycle of a proxy. + + A freshly created proxy is `provisioning` — or `pending_payment` until the + customer completes checkout — and becomes `active` once its upstream is + assigned. `cancelling` retains full access through the paid period; when the + subscription expires the proxy is `ended`. `error` marks a failed provisioning + attempt. + """ + + type: Literal["residential"] + + username: str + + payment_url: Optional[str] = FieldInfo(alias="paymentUrl", default=None) + """Checkout URL to complete payment while status is `pending_payment`. + + Null once paid or when no payment was required. + """ diff --git a/src/mobilerun_sdk/types/connect/user_create_params.py b/src/mobilerun_sdk/types/connect/user_create_params.py new file mode 100644 index 0000000..c8b7f59 --- /dev/null +++ b/src/mobilerun_sdk/types/connect/user_create_params.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["UserCreateParams"] + + +class UserCreateParams(TypedDict, total=False): + password: str + """Desired SOCKS5 password, 1-255 bytes (RFC 1929). Generated when omitted.""" + + proxy_id: Annotated[str, PropertyInfo(alias="proxyId")] + """Proxy to bind the user to for dedicated routing.""" + + username: str + """Desired SOCKS5 username, 1-255 bytes (RFC 1929). Generated when omitted.""" diff --git a/src/mobilerun_sdk/types/connect/user_create_response.py b/src/mobilerun_sdk/types/connect/user_create_response.py new file mode 100644 index 0000000..6235ac3 --- /dev/null +++ b/src/mobilerun_sdk/types/connect/user_create_response.py @@ -0,0 +1,28 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["UserCreateResponse"] + + +class UserCreateResponse(BaseModel): + """A SOCKS5 user including its password. + + Returned only on create and single-user reads. + """ + + id: str + + created_at: datetime = FieldInfo(alias="createdAt") + + password: str + + username: str + + proxy_id: Optional[str] = FieldInfo(alias="proxyId", default=None) + """The proxy this user routes to (dedicated routing), or null if unbound.""" diff --git a/src/mobilerun_sdk/types/connect/user_list_connections_params.py b/src/mobilerun_sdk/types/connect/user_list_connections_params.py new file mode 100644 index 0000000..c8a242f --- /dev/null +++ b/src/mobilerun_sdk/types/connect/user_list_connections_params.py @@ -0,0 +1,101 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime +from typing_extensions import Literal, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["UserListConnectionsParams"] + + +class UserListConnectionsParams(TypedDict, total=False): + close_reason: Annotated[str, PropertyInfo(alias="closeReason")] + """Filter to connections that closed with this reason (closed connections only).""" + + country: str + """Filter to connections served from this upstream country (ISO 3166-1 alpha-2).""" + + dst_host: Annotated[str, PropertyInfo(alias="dstHost")] + """Filter to connections to this destination host (exact match).""" + + dst_port: Annotated[int, PropertyInfo(alias="dstPort")] + """Filter to connections to this destination port.""" + + ended_after: Annotated[Union[str, datetime], PropertyInfo(alias="endedAfter", format="iso8601")] + """ + Filter to connections whose last activity was at or after this time (inclusive). + """ + + ended_before: Annotated[Union[str, datetime], PropertyInfo(alias="endedBefore", format="iso8601")] + """ + Filter to connections whose last activity was at or before this time + (inclusive). + """ + + max_bytes_in: Annotated[int, PropertyInfo(alias="maxBytesIn")] + """Filter to connections with at most this many bytes received from upstream.""" + + max_bytes_out: Annotated[int, PropertyInfo(alias="maxBytesOut")] + """Filter to connections with at most this many bytes sent to upstream.""" + + max_duration_ms: Annotated[int, PropertyInfo(alias="maxDurationMs")] + """Filter to connections lasting at most this many milliseconds.""" + + max_total_bytes: Annotated[int, PropertyInfo(alias="maxTotalBytes")] + """ + Filter to connections with at most this much total traffic (bytesIn + bytesOut). + """ + + min_bytes_in: Annotated[int, PropertyInfo(alias="minBytesIn")] + """Filter to connections with at least this many bytes received from upstream.""" + + min_bytes_out: Annotated[int, PropertyInfo(alias="minBytesOut")] + """Filter to connections with at least this many bytes sent to upstream.""" + + min_duration_ms: Annotated[int, PropertyInfo(alias="minDurationMs")] + """Filter to connections lasting at least this many milliseconds.""" + + min_total_bytes: Annotated[int, PropertyInfo(alias="minTotalBytes")] + """ + Filter to connections with at least this much total traffic (bytesIn + + bytesOut). + """ + + order: Literal["asc", "desc"] + """Sort direction.""" + + order_by: Annotated[ + Literal["startedAt", "endedAt", "bytesIn", "bytesOut", "totalBytes", "durationMs"], + PropertyInfo(alias="orderBy"), + ] + """Property to order the results by.""" + + page: int + """Page number (1-based).""" + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + """Number of items per page.""" + + protocol: Literal["tcp", "udp", "unknown"] + """Filter to connections of this transport protocol.""" + + provider: str + """Filter to connections served by this upstream provider.""" + + proxy_id: Annotated[str, PropertyInfo(alias="proxyId")] + """Filter to connections routed through this proxy.""" + + session_id: Annotated[str, PropertyInfo(alias="sessionId")] + """Filter to a single connection by its session id.""" + + started_after: Annotated[Union[str, datetime], PropertyInfo(alias="startedAfter", format="iso8601")] + """Filter to connections that started at or after this time (inclusive).""" + + started_before: Annotated[Union[str, datetime], PropertyInfo(alias="startedBefore", format="iso8601")] + """Filter to connections that started at or before this time (inclusive).""" + + status: Literal["active", "closed"] + """Filter by connection status.""" diff --git a/src/mobilerun_sdk/types/connect/user_list_connections_response.py b/src/mobilerun_sdk/types/connect/user_list_connections_response.py new file mode 100644 index 0000000..cf0db91 --- /dev/null +++ b/src/mobilerun_sdk/types/connect/user_list_connections_response.py @@ -0,0 +1,106 @@ +# 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__ = ["UserListConnectionsResponse", "Item", "Pagination"] + + +class Item(BaseModel): + """A single proxy connection, aggregated across its lifetime. + + Byte counts are totals for the whole connection. + """ + + bytes_in: int = FieldInfo(alias="bytesIn") + """Total bytes received from upstream over the connection's lifetime.""" + + bytes_out: int = FieldInfo(alias="bytesOut") + """Total bytes sent to upstream over the connection's lifetime.""" + + country: str + """Upstream country code (ISO 3166-1 alpha-2), or empty if unknown.""" + + dst_host: str = FieldInfo(alias="dstHost") + """Destination host the client connected to.""" + + dst_port: int = FieldInfo(alias="dstPort") + """Destination port the client connected to.""" + + duration_ms: int = FieldInfo(alias="durationMs") + """Elapsed time between startedAt and endedAt, in milliseconds.""" + + ended_at: datetime = FieldInfo(alias="endedAt") + """Time of the connection's last recorded activity (close time once closed).""" + + protocol: Literal["tcp", "udp", "unknown"] + """Transport protocol of a connection.""" + + provider: str + """Upstream provider that served the connection.""" + + proxy_id: str = FieldInfo(alias="proxyId") + """The proxy the connection was routed through. + + All-zero when the upstream was unresolved at capture time. + """ + + session_id: str = FieldInfo(alias="sessionId") + """Unique id of this connection.""" + + src_ip: str = FieldInfo(alias="srcIp") + """Client source IP address.""" + + started_at: datetime = FieldInfo(alias="startedAt") + """When the connection started.""" + + status: Literal["active", "closed"] + """ + `active` while the connection is still open (no terminal record yet); `closed` + once it has ended. + """ + + total_bytes: int = FieldInfo(alias="totalBytes") + """bytesIn + bytesOut.""" + + user_id: str = FieldInfo(alias="userId") + """The user that made the connection.""" + + close_reason: Optional[str] = FieldInfo(alias="closeReason", default=None) + """Why the connection closed; null while still active.""" + + +class Pagination(BaseModel): + """Pagination metadata for a list response.""" + + has_next: bool = FieldInfo(alias="hasNext") + """Whether a next page exists.""" + + has_prev: bool = FieldInfo(alias="hasPrev") + """Whether a previous page exists.""" + + page: int + """Current page number (1-based).""" + + pages: int + """Total number of pages.""" + + page_size: int = FieldInfo(alias="pageSize") + """Number of items per page.""" + + total: int + """Total number of items across all pages.""" + + +class UserListConnectionsResponse(BaseModel): + """A page of connections.""" + + items: List[Item] + + pagination: Pagination + """Pagination metadata for a list response.""" diff --git a/src/mobilerun_sdk/types/connect/user_list_params.py b/src/mobilerun_sdk/types/connect/user_list_params.py new file mode 100644 index 0000000..1cd7523 --- /dev/null +++ b/src/mobilerun_sdk/types/connect/user_list_params.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["UserListParams"] + + +class UserListParams(TypedDict, total=False): + page: int + """Page number (1-based).""" + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + """Number of items per page.""" + + proxy_id: Annotated[str, PropertyInfo(alias="proxyId")] + """Filter to users bound to this proxy. + + Users not bound to it (including unbound users) are excluded. + """ diff --git a/src/mobilerun_sdk/types/connect/user_list_response.py b/src/mobilerun_sdk/types/connect/user_list_response.py new file mode 100644 index 0000000..2f42145 --- /dev/null +++ b/src/mobilerun_sdk/types/connect/user_list_response.py @@ -0,0 +1,54 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["UserListResponse", "Item", "Pagination"] + + +class Item(BaseModel): + """A SOCKS5 credential without its password.""" + + id: str + + created_at: datetime = FieldInfo(alias="createdAt") + + username: str + + proxy_id: Optional[str] = FieldInfo(alias="proxyId", default=None) + """The proxy this user routes to (dedicated routing), or null if unbound.""" + + +class Pagination(BaseModel): + """Pagination metadata for a list response.""" + + has_next: bool = FieldInfo(alias="hasNext") + """Whether a next page exists.""" + + has_prev: bool = FieldInfo(alias="hasPrev") + """Whether a previous page exists.""" + + page: int + """Current page number (1-based).""" + + pages: int + """Total number of pages.""" + + page_size: int = FieldInfo(alias="pageSize") + """Number of items per page.""" + + total: int + """Total number of items across all pages.""" + + +class UserListResponse(BaseModel): + """A page of SOCKS5 users.""" + + items: List[Item] + + pagination: Pagination + """Pagination metadata for a list response.""" diff --git a/src/mobilerun_sdk/types/connect/user_retrieve_response.py b/src/mobilerun_sdk/types/connect/user_retrieve_response.py new file mode 100644 index 0000000..0096215 --- /dev/null +++ b/src/mobilerun_sdk/types/connect/user_retrieve_response.py @@ -0,0 +1,28 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["UserRetrieveResponse"] + + +class UserRetrieveResponse(BaseModel): + """A SOCKS5 user including its password. + + Returned only on create and single-user reads. + """ + + id: str + + created_at: datetime = FieldInfo(alias="createdAt") + + password: str + + username: str + + proxy_id: Optional[str] = FieldInfo(alias="proxyId", default=None) + """The proxy this user routes to (dedicated routing), or null if unbound.""" diff --git a/src/mobilerun_sdk/types/connect/user_update_params.py b/src/mobilerun_sdk/types/connect/user_update_params.py new file mode 100644 index 0000000..b8a9f79 --- /dev/null +++ b/src/mobilerun_sdk/types/connect/user_update_params.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["UserUpdateParams"] + + +class UserUpdateParams(TypedDict, total=False): + proxy_id: Annotated[Optional[str], PropertyInfo(alias="proxyId")] + """Proxy to rebind to, or null to detach. + + Omit to leave the user's current binding unchanged — only an explicit null + detaches. + """ diff --git a/src/mobilerun_sdk/types/connect/user_update_response.py b/src/mobilerun_sdk/types/connect/user_update_response.py new file mode 100644 index 0000000..c2f0535 --- /dev/null +++ b/src/mobilerun_sdk/types/connect/user_update_response.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["UserUpdateResponse"] + + +class UserUpdateResponse(BaseModel): + """A SOCKS5 credential without its password.""" + + id: str + + created_at: datetime = FieldInfo(alias="createdAt") + + username: str + + proxy_id: Optional[str] = FieldInfo(alias="proxyId", default=None) + """The proxy this user routes to (dedicated routing), or null if unbound.""" diff --git a/tests/api_resources/connect/__init__.py b/tests/api_resources/connect/__init__.py new file mode 100644 index 0000000..fd8019a --- /dev/null +++ b/tests/api_resources/connect/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/connect/test_countries.py b/tests/api_resources/connect/test_countries.py new file mode 100644 index 0000000..e7d88fc --- /dev/null +++ b/tests/api_resources/connect/test_countries.py @@ -0,0 +1,100 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk.types.connect import CountryListResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestCountries: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + country = client.connect.countries.list() + assert_matches_type(CountryListResponse, country, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Mobilerun) -> None: + country = client.connect.countries.list( + page=1, + page_size=1, + type="residential", + ) + assert_matches_type(CountryListResponse, country, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.connect.countries.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + country = response.parse() + assert_matches_type(CountryListResponse, country, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.connect.countries.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + country = response.parse() + assert_matches_type(CountryListResponse, country, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncCountries: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + country = await async_client.connect.countries.list() + assert_matches_type(CountryListResponse, country, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: + country = await async_client.connect.countries.list( + page=1, + page_size=1, + type="residential", + ) + assert_matches_type(CountryListResponse, country, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.connect.countries.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + country = await response.parse() + assert_matches_type(CountryListResponse, country, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.connect.countries.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + country = await response.parse() + assert_matches_type(CountryListResponse, country, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/connect/test_proxies.py b/tests/api_resources/connect/test_proxies.py new file mode 100644 index 0000000..6442710 --- /dev/null +++ b/tests/api_resources/connect/test_proxies.py @@ -0,0 +1,595 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk._utils import parse_datetime +from mobilerun_sdk.types.connect import ( + ProxyBuyResponse, + ProxyListResponse, + ProxyPingResponse, + ProxyRetrieveResponse, + ProxyListConnectionsResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestProxies: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve(self, client: Mobilerun) -> None: + proxy = client.connect.proxies.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve(self, client: Mobilerun) -> None: + response = client.connect.proxies.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = response.parse() + assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve(self, client: Mobilerun) -> None: + with client.connect.proxies.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = response.parse() + assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_retrieve(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.connect.proxies.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + proxy = client.connect.proxies.list() + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Mobilerun) -> None: + proxy = client.connect.proxies.list( + country="country", + page=1, + page_size=1, + ) + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.connect.proxies.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = response.parse() + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.connect.proxies.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = response.parse() + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_buy(self, client: Mobilerun) -> None: + proxy = client.connect.proxies.buy( + country="country", + ) + assert_matches_type(ProxyBuyResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_buy_with_all_params(self, client: Mobilerun) -> None: + proxy = client.connect.proxies.buy( + country="country", + type="residential", + ) + assert_matches_type(ProxyBuyResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_buy(self, client: Mobilerun) -> None: + response = client.connect.proxies.with_raw_response.buy( + country="country", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = response.parse() + assert_matches_type(ProxyBuyResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_buy(self, client: Mobilerun) -> None: + with client.connect.proxies.with_streaming_response.buy( + country="country", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = response.parse() + assert_matches_type(ProxyBuyResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_cancel(self, client: Mobilerun) -> None: + proxy = client.connect.proxies.cancel( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert proxy is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_cancel(self, client: Mobilerun) -> None: + response = client.connect.proxies.with_raw_response.cancel( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = response.parse() + assert proxy is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_cancel(self, client: Mobilerun) -> None: + with client.connect.proxies.with_streaming_response.cancel( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = response.parse() + assert proxy is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_cancel(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.connect.proxies.with_raw_response.cancel( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_connections(self, client: Mobilerun) -> None: + proxy = client.connect.proxies.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ProxyListConnectionsResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_connections_with_all_params(self, client: Mobilerun) -> None: + proxy = client.connect.proxies.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + close_reason="closeReason", + country="country", + dst_host="dstHost", + dst_port=0, + ended_after=parse_datetime("2019-12-27T18:11:19.117Z"), + ended_before=parse_datetime("2019-12-27T18:11:19.117Z"), + max_bytes_in=0, + max_bytes_out=0, + max_duration_ms=0, + max_total_bytes=0, + min_bytes_in=0, + min_bytes_out=0, + min_duration_ms=0, + min_total_bytes=0, + order="asc", + order_by="startedAt", + page=1, + page_size=1, + protocol="tcp", + provider="provider", + session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + started_after=parse_datetime("2019-12-27T18:11:19.117Z"), + started_before=parse_datetime("2019-12-27T18:11:19.117Z"), + status="active", + user_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ProxyListConnectionsResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list_connections(self, client: Mobilerun) -> None: + response = client.connect.proxies.with_raw_response.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = response.parse() + assert_matches_type(ProxyListConnectionsResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list_connections(self, client: Mobilerun) -> None: + with client.connect.proxies.with_streaming_response.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = response.parse() + assert_matches_type(ProxyListConnectionsResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_list_connections(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.connect.proxies.with_raw_response.list_connections( + id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_ping(self, client: Mobilerun) -> None: + proxy = client.connect.proxies.ping( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ProxyPingResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_ping(self, client: Mobilerun) -> None: + response = client.connect.proxies.with_raw_response.ping( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = response.parse() + assert_matches_type(ProxyPingResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_ping(self, client: Mobilerun) -> None: + with client.connect.proxies.with_streaming_response.ping( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = response.parse() + assert_matches_type(ProxyPingResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_ping(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.connect.proxies.with_raw_response.ping( + "", + ) + + +class TestAsyncProxies: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.connect.proxies.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncMobilerun) -> None: + response = await async_client.connect.proxies.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = await response.parse() + assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncMobilerun) -> None: + async with async_client.connect.proxies.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = await response.parse() + assert_matches_type(ProxyRetrieveResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.connect.proxies.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.connect.proxies.list() + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.connect.proxies.list( + country="country", + page=1, + page_size=1, + ) + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.connect.proxies.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = await response.parse() + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.connect.proxies.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = await response.parse() + assert_matches_type(ProxyListResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_buy(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.connect.proxies.buy( + country="country", + ) + assert_matches_type(ProxyBuyResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_buy_with_all_params(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.connect.proxies.buy( + country="country", + type="residential", + ) + assert_matches_type(ProxyBuyResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_buy(self, async_client: AsyncMobilerun) -> None: + response = await async_client.connect.proxies.with_raw_response.buy( + country="country", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = await response.parse() + assert_matches_type(ProxyBuyResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_buy(self, async_client: AsyncMobilerun) -> None: + async with async_client.connect.proxies.with_streaming_response.buy( + country="country", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = await response.parse() + assert_matches_type(ProxyBuyResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_cancel(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.connect.proxies.cancel( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert proxy is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_cancel(self, async_client: AsyncMobilerun) -> None: + response = await async_client.connect.proxies.with_raw_response.cancel( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = await response.parse() + assert proxy is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_cancel(self, async_client: AsyncMobilerun) -> None: + async with async_client.connect.proxies.with_streaming_response.cancel( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = await response.parse() + assert proxy is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_cancel(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.connect.proxies.with_raw_response.cancel( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_connections(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.connect.proxies.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ProxyListConnectionsResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_connections_with_all_params(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.connect.proxies.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + close_reason="closeReason", + country="country", + dst_host="dstHost", + dst_port=0, + ended_after=parse_datetime("2019-12-27T18:11:19.117Z"), + ended_before=parse_datetime("2019-12-27T18:11:19.117Z"), + max_bytes_in=0, + max_bytes_out=0, + max_duration_ms=0, + max_total_bytes=0, + min_bytes_in=0, + min_bytes_out=0, + min_duration_ms=0, + min_total_bytes=0, + order="asc", + order_by="startedAt", + page=1, + page_size=1, + protocol="tcp", + provider="provider", + session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + started_after=parse_datetime("2019-12-27T18:11:19.117Z"), + started_before=parse_datetime("2019-12-27T18:11:19.117Z"), + status="active", + user_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ProxyListConnectionsResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list_connections(self, async_client: AsyncMobilerun) -> None: + response = await async_client.connect.proxies.with_raw_response.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = await response.parse() + assert_matches_type(ProxyListConnectionsResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list_connections(self, async_client: AsyncMobilerun) -> None: + async with async_client.connect.proxies.with_streaming_response.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = await response.parse() + assert_matches_type(ProxyListConnectionsResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_list_connections(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.connect.proxies.with_raw_response.list_connections( + id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_ping(self, async_client: AsyncMobilerun) -> None: + proxy = await async_client.connect.proxies.ping( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(ProxyPingResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_ping(self, async_client: AsyncMobilerun) -> None: + response = await async_client.connect.proxies.with_raw_response.ping( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + proxy = await response.parse() + assert_matches_type(ProxyPingResponse, proxy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_ping(self, async_client: AsyncMobilerun) -> None: + async with async_client.connect.proxies.with_streaming_response.ping( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + proxy = await response.parse() + assert_matches_type(ProxyPingResponse, proxy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_ping(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.connect.proxies.with_raw_response.ping( + "", + ) diff --git a/tests/api_resources/connect/test_users.py b/tests/api_resources/connect/test_users.py new file mode 100644 index 0000000..c2e99dc --- /dev/null +++ b/tests/api_resources/connect/test_users.py @@ -0,0 +1,603 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from tests.utils import assert_matches_type +from mobilerun_sdk import Mobilerun, AsyncMobilerun +from mobilerun_sdk._utils import parse_datetime +from mobilerun_sdk.types.connect import ( + UserListResponse, + UserCreateResponse, + UserUpdateResponse, + UserRetrieveResponse, + UserListConnectionsResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestUsers: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create(self, client: Mobilerun) -> None: + user = client.connect.users.create() + assert_matches_type(UserCreateResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_with_all_params(self, client: Mobilerun) -> None: + user = client.connect.users.create( + password="x", + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + username="x", + ) + assert_matches_type(UserCreateResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: Mobilerun) -> None: + response = client.connect.users.with_raw_response.create() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert_matches_type(UserCreateResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: Mobilerun) -> None: + with client.connect.users.with_streaming_response.create() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert_matches_type(UserCreateResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve(self, client: Mobilerun) -> None: + user = client.connect.users.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(UserRetrieveResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve(self, client: Mobilerun) -> None: + response = client.connect.users.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert_matches_type(UserRetrieveResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve(self, client: Mobilerun) -> None: + with client.connect.users.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert_matches_type(UserRetrieveResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_retrieve(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.connect.users.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update(self, client: Mobilerun) -> None: + user = client.connect.users.update( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(UserUpdateResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update_with_all_params(self, client: Mobilerun) -> None: + user = client.connect.users.update( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(UserUpdateResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_update(self, client: Mobilerun) -> None: + response = client.connect.users.with_raw_response.update( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert_matches_type(UserUpdateResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_update(self, client: Mobilerun) -> None: + with client.connect.users.with_streaming_response.update( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert_matches_type(UserUpdateResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_update(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.connect.users.with_raw_response.update( + id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Mobilerun) -> None: + user = client.connect.users.list() + assert_matches_type(UserListResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Mobilerun) -> None: + user = client.connect.users.list( + page=1, + page_size=1, + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(UserListResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Mobilerun) -> None: + response = client.connect.users.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert_matches_type(UserListResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Mobilerun) -> None: + with client.connect.users.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert_matches_type(UserListResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete(self, client: Mobilerun) -> None: + user = client.connect.users.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert user is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete(self, client: Mobilerun) -> None: + response = client.connect.users.with_raw_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert user is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete(self, client: Mobilerun) -> None: + with client.connect.users.with_streaming_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert user is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_delete(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.connect.users.with_raw_response.delete( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_connections(self, client: Mobilerun) -> None: + user = client.connect.users.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(UserListConnectionsResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_connections_with_all_params(self, client: Mobilerun) -> None: + user = client.connect.users.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + close_reason="closeReason", + country="country", + dst_host="dstHost", + dst_port=0, + ended_after=parse_datetime("2019-12-27T18:11:19.117Z"), + ended_before=parse_datetime("2019-12-27T18:11:19.117Z"), + max_bytes_in=0, + max_bytes_out=0, + max_duration_ms=0, + max_total_bytes=0, + min_bytes_in=0, + min_bytes_out=0, + min_duration_ms=0, + min_total_bytes=0, + order="asc", + order_by="startedAt", + page=1, + page_size=1, + protocol="tcp", + provider="provider", + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + started_after=parse_datetime("2019-12-27T18:11:19.117Z"), + started_before=parse_datetime("2019-12-27T18:11:19.117Z"), + status="active", + ) + assert_matches_type(UserListConnectionsResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list_connections(self, client: Mobilerun) -> None: + response = client.connect.users.with_raw_response.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = response.parse() + assert_matches_type(UserListConnectionsResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list_connections(self, client: Mobilerun) -> None: + with client.connect.users.with_streaming_response.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = response.parse() + assert_matches_type(UserListConnectionsResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_list_connections(self, client: Mobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.connect.users.with_raw_response.list_connections( + id="", + ) + + +class TestAsyncUsers: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create(self, async_client: AsyncMobilerun) -> None: + user = await async_client.connect.users.create() + assert_matches_type(UserCreateResponse, user, 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: + user = await async_client.connect.users.create( + password="x", + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + username="x", + ) + assert_matches_type(UserCreateResponse, user, path=["response"]) + + @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.connect.users.with_raw_response.create() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert_matches_type(UserCreateResponse, user, path=["response"]) + + @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.connect.users.with_streaming_response.create() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert_matches_type(UserCreateResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve(self, async_client: AsyncMobilerun) -> None: + user = await async_client.connect.users.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(UserRetrieveResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncMobilerun) -> None: + response = await async_client.connect.users.with_raw_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert_matches_type(UserRetrieveResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncMobilerun) -> None: + async with async_client.connect.users.with_streaming_response.retrieve( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert_matches_type(UserRetrieveResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_retrieve(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.connect.users.with_raw_response.retrieve( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update(self, async_client: AsyncMobilerun) -> None: + user = await async_client.connect.users.update( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(UserUpdateResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncMobilerun) -> None: + user = await async_client.connect.users.update( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(UserUpdateResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_update(self, async_client: AsyncMobilerun) -> None: + response = await async_client.connect.users.with_raw_response.update( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert_matches_type(UserUpdateResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_update(self, async_client: AsyncMobilerun) -> None: + async with async_client.connect.users.with_streaming_response.update( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert_matches_type(UserUpdateResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_update(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.connect.users.with_raw_response.update( + id="", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncMobilerun) -> None: + user = await async_client.connect.users.list() + assert_matches_type(UserListResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncMobilerun) -> None: + user = await async_client.connect.users.list( + page=1, + page_size=1, + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(UserListResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncMobilerun) -> None: + response = await async_client.connect.users.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert_matches_type(UserListResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncMobilerun) -> None: + async with async_client.connect.users.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert_matches_type(UserListResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete(self, async_client: AsyncMobilerun) -> None: + user = await async_client.connect.users.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert user is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncMobilerun) -> None: + response = await async_client.connect.users.with_raw_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert user is None + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncMobilerun) -> None: + async with async_client.connect.users.with_streaming_response.delete( + "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert user is None + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_delete(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.connect.users.with_raw_response.delete( + "", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_connections(self, async_client: AsyncMobilerun) -> None: + user = await async_client.connect.users.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(UserListConnectionsResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_connections_with_all_params(self, async_client: AsyncMobilerun) -> None: + user = await async_client.connect.users.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + close_reason="closeReason", + country="country", + dst_host="dstHost", + dst_port=0, + ended_after=parse_datetime("2019-12-27T18:11:19.117Z"), + ended_before=parse_datetime("2019-12-27T18:11:19.117Z"), + max_bytes_in=0, + max_bytes_out=0, + max_duration_ms=0, + max_total_bytes=0, + min_bytes_in=0, + min_bytes_out=0, + min_duration_ms=0, + min_total_bytes=0, + order="asc", + order_by="startedAt", + page=1, + page_size=1, + protocol="tcp", + provider="provider", + proxy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + session_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + started_after=parse_datetime("2019-12-27T18:11:19.117Z"), + started_before=parse_datetime("2019-12-27T18:11:19.117Z"), + status="active", + ) + assert_matches_type(UserListConnectionsResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list_connections(self, async_client: AsyncMobilerun) -> None: + response = await async_client.connect.users.with_raw_response.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + user = await response.parse() + assert_matches_type(UserListConnectionsResponse, user, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list_connections(self, async_client: AsyncMobilerun) -> None: + async with async_client.connect.users.with_streaming_response.list_connections( + id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + user = await response.parse() + assert_matches_type(UserListConnectionsResponse, user, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_list_connections(self, async_client: AsyncMobilerun) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.connect.users.with_raw_response.list_connections( + id="", + ) From e6b356d4612816e536c6dad5fb19f322e90511ad Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 13:14:27 +0000 Subject: [PATCH 20/21] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index d21fd02..693b09d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 166 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-af0cf78a9ffb5f93cb988ae03eb409a9810d24056f193d48d7b8394c2ffa398f.yml -openapi_spec_hash: 29b62d198d5699a230afd5397359cecb +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/droidrun/droidrun-cloud-4e32174d9764ddeec31db33c46c772c4ac06eb72aa399445f79283b35c57e37d.yml +openapi_spec_hash: b2b7096b8e12f79a52ad303aa9b21dea config_hash: 7eee71321886b0cd05bdbd017f9d06ec From e7a6e2441e5dfc5681e42353bddf434e7c2dc588 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 11 Jun 2026 11:10:41 +0000 Subject: [PATCH 21/21] release: 5.0.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 20 ++++++++++++++++++++ pyproject.toml | 2 +- src/mobilerun_sdk/_version.py | 2 +- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 1f73031..8e76abb 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "3.2.0" + ".": "5.0.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 91e1a63..7832318 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## 5.0.0 (2026-06-11) + +Full Changelog: [v3.2.0...v5.0.0](https://github.com/droidrun/mobilerun-sdk-python/compare/v3.2.0...v5.0.0) + +### Features + +* **api:** add agents-api ([ec80ec3](https://github.com/droidrun/mobilerun-sdk-python/commit/ec80ec35e333e302f8b09cd8ddf81d69d297f027)) +* **api:** api update ([080b0a8](https://github.com/droidrun/mobilerun-sdk-python/commit/080b0a8a668e792ddfc8f2ceacb30ca59ac0f45a)) +* **api:** api update ([13645e2](https://github.com/droidrun/mobilerun-sdk-python/commit/13645e2290241b8930ad56231b0aac9ffb0d8b9d)) +* **api:** api update ([472689f](https://github.com/droidrun/mobilerun-sdk-python/commit/472689f40d0225edcedb331fabda5d9b5ddbe390)) +* **api:** api update ([b58be1c](https://github.com/droidrun/mobilerun-sdk-python/commit/b58be1c00be168f8719a56d2ce5c1806ac30ef92)) +* **api:** api update ([2add42e](https://github.com/droidrun/mobilerun-sdk-python/commit/2add42ec33a0accad90ab5afe8d27ce22629b871)) +* **api:** enable workflows ([b01d496](https://github.com/droidrun/mobilerun-sdk-python/commit/b01d4969bea4f20289720122c261a9897af656f2)) +* **api:** manual updates ([16e622e](https://github.com/droidrun/mobilerun-sdk-python/commit/16e622e471e8043c80c30f9904eb74bd168f1b00)) +* **api:** manual updates ([1b32b0d](https://github.com/droidrun/mobilerun-sdk-python/commit/1b32b0daa46383c045df0b9ec5e8903d0c6b8808)) +* **api:** manual updates ([7fa7979](https://github.com/droidrun/mobilerun-sdk-python/commit/7fa7979dda9d7827014ec82d390c622c3f096929)) +* **api:** manual updates ([1a4d40d](https://github.com/droidrun/mobilerun-sdk-python/commit/1a4d40df9fc939af3fc0c1cd7885b450821b7ce2)) +* **api:** manual updates ([88c9ae0](https://github.com/droidrun/mobilerun-sdk-python/commit/88c9ae09fe4979789e30e859bf9f7d57f39887c2)) +* **api:** mobilerun connect endpoints ([7856951](https://github.com/droidrun/mobilerun-sdk-python/commit/785695138d9ad132ef6ea86802c6b26d89ed9337)) + ## 3.2.0 (2026-05-21) Full Changelog: [v3.1.0...v3.2.0](https://github.com/droidrun/mobilerun-sdk-python/compare/v3.1.0...v3.2.0) diff --git a/pyproject.toml b/pyproject.toml index b097c23..92a3d5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "mobilerun-sdk" -version = "3.2.0" +version = "5.0.0" description = "The official Python library for the mobilerun API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/mobilerun_sdk/_version.py b/src/mobilerun_sdk/_version.py index a3beadb..f6ed05f 100644 --- a/src/mobilerun_sdk/_version.py +++ b/src/mobilerun_sdk/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "mobilerun_sdk" -__version__ = "3.2.0" # x-release-please-version +__version__ = "5.0.0" # x-release-please-version