moru 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. moru/__init__.py +174 -0
  2. moru/api/__init__.py +164 -0
  3. moru/api/client/__init__.py +8 -0
  4. moru/api/client/api/__init__.py +1 -0
  5. moru/api/client/api/sandboxes/__init__.py +1 -0
  6. moru/api/client/api/sandboxes/delete_sandboxes_sandbox_id.py +161 -0
  7. moru/api/client/api/sandboxes/get_sandboxes.py +176 -0
  8. moru/api/client/api/sandboxes/get_sandboxes_metrics.py +173 -0
  9. moru/api/client/api/sandboxes/get_sandboxes_sandbox_id.py +163 -0
  10. moru/api/client/api/sandboxes/get_sandboxes_sandbox_id_logs.py +199 -0
  11. moru/api/client/api/sandboxes/get_sandboxes_sandbox_id_metrics.py +212 -0
  12. moru/api/client/api/sandboxes/get_v2_sandboxes.py +230 -0
  13. moru/api/client/api/sandboxes/post_sandboxes.py +172 -0
  14. moru/api/client/api/sandboxes/post_sandboxes_sandbox_id_connect.py +193 -0
  15. moru/api/client/api/sandboxes/post_sandboxes_sandbox_id_pause.py +165 -0
  16. moru/api/client/api/sandboxes/post_sandboxes_sandbox_id_refreshes.py +181 -0
  17. moru/api/client/api/sandboxes/post_sandboxes_sandbox_id_resume.py +189 -0
  18. moru/api/client/api/sandboxes/post_sandboxes_sandbox_id_timeout.py +193 -0
  19. moru/api/client/api/templates/__init__.py +1 -0
  20. moru/api/client/api/templates/delete_templates_template_id.py +157 -0
  21. moru/api/client/api/templates/get_templates.py +172 -0
  22. moru/api/client/api/templates/get_templates_template_id.py +195 -0
  23. moru/api/client/api/templates/get_templates_template_id_builds_build_id_status.py +217 -0
  24. moru/api/client/api/templates/get_templates_template_id_files_hash.py +180 -0
  25. moru/api/client/api/templates/patch_templates_template_id.py +183 -0
  26. moru/api/client/api/templates/post_templates.py +172 -0
  27. moru/api/client/api/templates/post_templates_template_id.py +181 -0
  28. moru/api/client/api/templates/post_templates_template_id_builds_build_id.py +170 -0
  29. moru/api/client/api/templates/post_v2_templates.py +172 -0
  30. moru/api/client/api/templates/post_v3_templates.py +172 -0
  31. moru/api/client/api/templates/post_v_2_templates_template_id_builds_build_id.py +192 -0
  32. moru/api/client/client.py +286 -0
  33. moru/api/client/errors.py +16 -0
  34. moru/api/client/models/__init__.py +123 -0
  35. moru/api/client/models/aws_registry.py +85 -0
  36. moru/api/client/models/aws_registry_type.py +8 -0
  37. moru/api/client/models/build_log_entry.py +89 -0
  38. moru/api/client/models/build_status_reason.py +95 -0
  39. moru/api/client/models/connect_sandbox.py +59 -0
  40. moru/api/client/models/created_access_token.py +100 -0
  41. moru/api/client/models/created_team_api_key.py +166 -0
  42. moru/api/client/models/disk_metrics.py +91 -0
  43. moru/api/client/models/error.py +67 -0
  44. moru/api/client/models/gcp_registry.py +69 -0
  45. moru/api/client/models/gcp_registry_type.py +8 -0
  46. moru/api/client/models/general_registry.py +77 -0
  47. moru/api/client/models/general_registry_type.py +8 -0
  48. moru/api/client/models/identifier_masking_details.py +83 -0
  49. moru/api/client/models/listed_sandbox.py +154 -0
  50. moru/api/client/models/log_level.py +11 -0
  51. moru/api/client/models/max_team_metric.py +78 -0
  52. moru/api/client/models/mcp_type_0.py +44 -0
  53. moru/api/client/models/new_access_token.py +59 -0
  54. moru/api/client/models/new_sandbox.py +172 -0
  55. moru/api/client/models/new_team_api_key.py +59 -0
  56. moru/api/client/models/node.py +155 -0
  57. moru/api/client/models/node_detail.py +165 -0
  58. moru/api/client/models/node_metrics.py +122 -0
  59. moru/api/client/models/node_status.py +11 -0
  60. moru/api/client/models/node_status_change.py +79 -0
  61. moru/api/client/models/post_sandboxes_sandbox_id_refreshes_body.py +59 -0
  62. moru/api/client/models/post_sandboxes_sandbox_id_timeout_body.py +59 -0
  63. moru/api/client/models/resumed_sandbox.py +68 -0
  64. moru/api/client/models/sandbox.py +145 -0
  65. moru/api/client/models/sandbox_detail.py +183 -0
  66. moru/api/client/models/sandbox_log.py +70 -0
  67. moru/api/client/models/sandbox_log_entry.py +93 -0
  68. moru/api/client/models/sandbox_log_entry_fields.py +44 -0
  69. moru/api/client/models/sandbox_logs.py +91 -0
  70. moru/api/client/models/sandbox_metric.py +118 -0
  71. moru/api/client/models/sandbox_network_config.py +92 -0
  72. moru/api/client/models/sandbox_state.py +9 -0
  73. moru/api/client/models/sandboxes_with_metrics.py +59 -0
  74. moru/api/client/models/team.py +83 -0
  75. moru/api/client/models/team_api_key.py +158 -0
  76. moru/api/client/models/team_metric.py +86 -0
  77. moru/api/client/models/team_user.py +68 -0
  78. moru/api/client/models/template.py +217 -0
  79. moru/api/client/models/template_build.py +139 -0
  80. moru/api/client/models/template_build_file_upload.py +70 -0
  81. moru/api/client/models/template_build_info.py +126 -0
  82. moru/api/client/models/template_build_request.py +115 -0
  83. moru/api/client/models/template_build_request_v2.py +88 -0
  84. moru/api/client/models/template_build_request_v3.py +88 -0
  85. moru/api/client/models/template_build_start_v2.py +184 -0
  86. moru/api/client/models/template_build_status.py +11 -0
  87. moru/api/client/models/template_legacy.py +207 -0
  88. moru/api/client/models/template_request_response_v3.py +83 -0
  89. moru/api/client/models/template_step.py +91 -0
  90. moru/api/client/models/template_update_request.py +59 -0
  91. moru/api/client/models/template_with_builds.py +148 -0
  92. moru/api/client/models/update_team_api_key.py +59 -0
  93. moru/api/client/py.typed +1 -0
  94. moru/api/client/types.py +54 -0
  95. moru/api/client_async/__init__.py +50 -0
  96. moru/api/client_sync/__init__.py +52 -0
  97. moru/api/metadata.py +14 -0
  98. moru/connection_config.py +217 -0
  99. moru/envd/api.py +59 -0
  100. moru/envd/filesystem/filesystem_connect.py +193 -0
  101. moru/envd/filesystem/filesystem_pb2.py +76 -0
  102. moru/envd/filesystem/filesystem_pb2.pyi +233 -0
  103. moru/envd/process/process_connect.py +155 -0
  104. moru/envd/process/process_pb2.py +92 -0
  105. moru/envd/process/process_pb2.pyi +304 -0
  106. moru/envd/rpc.py +61 -0
  107. moru/envd/versions.py +6 -0
  108. moru/exceptions.py +95 -0
  109. moru/sandbox/commands/command_handle.py +69 -0
  110. moru/sandbox/commands/main.py +39 -0
  111. moru/sandbox/filesystem/filesystem.py +94 -0
  112. moru/sandbox/filesystem/watch_handle.py +60 -0
  113. moru/sandbox/main.py +210 -0
  114. moru/sandbox/mcp.py +1120 -0
  115. moru/sandbox/network.py +8 -0
  116. moru/sandbox/sandbox_api.py +210 -0
  117. moru/sandbox/signature.py +45 -0
  118. moru/sandbox/utils.py +34 -0
  119. moru/sandbox_async/commands/command.py +336 -0
  120. moru/sandbox_async/commands/command_handle.py +196 -0
  121. moru/sandbox_async/commands/pty.py +240 -0
  122. moru/sandbox_async/filesystem/filesystem.py +531 -0
  123. moru/sandbox_async/filesystem/watch_handle.py +62 -0
  124. moru/sandbox_async/main.py +734 -0
  125. moru/sandbox_async/paginator.py +69 -0
  126. moru/sandbox_async/sandbox_api.py +325 -0
  127. moru/sandbox_async/utils.py +7 -0
  128. moru/sandbox_sync/commands/command.py +328 -0
  129. moru/sandbox_sync/commands/command_handle.py +150 -0
  130. moru/sandbox_sync/commands/pty.py +230 -0
  131. moru/sandbox_sync/filesystem/filesystem.py +518 -0
  132. moru/sandbox_sync/filesystem/watch_handle.py +69 -0
  133. moru/sandbox_sync/main.py +726 -0
  134. moru/sandbox_sync/paginator.py +69 -0
  135. moru/sandbox_sync/sandbox_api.py +308 -0
  136. moru/template/consts.py +30 -0
  137. moru/template/dockerfile_parser.py +275 -0
  138. moru/template/logger.py +232 -0
  139. moru/template/main.py +1360 -0
  140. moru/template/readycmd.py +138 -0
  141. moru/template/types.py +105 -0
  142. moru/template/utils.py +320 -0
  143. moru/template_async/build_api.py +202 -0
  144. moru/template_async/main.py +366 -0
  145. moru/template_sync/build_api.py +199 -0
  146. moru/template_sync/main.py +371 -0
  147. moru-0.1.0.dist-info/METADATA +63 -0
  148. moru-0.1.0.dist-info/RECORD +152 -0
  149. moru-0.1.0.dist-info/WHEEL +4 -0
  150. moru-0.1.0.dist-info/licenses/LICENSE +9 -0
  151. moru_connect/__init__.py +1 -0
  152. moru_connect/client.py +493 -0
