moru 0.1.0__py3-none-any.whl → 0.2.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 (72) hide show
  1. moru/__init__.py +8 -0
  2. moru/api/__init__.py +4 -0
  3. moru/api/client/__init__.py +1 -1
  4. moru/api/client/api/sandboxes/delete_sandboxes_sandbox_id.py +4 -0
  5. moru/api/client/api/sandboxes/get_sandboxes.py +4 -0
  6. moru/api/client/api/sandboxes/get_sandboxes_metrics.py +5 -1
  7. moru/api/client/api/sandboxes/get_sandboxes_sandbox_id.py +4 -0
  8. moru/api/client/api/sandboxes/get_sandboxes_sandbox_id_logs.py +67 -23
  9. moru/api/client/api/sandboxes/get_sandboxes_sandbox_id_metrics.py +5 -0
  10. moru/api/client/api/sandboxes/get_v2_sandbox_runs.py +218 -0
  11. moru/api/client/api/sandboxes/get_v2_sandboxes.py +5 -2
  12. moru/api/client/api/sandboxes/post_sandboxes.py +4 -0
  13. moru/api/client/api/sandboxes/post_sandboxes_sandbox_id_connect.py +6 -0
  14. moru/api/client/api/sandboxes/post_sandboxes_sandbox_id_pause.py +5 -0
  15. moru/api/client/api/sandboxes/post_sandboxes_sandbox_id_refreshes.py +3 -0
  16. moru/api/client/api/sandboxes/post_sandboxes_sandbox_id_resume.py +5 -0
  17. moru/api/client/api/sandboxes/post_sandboxes_sandbox_id_timeout.py +4 -0
  18. moru/api/client/api/templates/delete_templates_template_id.py +3 -0
  19. moru/api/client/api/templates/get_templates.py +3 -0
  20. moru/api/client/api/templates/get_templates_template_id.py +3 -0
  21. moru/api/client/api/templates/get_templates_template_id_builds_build_id_logs.py +276 -0
  22. moru/api/client/api/templates/get_templates_template_id_builds_build_id_status.py +23 -4
  23. moru/api/client/api/templates/get_templates_template_id_files_hash.py +5 -0
  24. moru/api/client/api/templates/patch_templates_template_id.py +4 -0
  25. moru/api/client/api/templates/post_templates.py +4 -0
  26. moru/api/client/api/templates/post_templates_template_id.py +3 -0
  27. moru/api/client/api/templates/post_templates_template_id_builds_build_id.py +3 -0
  28. moru/api/client/api/templates/post_v2_templates.py +4 -0
  29. moru/api/client/api/templates/post_v3_templates.py +4 -0
  30. moru/api/client/api/templates/post_v_2_templates_template_id_builds_build_id.py +3 -0
  31. moru/api/client/models/__init__.py +30 -0
  32. moru/api/client/models/admin_sandbox_kill_result.py +67 -0
  33. moru/api/client/models/build_log_entry.py +1 -1
  34. moru/api/client/models/create_volume_request.py +59 -0
  35. moru/api/client/models/file_info.py +105 -0
  36. moru/api/client/models/file_info_type.py +9 -0
  37. moru/api/client/models/file_list_response.py +84 -0
  38. moru/api/client/models/logs_direction.py +9 -0
  39. moru/api/client/models/logs_source.py +9 -0
  40. moru/api/client/models/machine_info.py +83 -0
  41. moru/api/client/models/new_sandbox.py +19 -0
  42. moru/api/client/models/node.py +10 -0
  43. moru/api/client/models/node_detail.py +10 -0
  44. moru/api/client/models/sandbox_log_entry.py +9 -9
  45. moru/api/client/models/sandbox_log_event_type.py +11 -0
  46. moru/api/client/models/sandbox_run.py +130 -0
  47. moru/api/client/models/sandbox_run_end_reason.py +11 -0
  48. moru/api/client/models/sandbox_run_status.py +10 -0
  49. moru/api/client/models/template_build_logs_response.py +73 -0
  50. moru/api/client/models/upload_response.py +67 -0
  51. moru/api/client/models/volume.py +105 -0
  52. moru/sandbox/mcp.py +835 -6
  53. moru/sandbox_async/commands/command.py +5 -1
  54. moru/sandbox_async/filesystem/filesystem.py +5 -1
  55. moru/sandbox_async/main.py +21 -0
  56. moru/sandbox_async/sandbox_api.py +17 -11
  57. moru/sandbox_sync/filesystem/filesystem.py +5 -1
  58. moru/sandbox_sync/main.py +21 -0
  59. moru/sandbox_sync/sandbox_api.py +17 -11
  60. moru/volume/__init__.py +11 -0
  61. moru/volume/types.py +83 -0
  62. moru/volume/volume_api.py +330 -0
  63. moru/volume_async/__init__.py +5 -0
  64. moru/volume_async/main.py +327 -0
  65. moru/volume_async/volume_api.py +290 -0
  66. moru/volume_sync/__init__.py +5 -0
  67. moru/volume_sync/main.py +325 -0
  68. moru-0.2.0.dist-info/METADATA +122 -0
  69. {moru-0.1.0.dist-info → moru-0.2.0.dist-info}/RECORD +71 -46
  70. {moru-0.1.0.dist-info → moru-0.2.0.dist-info}/WHEEL +1 -1
  71. moru-0.1.0.dist-info/METADATA +0 -63
  72. {moru-0.1.0.dist-info/licenses → moru-0.2.0.dist-info}/LICENSE +0 -0
