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