moru/__init__.py ADDED
@@ -0,0 +1,174 @@
1
+ """
2
+ Secure sandboxed cloud environments made for AI agents and AI apps.
3
+
4
+ Check docs [here](https://moru.io/docs).
5
+
6
+ Moru Sandbox is a secure cloud sandbox environment made for AI agents and AI
7
+ apps.
8
+ Sandboxes allow AI agents and apps to have long running cloud secure environments.
9
+ In these environments, large language models can use the same tools as humans do.
10
+
11
+ Moru Python SDK supports both sync and async API:
12
+
13
+ ```py
14
+ from moru import Sandbox
15
+
16
+ # Create sandbox
17
+ sandbox = Sandbox.create()
18
+ ```
19
+
20
+ ```py
21
+ from moru import AsyncSandbox
22
+
23
+ # Create sandbox
24
+ sandbox = await AsyncSandbox.create()
25
+ ```
26
+ """
27
+
28
+ from .api import (
29
+ ApiClient,
30
+ client,
31
+ )
32
+ from .connection_config import (
33
+ ConnectionConfig,
34
+ ProxyTypes,
35
+ )
36
+ from .exceptions import (
37
+ AuthenticationException,
38
+ BuildException,
39
+ FileUploadException,
40
+ InvalidArgumentException,
41
+ NotEnoughSpaceException,
42
+ NotFoundException,
43
+ SandboxException,
44
+ TemplateException,
45
+ TimeoutException,
46
+ )
47
+ from .sandbox.commands.command_handle import (
48
+ CommandExitException,
49
+ CommandResult,
50
+ PtyOutput,
51
+ PtySize,
52
+ Stderr,
53
+ Stdout,
54
+ )
55
+ from .sandbox.commands.main import ProcessInfo
56
+ from .sandbox.filesystem.filesystem import EntryInfo, FileType, WriteInfo
57
+ from .sandbox.filesystem.watch_handle import (
58
+ FilesystemEvent,
59
+ FilesystemEventType,
60
+ )
61
+ from .sandbox.network import ALL_TRAFFIC
62
+ from .sandbox.sandbox_api import (
63
+ GitHubMcpServer,
64
+ GitHubMcpServerConfig,
65
+ McpServer,
66
+ SandboxInfo,
67
+ SandboxMetrics,
68
+ SandboxNetworkOpts,
69
+ SandboxQuery,
70
+ SandboxState,
71
+ )
72
+ from .sandbox_async.commands.command_handle import AsyncCommandHandle
73
+ from .sandbox_async.filesystem.watch_handle import AsyncWatchHandle
74
+ from .sandbox_async.main import AsyncSandbox
75
+ from .sandbox_async.paginator import AsyncSandboxPaginator
76
+ from .sandbox_async.utils import OutputHandler
77
+ from .sandbox_sync.commands.command_handle import CommandHandle
78
+ from .sandbox_sync.filesystem.watch_handle import WatchHandle
79
+ from .sandbox_sync.main import Sandbox
80
+ from .sandbox_sync.paginator import SandboxPaginator
81
+ from .template.logger import (
82
+ LogEntry,
83
+ LogEntryEnd,
84
+ LogEntryLevel,
85
+ LogEntryStart,
86
+ default_build_logger,
87
+ )
88
+ from .template.main import TemplateBase, TemplateClass
89
+ from .template.readycmd import (
90
+ ReadyCmd,
91
+ wait_for_file,
92
+ wait_for_port,
93
+ wait_for_process,
94
+ wait_for_timeout,
95
+ wait_for_url,
96
+ )
97
+ from .template.types import BuildInfo, CopyItem
98
+ from .template_async.main import AsyncTemplate
99
+ from .template_sync.main import Template
100
+
101
+ __all__ = [
102
+ # API
103
+ "ApiClient",
104
+ "client",
105
+ # Connection config
106
+ "ConnectionConfig",
107
+ "ProxyTypes",
108
+ # Exceptions
109
+ "SandboxException",
110
+ "TimeoutException",
111
+ "NotFoundException",
112
+ "AuthenticationException",
113
+ "InvalidArgumentException",
114
+ "NotEnoughSpaceException",
115
+ "TemplateException",
116
+ "BuildException",
117
+ "FileUploadException",
118
+ # Sandbox API
119
+ "SandboxInfo",
120
+ "SandboxMetrics",
121
+ "ProcessInfo",
122
+ "SandboxQuery",
123
+ "SandboxState",
124
+ "SandboxMetrics",
125
+ # Command handle
126
+ "CommandResult",
127
+ "Stderr",
128
+ "Stdout",
129
+ "CommandExitException",
130
+ "PtyOutput",
131
+ "PtySize",
132
+ # Filesystem
133
+ "FilesystemEvent",
134
+ "FilesystemEventType",
135
+ "EntryInfo",
136
+ "WriteInfo",
137
+ "FileType",
138
+ # Network
139
+ "SandboxNetworkOpts",
140
+ "ALL_TRAFFIC",
141
+ # Sync sandbox
142
+ "Sandbox",
143
+ "SandboxPaginator",
144
+ "WatchHandle",
145
+ "CommandHandle",
146
+ # Async sandbox
147
+ "OutputHandler",
148
+ "AsyncSandboxPaginator",
149
+ "AsyncSandbox",
150
+ "AsyncWatchHandle",
151
+ "AsyncCommandHandle",
152
+ # Template
153
+ "Template",
154
+ "AsyncTemplate",
155
+ "TemplateBase",
156
+ "TemplateClass",
157
+ "CopyItem",
158
+ "BuildInfo",
159
+ "ReadyCmd",
160
+ "wait_for_file",
161
+ "wait_for_url",
162
+ "wait_for_port",
163
+ "wait_for_process",
164
+ "wait_for_timeout",
165
+ "LogEntry",
166
+ "LogEntryStart",
167
+ "LogEntryEnd",
168
+ "LogEntryLevel",
169
+ "default_build_logger",
170
+ # MCP
171
+ "McpServer",
172
+ "GitHubMcpServer",
173
+ "GitHubMcpServerConfig",
174
+ ]
moru/api/__init__.py ADDED
@@ -0,0 +1,164 @@
1
+ import json
2
+ import logging
3
+ import os
4
+ from dataclasses import dataclass
5
+ from types import TracebackType
6
+ from typing import Optional, Union
7
+
8
+ from httpx import AsyncBaseTransport, BaseTransport, Limits
9
+
10
+ from moru.api.client.client import AuthenticatedClient
11
+ from moru.api.client.types import Response
12
+ from moru.api.metadata import default_headers
13
+ from moru.connection_config import ConnectionConfig
14
+ from moru.exceptions import (
15
+ AuthenticationException,
16
+ RateLimitException,
17
+ SandboxException,
18
+ )
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+ limits = Limits(
23
+ max_keepalive_connections=int(os.getenv("MORU_MAX_KEEPALIVE_CONNECTIONS", "20")),
24
+ max_connections=int(os.getenv("MORU_MAX_CONNECTIONS", "2000")),
25
+ keepalive_expiry=int(os.getenv("MORU_KEEPALIVE_EXPIRY", "300")),
26
+ )
27
+
28
+
29
+ @dataclass
30
+ class SandboxCreateResponse:
31
+ sandbox_id: str
32
+ sandbox_domain: Optional[str]
33
+ envd_version: str
34
+ envd_access_token: str
35
+ traffic_access_token: Optional[str]
36
+
37
+
38
+ def handle_api_exception(
39
+ e: Response,
40
+ default_exception_class: type[Exception] = SandboxException,
41
+ stack_trace: Optional[TracebackType] = None,
42
+ ):
43
+ try:
44
+ body = json.loads(e.content) if e.content else {}
45
+ except json.JSONDecodeError:
46
+ body = {}
47
+
48
+ if e.status_code == 401:
49
+ message = f"{e.status_code}: Unauthorized, please check your credentials."
50
+ if body.get("message"):
51
+ message += f" - {body['message']}"
52
+ return AuthenticationException(message)
53
+
54
+ if e.status_code == 429:
55
+ message = f"{e.status_code}: Rate limit exceeded, please try again later."
56
+ if body.get("message"):
57
+ message += f" - {body['message']}"
58
+ return RateLimitException(message)
59
+
60
+ if "message" in body:
61
+ return default_exception_class(
62
+ f"{e.status_code}: {body['message']}"
63
+ ).with_traceback(stack_trace)
64
+ return default_exception_class(f"{e.status_code}: {e.content}").with_traceback(
65
+ stack_trace
66
+ )
67
+
68
+
69
+ class ApiClient(AuthenticatedClient):
70
+ """
71
+ The client for interacting with the Moru API.
72
+ """
73
+
74
+ def __init__(
75
+ self,
76
+ config: ConnectionConfig,
77
+ require_api_key: bool = True,
78
+ require_access_token: bool = False,
79
+ transport: Optional[Union[BaseTransport, AsyncBaseTransport]] = None,
80
+ *args,
81
+ **kwargs,
82
+ ):
83
+ if require_api_key and require_access_token:
84
+ raise AuthenticationException(
85
+ "Only one of api_key or access_token can be required, not both",
86
+ )
87
+
88
+ if not require_api_key and not require_access_token:
89
+ raise AuthenticationException(
90
+ "Either api_key or access_token is required",
91
+ )
92
+
93
+ token = None
94
+ if require_api_key:
95
+ if config.api_key is None:
96
+ raise AuthenticationException(
97
+ "API key is required. "
98
+ "You can either set the environment variable `MORU_API_KEY` "
99
+ 'or you can pass it directly to the method like api_key="..."',
100
+ )
101
+ token = config.api_key
102
+
103
+ if require_access_token:
104
+ if config.access_token is None:
105
+ raise AuthenticationException(
106
+ "Access token is required. "
107
+ "You can set the environment variable `MORU_ACCESS_TOKEN` or pass the `access_token` in options.",
108
+ )
109
+ token = config.access_token
110
+
111
+ auth_header_name = "X-API-KEY" if require_api_key else "Authorization"
112
+ prefix = "" if require_api_key else "Bearer"
113
+
114
+ headers = {
115
+ **default_headers,
116
+ **(config.headers or {}),
117
+ }
118
+
119
+ # Prevent passing these parameters twice
120
+ more_headers: Optional[dict] = kwargs.pop("headers", None)
121
+ if more_headers:
122
+ headers.update(more_headers)
123
+ kwargs.pop("token", None)
124
+ kwargs.pop("auth_header_name", None)
125
+ kwargs.pop("prefix", None)
126
+
127
+ super().__init__(
128
+ base_url=config.api_url,
129
+ httpx_args={
130
+ "event_hooks": {
131
+ "request": [self._log_request],
132
+ "response": [self._log_response],
133
+ },
134
+ "proxy": config.proxy,
135
+ "transport": transport,
136
+ },
137
+ headers=headers,
138
+ token=token,
139
+ auth_header_name=auth_header_name,
140
+ prefix=prefix,
141
+ *args,
142
+ **kwargs,
143
+ )
144
+
145
+ def _log_request(self, request):
146
+ logger.info(f"Request {request.method} {request.url}")
147
+
148
+ def _log_response(self, response: Response):
149
+ if response.status_code >= 400:
150
+ logger.error(f"Response {response.status_code}")
151
+ else:
152
+ logger.info(f"Response {response.status_code}")
153
+
154
+
155
+ # We need to override the logging hooks for the async usage
156
+ class AsyncApiClient(ApiClient):
157
+ async def _log_request(self, request):
158
+ logger.info(f"Request {request.method} {request.url}")
159
+
160
+ async def _log_response(self, response: Response):
161
+ if response.status_code >= 400:
162
+ logger.error(f"Response {response.status_code}")
163
+ else:
164
+ logger.info(f"Response {response.status_code}")
@@ -0,0 +1,8 @@
1
+ """A client library for accessing Moru API"""
2
+
3
+ from .client import AuthenticatedClient, Client
4
+
5
+ __all__ = (
6
+ "AuthenticatedClient",
7
+ "Client",
8
+ )
@@ -0,0 +1 @@
1
+ """Contains methods for accessing the API"""
@@ -0,0 +1 @@
1
+ """Contains endpoint functions for accessing the API"""
@@ -0,0 +1,161 @@
1
+ from http import HTTPStatus
2
+ from typing import Any, Optional, Union, cast
3
+
4
+ import httpx
5
+
6
+ from ... import errors
7
+ from ...client import AuthenticatedClient, Client
8
+ from ...models.error import Error
9
+ from ...types import Response
10
+
11
+
12
+ def _get_kwargs(
13
+ sandbox_id: str,
14
+ ) -> dict[str, Any]:
15
+ _kwargs: dict[str, Any] = {
16
+ "method": "delete",
17
+ "url": f"/sandboxes/{sandbox_id}",
18
+ }
19
+
20
+ return _kwargs
21
+
22
+
23
+ def _parse_response(
24
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
25
+ ) -> Optional[Union[Any, Error]]:
26
+ if response.status_code == 204:
27
+ response_204 = cast(Any, None)
28
+ return response_204
29
+ if response.status_code == 401:
30
+ response_401 = Error.from_dict(response.json())
31
+
32
+ return response_401
33
+ if response.status_code == 404:
34
+ response_404 = Error.from_dict(response.json())
35
+
36
+ return response_404
37
+ if response.status_code == 500:
38
+ response_500 = Error.from_dict(response.json())
39
+
40
+ return response_500
41
+ if client.raise_on_unexpected_status:
42
+ raise errors.UnexpectedStatus(response.status_code, response.content)
43
+ else:
44
+ return None
45
+
46
+
47
+ def _build_response(
48
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
49
+ ) -> Response[Union[Any, Error]]:
50
+ return Response(
51
+ status_code=HTTPStatus(response.status_code),
52
+ content=response.content,
53
+ headers=response.headers,
54
+ parsed=_parse_response(client=client, response=response),
55
+ )
56
+
57
+
58
+ def sync_detailed(
59
+ sandbox_id: str,
60
+ *,
61
+ client: AuthenticatedClient,
62
+ ) -> Response[Union[Any, Error]]:
63
+ """Kill a sandbox
64
+
65
+ Args:
66
+ sandbox_id (str):
67
+
68
+ Raises:
69
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
70
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
71
+
72
+ Returns:
73
+ Response[Union[Any, Error]]
74
+ """
75
+
76
+ kwargs = _get_kwargs(
77
+ sandbox_id=sandbox_id,
78
+ )
79
+
80
+ response = client.get_httpx_client().request(
81
+ **kwargs,
82
+ )
83
+
84
+ return _build_response(client=client, response=response)
85
+
86
+
87
+ def sync(
88
+ sandbox_id: str,
89
+ *,
90
+ client: AuthenticatedClient,
91
+ ) -> Optional[Union[Any, Error]]:
92
+ """Kill a sandbox
93
+
94
+ Args:
95
+ sandbox_id (str):
96
+
97
+ Raises:
98
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
99
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
100
+
101
+ Returns:
102
+ Union[Any, Error]
103
+ """
104
+
105
+ return sync_detailed(
106
+ sandbox_id=sandbox_id,
107
+ client=client,
108
+ ).parsed
109
+
110
+
111
+ async def asyncio_detailed(
112
+ sandbox_id: str,
113
+ *,
114
+ client: AuthenticatedClient,
115
+ ) -> Response[Union[Any, Error]]:
116
+ """Kill a sandbox
117
+
118
+ Args:
119
+ sandbox_id (str):
120
+
121
+ Raises:
122
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
123
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
124
+
125
+ Returns:
126
+ Response[Union[Any, Error]]
127
+ """
128
+
129
+ kwargs = _get_kwargs(
130
+ sandbox_id=sandbox_id,
131
+ )
132
+
133
+ response = await client.get_async_httpx_client().request(**kwargs)
134
+
135
+ return _build_response(client=client, response=response)
136
+
137
+
138
+ async def asyncio(
139
+ sandbox_id: str,
140
+ *,
141
+ client: AuthenticatedClient,
142
+ ) -> Optional[Union[Any, Error]]:
143
+ """Kill a sandbox
144
+
145
+ Args:
146
+ sandbox_id (str):
147
+
148
+ Raises:
149
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
150
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
151
+
152
+ Returns:
153
+ Union[Any, Error]
154
+ """
155
+
156
+ return (
157
+ await asyncio_detailed(
158
+ sandbox_id=sandbox_id,
159
+ client=client,
160
+ )
161
+ ).parsed
@@ -0,0 +1,176 @@
1
+ from http import HTTPStatus
2
+ from typing import Any, Optional, Union
3
+
4
+ import httpx
5
+
6
+ from ... import errors
7
+ from ...client import AuthenticatedClient, Client
8
+ from ...models.error import Error
9
+ from ...models.listed_sandbox import ListedSandbox
10
+ from ...types import UNSET, Response, Unset
11
+
12
+
13
+ def _get_kwargs(
14
+ *,
15
+ metadata: Union[Unset, str] = UNSET,
16
+ ) -> dict[str, Any]:
17
+ params: dict[str, Any] = {}
18
+
19
+ params["metadata"] = metadata
20
+
21
+ params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
22
+
23
+ _kwargs: dict[str, Any] = {
24
+ "method": "get",
25
+ "url": "/sandboxes",
26
+ "params": params,
27
+ }
28
+
29
+ return _kwargs
30
+
31
+
32
+ def _parse_response(
33
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
34
+ ) -> Optional[Union[Error, list["ListedSandbox"]]]:
35
+ if response.status_code == 200:
36
+ response_200 = []
37
+ _response_200 = response.json()
38
+ for response_200_item_data in _response_200:
39
+ response_200_item = ListedSandbox.from_dict(response_200_item_data)
40
+
41
+ response_200.append(response_200_item)
42
+
43
+ return response_200
44
+ if response.status_code == 400:
45
+ response_400 = Error.from_dict(response.json())
46
+
47
+ return response_400
48
+ if response.status_code == 401:
49
+ response_401 = Error.from_dict(response.json())
50
+
51
+ return response_401
52
+ if response.status_code == 500:
53
+ response_500 = Error.from_dict(response.json())
54
+
55
+ return response_500
56
+ if client.raise_on_unexpected_status:
57
+ raise errors.UnexpectedStatus(response.status_code, response.content)
58
+ else:
59
+ return None
60
+
61
+
62
+ def _build_response(
63
+ *, client: Union[AuthenticatedClient, Client], response: httpx.Response
64
+ ) -> Response[Union[Error, list["ListedSandbox"]]]:
65
+ return Response(
66
+ status_code=HTTPStatus(response.status_code),
67
+ content=response.content,
68
+ headers=response.headers,
69
+ parsed=_parse_response(client=client, response=response),
70
+ )
71
+
72
+
73
+ def sync_detailed(
74
+ *,
75
+ client: AuthenticatedClient,
76
+ metadata: Union[Unset, str] = UNSET,
77
+ ) -> Response[Union[Error, list["ListedSandbox"]]]:
78
+ """List all running sandboxes
79
+
80
+ Args:
81
+ metadata (Union[Unset, str]):
82
+
83
+ Raises:
84
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
85
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
86
+
87
+ Returns:
88
+ Response[Union[Error, list['ListedSandbox']]]
89
+ """
90
+
91
+ kwargs = _get_kwargs(
92
+ metadata=metadata,
93
+ )
94
+
95
+ response = client.get_httpx_client().request(
96
+ **kwargs,
97
+ )
98
+
99
+ return _build_response(client=client, response=response)
100
+
101
+
102
+ def sync(
103
+ *,
104
+ client: AuthenticatedClient,
105
+ metadata: Union[Unset, str] = UNSET,
106
+ ) -> Optional[Union[Error, list["ListedSandbox"]]]:
107
+ """List all running sandboxes
108
+
109
+ Args:
110
+ metadata (Union[Unset, str]):
111
+
112
+ Raises:
113
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
114
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
115
+
116
+ Returns:
117
+ Union[Error, list['ListedSandbox']]
118
+ """
119
+
120
+ return sync_detailed(
121
+ client=client,
122
+ metadata=metadata,
123
+ ).parsed
124
+
125
+
126
+ async def asyncio_detailed(
127
+ *,
128
+ client: AuthenticatedClient,
129
+ metadata: Union[Unset, str] = UNSET,
130
+ ) -> Response[Union[Error, list["ListedSandbox"]]]:
131
+ """List all running sandboxes
132
+
133
+ Args:
134
+ metadata (Union[Unset, str]):
135
+
136
+ Raises:
137
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
138
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
139
+
140
+ Returns:
141
+ Response[Union[Error, list['ListedSandbox']]]
142
+ """
143
+
144
+ kwargs = _get_kwargs(
145
+ metadata=metadata,
146
+ )
147
+
148
+ response = await client.get_async_httpx_client().request(**kwargs)
149
+
150
+ return _build_response(client=client, response=response)
151
+
152
+
153
+ async def asyncio(
154
+ *,
155
+ client: AuthenticatedClient,
156
+ metadata: Union[Unset, str] = UNSET,
157
+ ) -> Optional[Union[Error, list["ListedSandbox"]]]:
158
+ """List all running sandboxes
159
+
160
+ Args:
161
+ metadata (Union[Unset, str]):
162
+
163
+ Raises:
164
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
165
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
166
+
167
+ Returns:
168
+ Union[Error, list['ListedSandbox']]
169
+ """
170
+
171
+ return (
172
+ await asyncio_detailed(
173
+ client=client,
174
+ metadata=metadata,
175
+ )
176
+ ).parsed