@@ -37,18 +37,22 @@ def _parse_response(
37
37
  response_202 = TemplateLegacy.from_dict(response.json())
38
38
 
39
39
  return response_202
40
+
40
41
  if response.status_code == 400:
41
42
  response_400 = Error.from_dict(response.json())
42
43
 
43
44
  return response_400
45
+
44
46
  if response.status_code == 401:
45
47
  response_401 = Error.from_dict(response.json())
46
48
 
47
49
  return response_401
50
+
48
51
  if response.status_code == 500:
49
52
  response_500 = Error.from_dict(response.json())
50
53
 
51
54
  return response_500
55
+
52
56
  if client.raise_on_unexpected_status:
53
57
  raise errors.UnexpectedStatus(response.status_code, response.content)
54
58
  else:
@@ -37,18 +37,22 @@ def _parse_response(
37
37
  response_202 = TemplateRequestResponseV3.from_dict(response.json())
38
38
 
39
39
  return response_202
40
+
40
41
  if response.status_code == 400:
41
42
  response_400 = Error.from_dict(response.json())
42
43
 
43
44
  return response_400
45
+
44
46
  if response.status_code == 401:
45
47
  response_401 = Error.from_dict(response.json())
46
48
 
47
49
  return response_401
50
+
48
51
  if response.status_code == 500:
49
52
  response_500 = Error.from_dict(response.json())
50
53
 
51
54
  return response_500
55
+
52
56
  if client.raise_on_unexpected_status:
53
57
  raise errors.UnexpectedStatus(response.status_code, response.content)
54
58
  else:
@@ -37,14 +37,17 @@ def _parse_response(
37
37
  if response.status_code == 202:
38
38
  response_202 = cast(Any, None)
39
39
  return response_202
40
+
40
41
  if response.status_code == 401:
41
42
  response_401 = Error.from_dict(response.json())
42
43
 
43
44
  return response_401
45
+
44
46
  if response.status_code == 500:
45
47
  response_500 = Error.from_dict(response.json())
46
48
 
47
49
  return response_500
50
+
48
51
  if client.raise_on_unexpected_status:
49
52
  raise errors.UnexpectedStatus(response.status_code, response.content)
50
53
  else:
@@ -1,14 +1,19 @@
1
1
  """Contains all the data models used in inputs/outputs"""
2
2
 
3
+ from .admin_sandbox_kill_result import AdminSandboxKillResult
3
4
  from .aws_registry import AWSRegistry
4
5
  from .aws_registry_type import AWSRegistryType
5
6
  from .build_log_entry import BuildLogEntry
6
7
  from .build_status_reason import BuildStatusReason
7
8
  from .connect_sandbox import ConnectSandbox
9
+ from .create_volume_request import CreateVolumeRequest
8
10
  from .created_access_token import CreatedAccessToken
9
11
  from .created_team_api_key import CreatedTeamAPIKey
10
12
  from .disk_metrics import DiskMetrics
11
13
  from .error import Error
14
+ from .file_info import FileInfo
15
+ from .file_info_type import FileInfoType
16
+ from .file_list_response import FileListResponse
12
17
  from .gcp_registry import GCPRegistry
13
18
  from .gcp_registry_type import GCPRegistryType
14
19
  from .general_registry import GeneralRegistry
@@ -16,6 +21,9 @@ from .general_registry_type import GeneralRegistryType
16
21
  from .identifier_masking_details import IdentifierMaskingDetails
17
22
  from .listed_sandbox import ListedSandbox
18
23
  from .log_level import LogLevel
24
+ from .logs_direction import LogsDirection
25
+ from .logs_source import LogsSource
26
+ from .machine_info import MachineInfo
19
27
  from .max_team_metric import MaxTeamMetric
20
28
  from .mcp_type_0 import McpType0
21
29
  from .new_access_token import NewAccessToken
@@ -36,9 +44,13 @@ from .sandbox_detail import SandboxDetail
36
44
  from .sandbox_log import SandboxLog
37
45
  from .sandbox_log_entry import SandboxLogEntry
38
46
  from .sandbox_log_entry_fields import SandboxLogEntryFields
47
+ from .sandbox_log_event_type import SandboxLogEventType
39
48
  from .sandbox_logs import SandboxLogs
40
49
  from .sandbox_metric import SandboxMetric
41
50
  from .sandbox_network_config import SandboxNetworkConfig
51
+ from .sandbox_run import SandboxRun
52
+ from .sandbox_run_end_reason import SandboxRunEndReason
53
+ from .sandbox_run_status import SandboxRunStatus
42
54
  from .sandbox_state import SandboxState
43
55
  from .sandboxes_with_metrics import SandboxesWithMetrics
44
56
  from .team import Team
@@ -49,6 +61,7 @@ from .template import Template
49
61
  from .template_build import TemplateBuild
50
62
  from .template_build_file_upload import TemplateBuildFileUpload
51
63
  from .template_build_info import TemplateBuildInfo
64
+ from .template_build_logs_response import TemplateBuildLogsResponse
52
65
  from .template_build_request import TemplateBuildRequest
53
66
  from .template_build_request_v2 import TemplateBuildRequestV2
54
67
  from .template_build_request_v3 import TemplateBuildRequestV3
@@ -60,8 +73,11 @@ from .template_step import TemplateStep
60
73
  from .template_update_request import TemplateUpdateRequest
61
74
  from .template_with_builds import TemplateWithBuilds
62
75
  from .update_team_api_key import UpdateTeamAPIKey
76
+ from .upload_response import UploadResponse
77
+ from .volume import Volume
63
78
 
64
79
  __all__ = (
80
+ "AdminSandboxKillResult",
65
81
  "AWSRegistry",
66
82
  "AWSRegistryType",
67
83
  "BuildLogEntry",
@@ -69,8 +85,12 @@ __all__ = (
69
85
  "ConnectSandbox",
70
86
  "CreatedAccessToken",
71
87
  "CreatedTeamAPIKey",
88
+ "CreateVolumeRequest",
72
89
  "DiskMetrics",
73
90
  "Error",
91
+ "FileInfo",
92
+ "FileInfoType",
93
+ "FileListResponse",
74
94
  "GCPRegistry",
75
95
  "GCPRegistryType",
76
96
  "GeneralRegistry",
@@ -78,6 +98,9 @@ __all__ = (
78
98
  "IdentifierMaskingDetails",
79
99
  "ListedSandbox",
80
100
  "LogLevel",
101
+ "LogsDirection",
102
+ "LogsSource",
103
+ "MachineInfo",
81
104
  "MaxTeamMetric",
82
105
  "McpType0",
83
106
  "NewAccessToken",
@@ -97,9 +120,13 @@ __all__ = (
97
120
  "SandboxLog",
98
121
  "SandboxLogEntry",
99
122
  "SandboxLogEntryFields",
123
+ "SandboxLogEventType",
100
124
  "SandboxLogs",
101
125
  "SandboxMetric",
102
126
  "SandboxNetworkConfig",
127
+ "SandboxRun",
128
+ "SandboxRunEndReason",
129
+ "SandboxRunStatus",
103
130
  "SandboxState",
104
131
  "Team",
105
132
  "TeamAPIKey",
@@ -109,6 +136,7 @@ __all__ = (
109
136
  "TemplateBuild",
110
137
  "TemplateBuildFileUpload",
111
138
  "TemplateBuildInfo",
139
+ "TemplateBuildLogsResponse",
112
140
  "TemplateBuildRequest",
113
141
  "TemplateBuildRequestV2",
114
142
  "TemplateBuildRequestV3",
@@ -120,4 +148,6 @@ __all__ = (
120
148
  "TemplateUpdateRequest",
121
149
  "TemplateWithBuilds",
122
150
  "UpdateTeamAPIKey",
151
+ "UploadResponse",
152
+ "Volume",
123
153
  )
@@ -0,0 +1,67 @@
1
+ from collections.abc import Mapping
2
+ from typing import Any, TypeVar
3
+
4
+ from attrs import define as _attrs_define
5
+ from attrs import field as _attrs_field
6
+
7
+ T = TypeVar("T", bound="AdminSandboxKillResult")
8
+
9
+
10
+ @_attrs_define
11
+ class AdminSandboxKillResult:
12
+ """
13
+ Attributes:
14
+ failed_count (int): Number of sandboxes that failed to kill
15
+ killed_count (int): Number of sandboxes successfully killed
16
+ """
17
+
18
+ failed_count: int
19
+ killed_count: int
20
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
21
+
22
+ def to_dict(self) -> dict[str, Any]:
23
+ failed_count = self.failed_count
24
+
25
+ killed_count = self.killed_count
26
+
27
+ field_dict: dict[str, Any] = {}
28
+ field_dict.update(self.additional_properties)
29
+ field_dict.update(
30
+ {
31
+ "failedCount": failed_count,
32
+ "killedCount": killed_count,
33
+ }
34
+ )
35
+
36
+ return field_dict
37
+
38
+ @classmethod
39
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
40
+ d = dict(src_dict)
41
+ failed_count = d.pop("failedCount")
42
+
43
+ killed_count = d.pop("killedCount")
44
+
45
+ admin_sandbox_kill_result = cls(
46
+ failed_count=failed_count,
47
+ killed_count=killed_count,
48
+ )
49
+
50
+ admin_sandbox_kill_result.additional_properties = d
51
+ return admin_sandbox_kill_result
52
+
53
+ @property
54
+ def additional_keys(self) -> list[str]:
55
+ return list(self.additional_properties.keys())
56
+
57
+ def __getitem__(self, key: str) -> Any:
58
+ return self.additional_properties[key]
59
+
60
+ def __setitem__(self, key: str, value: Any) -> None:
61
+ self.additional_properties[key] = value
62
+
63
+ def __delitem__(self, key: str) -> None:
64
+ del self.additional_properties[key]
65
+
66
+ def __contains__(self, key: str) -> bool:
67
+ return key in self.additional_properties
@@ -16,7 +16,7 @@ T = TypeVar("T", bound="BuildLogEntry")
16
16
  class BuildLogEntry:
17
17
  """
18
18
  Attributes:
19
- level (LogLevel): State of the sandbox
19
+ level (LogLevel): Log level for build logs
20
20
  message (str): Log message content
21
21
  timestamp (datetime.datetime): Timestamp of the log entry
22
22
  step (Union[Unset, str]): Step in the build process related to the log entry
@@ -0,0 +1,59 @@
1
+ from collections.abc import Mapping
2
+ from typing import Any, TypeVar
3
+
4
+ from attrs import define as _attrs_define
5
+ from attrs import field as _attrs_field
6
+
7
+ T = TypeVar("T", bound="CreateVolumeRequest")
8
+
9
+
10
+ @_attrs_define
11
+ class CreateVolumeRequest:
12
+ """
13
+ Attributes:
14
+ name (str): Volume name (unique per team, slug format)
15
+ """
16
+
17
+ name: str
18
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
19
+
20
+ def to_dict(self) -> dict[str, Any]:
21
+ name = self.name
22
+
23
+ field_dict: dict[str, Any] = {}
24
+ field_dict.update(self.additional_properties)
25
+ field_dict.update(
26
+ {
27
+ "name": name,
28
+ }
29
+ )
30
+
31
+ return field_dict
32
+
33
+ @classmethod
34
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
35
+ d = dict(src_dict)
36
+ name = d.pop("name")
37
+
38
+ create_volume_request = cls(
39
+ name=name,
40
+ )
41
+
42
+ create_volume_request.additional_properties = d
43
+ return create_volume_request
44
+
45
+ @property
46
+ def additional_keys(self) -> list[str]:
47
+ return list(self.additional_properties.keys())
48
+
49
+ def __getitem__(self, key: str) -> Any:
50
+ return self.additional_properties[key]
51
+
52
+ def __setitem__(self, key: str, value: Any) -> None:
53
+ self.additional_properties[key] = value
54
+
55
+ def __delitem__(self, key: str) -> None:
56
+ del self.additional_properties[key]
57
+
58
+ def __contains__(self, key: str) -> bool:
59
+ return key in self.additional_properties
@@ -0,0 +1,105 @@
1
+ import datetime
2
+ from collections.abc import Mapping
3
+ from typing import Any, TypeVar, Union
4
+
5
+ from attrs import define as _attrs_define
6
+ from attrs import field as _attrs_field
7
+ from dateutil.parser import isoparse
8
+
9
+ from ..models.file_info_type import FileInfoType
10
+ from ..types import UNSET, Unset
11
+
12
+ T = TypeVar("T", bound="FileInfo")
13
+
14
+
15
+ @_attrs_define
16
+ class FileInfo:
17
+ """
18
+ Attributes:
19
+ name (str): File or directory name
20
+ path (str): Full path within volume
21
+ type_ (FileInfoType): Entry type
22
+ modified_at (Union[Unset, datetime.datetime]): Last modification time
23
+ size (Union[Unset, int]): File size in bytes (only for files)
24
+ """
25
+
26
+ name: str
27
+ path: str
28
+ type_: FileInfoType
29
+ modified_at: Union[Unset, datetime.datetime] = UNSET
30
+ size: Union[Unset, int] = UNSET
31
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
32
+
33
+ def to_dict(self) -> dict[str, Any]:
34
+ name = self.name
35
+
36
+ path = self.path
37
+
38
+ type_ = self.type_.value
39
+
40
+ modified_at: Union[Unset, str] = UNSET
41
+ if not isinstance(self.modified_at, Unset):
42
+ modified_at = self.modified_at.isoformat()
43
+
44
+ size = self.size
45
+
46
+ field_dict: dict[str, Any] = {}
47
+ field_dict.update(self.additional_properties)
48
+ field_dict.update(
49
+ {
50
+ "name": name,
51
+ "path": path,
52
+ "type": type_,
53
+ }
54
+ )
55
+ if modified_at is not UNSET:
56
+ field_dict["modifiedAt"] = modified_at
57
+ if size is not UNSET:
58
+ field_dict["size"] = size
59
+
60
+ return field_dict
61
+
62
+ @classmethod
63
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
64
+ d = dict(src_dict)
65
+ name = d.pop("name")
66
+
67
+ path = d.pop("path")
68
+
69
+ type_ = FileInfoType(d.pop("type"))
70
+
71
+ _modified_at = d.pop("modifiedAt", UNSET)
72
+ modified_at: Union[Unset, datetime.datetime]
73
+ if isinstance(_modified_at, Unset):
74
+ modified_at = UNSET
75
+ else:
76
+ modified_at = isoparse(_modified_at)
77
+
78
+ size = d.pop("size", UNSET)
79
+
80
+ file_info = cls(
81
+ name=name,
82
+ path=path,
83
+ type_=type_,
84
+ modified_at=modified_at,
85
+ size=size,
86
+ )
87
+
88
+ file_info.additional_properties = d
89
+ return file_info
90
+
91
+ @property
92
+ def additional_keys(self) -> list[str]:
93
+ return list(self.additional_properties.keys())
94
+
95
+ def __getitem__(self, key: str) -> Any:
96
+ return self.additional_properties[key]
97
+
98
+ def __setitem__(self, key: str, value: Any) -> None:
99
+ self.additional_properties[key] = value
100
+
101
+ def __delitem__(self, key: str) -> None:
102
+ del self.additional_properties[key]
103
+
104
+ def __contains__(self, key: str) -> bool:
105
+ return key in self.additional_properties
@@ -0,0 +1,9 @@
1
+ from enum import Enum
2
+
3
+
4
+ class FileInfoType(str, Enum):
5
+ DIRECTORY = "directory"
6
+ FILE = "file"
7
+
8
+ def __str__(self) -> str:
9
+ return str(self.value)
@@ -0,0 +1,84 @@
1
+ from collections.abc import Mapping
2
+ from typing import TYPE_CHECKING, Any, TypeVar, Union
3
+
4
+ from attrs import define as _attrs_define
5
+ from attrs import field as _attrs_field
6
+
7
+ from ..types import UNSET, Unset
8
+
9
+ if TYPE_CHECKING:
10
+ from ..models.file_info import FileInfo
11
+
12
+
13
+ T = TypeVar("T", bound="FileListResponse")
14
+
15
+
16
+ @_attrs_define
17
+ class FileListResponse:
18
+ """
19
+ Attributes:
20
+ files (list['FileInfo']):
21
+ next_token (Union[Unset, str]): Pagination token for next page
22
+ """
23
+
24
+ files: list["FileInfo"]
25
+ next_token: Union[Unset, str] = UNSET
26
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
27
+
28
+ def to_dict(self) -> dict[str, Any]:
29
+ files = []
30
+ for files_item_data in self.files:
31
+ files_item = files_item_data.to_dict()
32
+ files.append(files_item)
33
+
34
+ next_token = self.next_token
35
+
36
+ field_dict: dict[str, Any] = {}
37
+ field_dict.update(self.additional_properties)
38
+ field_dict.update(
39
+ {
40
+ "files": files,
41
+ }
42
+ )
43
+ if next_token is not UNSET:
44
+ field_dict["nextToken"] = next_token
45
+
46
+ return field_dict
47
+
48
+ @classmethod
49
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
50
+ from ..models.file_info import FileInfo
51
+
52
+ d = dict(src_dict)
53
+ files = []
54
+ _files = d.pop("files")
55
+ for files_item_data in _files:
56
+ files_item = FileInfo.from_dict(files_item_data)
57
+
58
+ files.append(files_item)
59
+
60
+ next_token = d.pop("nextToken", UNSET)
61
+
62
+ file_list_response = cls(
63
+ files=files,
64
+ next_token=next_token,
65
+ )
66
+
67
+ file_list_response.additional_properties = d
68
+ return file_list_response
69
+
70
+ @property
71
+ def additional_keys(self) -> list[str]:
72
+ return list(self.additional_properties.keys())
73
+
74
+ def __getitem__(self, key: str) -> Any:
75
+ return self.additional_properties[key]
76
+
77
+ def __setitem__(self, key: str, value: Any) -> None:
78
+ self.additional_properties[key] = value
79
+
80
+ def __delitem__(self, key: str) -> None:
81
+ del self.additional_properties[key]
82
+
83
+ def __contains__(self, key: str) -> bool:
84
+ return key in self.additional_properties
@@ -0,0 +1,9 @@
1
+ from enum import Enum
2
+
3
+
4
+ class LogsDirection(str, Enum):
5
+ BACKWARD = "backward"
6
+ FORWARD = "forward"
7
+
8
+ def __str__(self) -> str:
9
+ return str(self.value)
@@ -0,0 +1,9 @@
1
+ from enum import Enum
2
+
3
+
4
+ class LogsSource(str, Enum):
5
+ PERSISTENT = "persistent"
6
+ TEMPORARY = "temporary"
7
+
8
+ def __str__(self) -> str:
9
+ return str(self.value)
@@ -0,0 +1,83 @@
1
+ from collections.abc import Mapping
2
+ from typing import Any, TypeVar
3
+
4
+ from attrs import define as _attrs_define
5
+ from attrs import field as _attrs_field
6
+
7
+ T = TypeVar("T", bound="MachineInfo")
8
+
9
+
10
+ @_attrs_define
11
+ class MachineInfo:
12
+ """
13
+ Attributes:
14
+ cpu_architecture (str): CPU architecture of the node
15
+ cpu_family (str): CPU family of the node
16
+ cpu_model (str): CPU model of the node
17
+ cpu_model_name (str): CPU model name of the node
18
+ """
19
+
20
+ cpu_architecture: str
21
+ cpu_family: str
22
+ cpu_model: str
23
+ cpu_model_name: str
24
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
25
+
26
+ def to_dict(self) -> dict[str, Any]:
27
+ cpu_architecture = self.cpu_architecture
28
+
29
+ cpu_family = self.cpu_family
30
+
31
+ cpu_model = self.cpu_model
32
+
33
+ cpu_model_name = self.cpu_model_name
34
+
35
+ field_dict: dict[str, Any] = {}
36
+ field_dict.update(self.additional_properties)
37
+ field_dict.update(
38
+ {
39
+ "cpuArchitecture": cpu_architecture,
40
+ "cpuFamily": cpu_family,
41
+ "cpuModel": cpu_model,
42
+ "cpuModelName": cpu_model_name,
43
+ }
44
+ )
45
+
46
+ return field_dict
47
+
48
+ @classmethod
49
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
50
+ d = dict(src_dict)
51
+ cpu_architecture = d.pop("cpuArchitecture")
52
+
53
+ cpu_family = d.pop("cpuFamily")
54
+
55
+ cpu_model = d.pop("cpuModel")
56
+
57
+ cpu_model_name = d.pop("cpuModelName")
58
+
59
+ machine_info = cls(
60
+ cpu_architecture=cpu_architecture,
61
+ cpu_family=cpu_family,
62
+ cpu_model=cpu_model,
63
+ cpu_model_name=cpu_model_name,
64
+ )
65
+
66
+ machine_info.additional_properties = d
67
+ return machine_info
68
+
69
+ @property
70
+ def additional_keys(self) -> list[str]:
71
+ return list(self.additional_properties.keys())
72
+
73
+ def __getitem__(self, key: str) -> Any:
74
+ return self.additional_properties[key]
75
+
76
+ def __setitem__(self, key: str, value: Any) -> None:
77
+ self.additional_properties[key] = value
78
+
79
+ def __delitem__(self, key: str) -> None:
80
+ del self.additional_properties[key]
81
+
82
+ def __contains__(self, key: str) -> bool:
83
+ return key in self.additional_properties
@@ -28,6 +28,9 @@ class NewSandbox:
28
28
  network (Union[Unset, SandboxNetworkConfig]):
29
29
  secure (Union[Unset, bool]): Secure all system communication with sandbox
30
30
  timeout (Union[Unset, int]): Time to live for the sandbox in seconds. Default: 15.
31
+ volume_id (Union[Unset, str]): Volume ID to attach (e.g., vol_abc123). Requires volumeMountPath.
32
+ volume_mount_path (Union[Unset, str]): Mount path inside sandbox (e.g., /workspace/data). Required if volumeId
33
+ is provided. Must start with /workspace/, /data/, /mnt/, or /volumes/.
31
34
  """
32
35
 
33
36
  template_id: str
@@ -39,6 +42,8 @@ class NewSandbox:
39
42
  network: Union[Unset, "SandboxNetworkConfig"] = UNSET
40
43
  secure: Union[Unset, bool] = UNSET
41
44
  timeout: Union[Unset, int] = 15
45
+ volume_id: Union[Unset, str] = UNSET
46
+ volume_mount_path: Union[Unset, str] = UNSET
42
47
  additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
43
48
 
44
49
  def to_dict(self) -> dict[str, Any]:
@@ -70,6 +75,10 @@ class NewSandbox:
70
75
 
71
76
  timeout = self.timeout
72
77
 
78
+ volume_id = self.volume_id
79
+
80
+ volume_mount_path = self.volume_mount_path
81
+
73
82
  field_dict: dict[str, Any] = {}
74
83
  field_dict.update(self.additional_properties)
75
84
  field_dict.update(
@@ -93,6 +102,10 @@ class NewSandbox:
93
102
  field_dict["secure"] = secure
94
103
  if timeout is not UNSET:
95
104
  field_dict["timeout"] = timeout
105
+ if volume_id is not UNSET:
106
+ field_dict["volumeId"] = volume_id
107
+ if volume_mount_path is not UNSET:
108
+ field_dict["volumeMountPath"] = volume_mount_path
96
109
 
97
110
  return field_dict
98
111
 
@@ -140,6 +153,10 @@ class NewSandbox:
140
153
 
141
154
  timeout = d.pop("timeout", UNSET)
142
155
 
156
+ volume_id = d.pop("volumeId", UNSET)
157
+
158
+ volume_mount_path = d.pop("volumeMountPath", UNSET)
159
+
143
160
  new_sandbox = cls(
144
161
  template_id=template_id,
145
162
  allow_internet_access=allow_internet_access,
@@ -150,6 +167,8 @@ class NewSandbox:
150
167
  network=network,
151
168
  secure=secure,
152
169
  timeout=timeout,
170
+ volume_id=volume_id,
171
+ volume_mount_path=volume_mount_path,
153
172
  )
154
173
 
155
174
  new_sandbox.additional_properties = d