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
@@ -0,0 +1,60 @@
1
+ from dataclasses import dataclass
2
+ from enum import Enum
3
+
4
+ from moru.envd.filesystem.filesystem_pb2 import EventType
5
+
6
+
7
+ class FilesystemEventType(Enum):
8
+ """
9
+ Enum representing the type of filesystem event.
10
+ """
11
+
12
+ CHMOD = "chmod"
13
+ """
14
+ Filesystem object permissions were changed.
15
+ """
16
+ CREATE = "create"
17
+ """
18
+ Filesystem object was created.
19
+ """
20
+ REMOVE = "remove"
21
+ """
22
+ Filesystem object was removed.
23
+ """
24
+ RENAME = "rename"
25
+ """
26
+ Filesystem object was renamed.
27
+ """
28
+ WRITE = "write"
29
+ """
30
+ Filesystem object was written to.
31
+ """
32
+
33
+
34
+ def map_event_type(event: EventType):
35
+ if event == EventType.EVENT_TYPE_CHMOD:
36
+ return FilesystemEventType.CHMOD
37
+ elif event == EventType.EVENT_TYPE_CREATE:
38
+ return FilesystemEventType.CREATE
39
+ elif event == EventType.EVENT_TYPE_REMOVE:
40
+ return FilesystemEventType.REMOVE
41
+ elif event == EventType.EVENT_TYPE_RENAME:
42
+ return FilesystemEventType.RENAME
43
+ elif event == EventType.EVENT_TYPE_WRITE:
44
+ return FilesystemEventType.WRITE
45
+
46
+
47
+ @dataclass
48
+ class FilesystemEvent:
49
+ """
50
+ Contains information about the filesystem event - the name of the file and the type of the event.
51
+ """
52
+
53
+ name: str
54
+ """
55
+ Relative path to the filesystem object.
56
+ """
57
+ type: FilesystemEventType
58
+ """
59
+ Filesystem operation event type.
60
+ """
moru/sandbox/main.py ADDED
@@ -0,0 +1,210 @@
1
+ import urllib.parse
2
+ from typing import Optional, TypedDict
3
+
4
+ from packaging.version import Version
5
+
6
+ from moru.connection_config import ConnectionConfig, default_username
7
+ from moru.envd.api import ENVD_API_FILES_ROUTE
8
+ from moru.envd.versions import ENVD_DEFAULT_USER
9
+ from moru.sandbox.signature import get_signature
10
+
11
+
12
+ class SandboxOpts(TypedDict):
13
+ sandbox_id: str
14
+ sandbox_domain: Optional[str]
15
+ envd_version: Version
16
+ envd_access_token: Optional[str]
17
+ sandbox_url: Optional[str]
18
+ traffic_access_token: Optional[str]
19
+ connection_config: ConnectionConfig
20
+
21
+
22
+ class SandboxBase:
23
+ mcp_port = 50005
24
+
25
+ default_sandbox_timeout = 300
26
+
27
+ default_template = "base"
28
+ default_mcp_template = "mcp-gateway"
29
+
30
+ def __init__(
31
+ self,
32
+ sandbox_id: str,
33
+ envd_version: Version,
34
+ envd_access_token: Optional[str],
35
+ sandbox_domain: Optional[str],
36
+ connection_config: ConnectionConfig,
37
+ traffic_access_token: Optional[str] = None,
38
+ ):
39
+ self.__connection_config = connection_config
40
+ self.__sandbox_id = sandbox_id
41
+ self.__sandbox_domain = sandbox_domain or self.connection_config.domain
42
+ self.__envd_version = envd_version
43
+ self.__envd_access_token = envd_access_token
44
+ self.__traffic_access_token = traffic_access_token
45
+ self.__envd_api_url = self.connection_config.get_sandbox_url(
46
+ self.sandbox_id, self.sandbox_domain
47
+ )
48
+ self.__mcp_token: Optional[str] = None
49
+
50
+ @property
51
+ def _envd_access_token(self) -> Optional[str]:
52
+ """Private property to access the envd token"""
53
+ return self.__envd_access_token
54
+
55
+ @property
56
+ def _mcp_token(self) -> Optional[str]:
57
+ return self.__mcp_token
58
+
59
+ @_mcp_token.setter
60
+ def _mcp_token(self, token: str) -> None:
61
+ self.__mcp_token = token
62
+
63
+ @property
64
+ def connection_config(self) -> ConnectionConfig:
65
+ return self.__connection_config
66
+
67
+ @property
68
+ def _envd_version(self) -> Version:
69
+ return self.__envd_version
70
+
71
+ @property
72
+ def traffic_access_token(self) -> Optional[str]:
73
+ return self.__traffic_access_token
74
+
75
+ @property
76
+ def sandbox_domain(self) -> Optional[str]:
77
+ return self.__sandbox_domain
78
+
79
+ @property
80
+ def envd_api_url(self) -> str:
81
+ return self.__envd_api_url
82
+
83
+ @property
84
+ def sandbox_id(self) -> str:
85
+ """
86
+ Unique identifier of the sandbox.
87
+ """
88
+ return self.__sandbox_id
89
+
90
+ def _file_url(
91
+ self,
92
+ path: str,
93
+ user: Optional[str] = None,
94
+ signature: Optional[str] = None,
95
+ signature_expiration: Optional[int] = None,
96
+ ) -> str:
97
+ url = urllib.parse.urljoin(self.envd_api_url, ENVD_API_FILES_ROUTE)
98
+ query = {"path": path} if path else {}
99
+
100
+ if user:
101
+ query["username"] = user
102
+
103
+ if signature:
104
+ query["signature"] = signature
105
+
106
+ if signature_expiration:
107
+ if signature is None:
108
+ raise ValueError("signature_expiration requires signature to be set")
109
+ query["signature_expiration"] = str(signature_expiration)
110
+
111
+ params = urllib.parse.urlencode(
112
+ query,
113
+ quote_via=urllib.parse.quote,
114
+ )
115
+ url = urllib.parse.urljoin(url, f"?{params}")
116
+
117
+ return url
118
+
119
+ def download_url(
120
+ self,
121
+ path: str,
122
+ user: Optional[str] = None,
123
+ use_signature_expiration: Optional[int] = None,
124
+ ) -> str:
125
+ """
126
+ Get the URL to download a file from the sandbox.
127
+
128
+ :param path: Path to the file to download
129
+ :param user: User to download the file as
130
+ :param use_signature_expiration: Expiration time for the signed URL in seconds
131
+
132
+ :return: URL for downloading file
133
+ """
134
+
135
+ username = user
136
+ if username is None and self._envd_version < ENVD_DEFAULT_USER:
137
+ username = default_username
138
+
139
+ use_signature = self._envd_access_token is not None
140
+ if use_signature:
141
+ signature = get_signature(
142
+ path,
143
+ "read",
144
+ username,
145
+ self._envd_access_token,
146
+ use_signature_expiration,
147
+ )
148
+ return self._file_url(
149
+ path, username, signature["signature"], signature["expiration"]
150
+ )
151
+ else:
152
+ return self._file_url(path, username)
153
+
154
+ def upload_url(
155
+ self,
156
+ path: str,
157
+ user: Optional[str] = None,
158
+ use_signature_expiration: Optional[int] = None,
159
+ ) -> str:
160
+ """
161
+ Get the URL to upload a file to the sandbox.
162
+
163
+ You have to send a POST request to this URL with the file as multipart/form-data.
164
+
165
+ :param path: Path to the file to upload
166
+ :param user: User to upload the file as
167
+ :param use_signature_expiration: Expiration time for the signed URL in seconds
168
+
169
+ :return: URL for uploading file
170
+ """
171
+
172
+ username = user
173
+ if username is None and self._envd_version < ENVD_DEFAULT_USER:
174
+ username = default_username
175
+
176
+ use_signature = self._envd_access_token is not None
177
+ if use_signature:
178
+ signature = get_signature(
179
+ path,
180
+ "write",
181
+ username,
182
+ self._envd_access_token,
183
+ use_signature_expiration,
184
+ )
185
+ return self._file_url(
186
+ path, username, signature["signature"], signature["expiration"]
187
+ )
188
+ else:
189
+ return self._file_url(path, username)
190
+
191
+ def get_host(self, port: int) -> str:
192
+ """
193
+ Get the host address to connect to the sandbox.
194
+ You can then use this address to connect to the sandbox port from outside the sandbox via HTTP or WebSocket.
195
+
196
+ :param port: Port to connect to
197
+
198
+ :return: Host address to connect to
199
+ """
200
+ return self.connection_config.get_host(
201
+ self.sandbox_id, self.sandbox_domain, port
202
+ )
203
+
204
+ def get_mcp_url(self) -> str:
205
+ """
206
+ Get the MCP URL for the sandbox.
207
+
208
+ :returns MCP URL for the sandbox.
209
+ """
210
+ return f"https://{self.get_host(self.mcp_port)}/mcp"