modal 1.0.3.dev10__py3-none-any.whl → 1.2.3.dev7__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.

Potentially problematic release.


This version of modal might be problematic. Click here for more details.

Files changed (160) hide show
  1. modal/__init__.py +0 -2
  2. modal/__main__.py +3 -4
  3. modal/_billing.py +80 -0
  4. modal/_clustered_functions.py +7 -3
  5. modal/_clustered_functions.pyi +15 -3
  6. modal/_container_entrypoint.py +51 -69
  7. modal/_functions.py +508 -240
  8. modal/_grpc_client.py +171 -0
  9. modal/_load_context.py +105 -0
  10. modal/_object.py +81 -21
  11. modal/_output.py +58 -45
  12. modal/_partial_function.py +48 -73
  13. modal/_pty.py +7 -3
  14. modal/_resolver.py +26 -46
  15. modal/_runtime/asgi.py +4 -3
  16. modal/_runtime/container_io_manager.py +358 -220
  17. modal/_runtime/container_io_manager.pyi +296 -101
  18. modal/_runtime/execution_context.py +18 -2
  19. modal/_runtime/execution_context.pyi +64 -7
  20. modal/_runtime/gpu_memory_snapshot.py +262 -57
  21. modal/_runtime/user_code_imports.py +28 -58
  22. modal/_serialization.py +90 -6
  23. modal/_traceback.py +42 -1
  24. modal/_tunnel.pyi +380 -12
  25. modal/_utils/async_utils.py +84 -29
  26. modal/_utils/auth_token_manager.py +111 -0
  27. modal/_utils/blob_utils.py +181 -58
  28. modal/_utils/deprecation.py +19 -0
  29. modal/_utils/function_utils.py +91 -47
  30. modal/_utils/grpc_utils.py +89 -66
  31. modal/_utils/mount_utils.py +26 -1
  32. modal/_utils/name_utils.py +17 -3
  33. modal/_utils/task_command_router_client.py +536 -0
  34. modal/_utils/time_utils.py +34 -6
  35. modal/app.py +256 -88
  36. modal/app.pyi +909 -92
  37. modal/billing.py +5 -0
  38. modal/builder/2025.06.txt +18 -0
  39. modal/builder/PREVIEW.txt +18 -0
  40. modal/builder/base-images.json +58 -0
  41. modal/cli/_download.py +19 -3
  42. modal/cli/_traceback.py +3 -2
  43. modal/cli/app.py +4 -4
  44. modal/cli/cluster.py +15 -7
  45. modal/cli/config.py +5 -3
  46. modal/cli/container.py +7 -6
  47. modal/cli/dict.py +22 -16
  48. modal/cli/entry_point.py +12 -5
  49. modal/cli/environment.py +5 -4
  50. modal/cli/import_refs.py +3 -3
  51. modal/cli/launch.py +102 -5
  52. modal/cli/network_file_system.py +11 -12
  53. modal/cli/profile.py +3 -2
  54. modal/cli/programs/launch_instance_ssh.py +94 -0
  55. modal/cli/programs/run_jupyter.py +1 -1
  56. modal/cli/programs/run_marimo.py +95 -0
  57. modal/cli/programs/vscode.py +1 -1
  58. modal/cli/queues.py +57 -26
  59. modal/cli/run.py +91 -23
  60. modal/cli/secret.py +48 -22
  61. modal/cli/token.py +7 -8
  62. modal/cli/utils.py +4 -7
  63. modal/cli/volume.py +31 -25
  64. modal/client.py +15 -85
  65. modal/client.pyi +183 -62
  66. modal/cloud_bucket_mount.py +5 -3
  67. modal/cloud_bucket_mount.pyi +197 -5
  68. modal/cls.py +200 -126
  69. modal/cls.pyi +446 -68
  70. modal/config.py +29 -11
  71. modal/container_process.py +319 -19
  72. modal/container_process.pyi +190 -20
  73. modal/dict.py +290 -71
  74. modal/dict.pyi +835 -83
  75. modal/environments.py +15 -27
  76. modal/environments.pyi +46 -24
  77. modal/exception.py +14 -2
  78. modal/experimental/__init__.py +194 -40
  79. modal/experimental/flash.py +618 -0
  80. modal/experimental/flash.pyi +380 -0
  81. modal/experimental/ipython.py +11 -7
  82. modal/file_io.py +29 -36
  83. modal/file_io.pyi +251 -53
  84. modal/file_pattern_matcher.py +56 -16
  85. modal/functions.pyi +673 -92
  86. modal/gpu.py +1 -1
  87. modal/image.py +528 -176
  88. modal/image.pyi +1572 -145
  89. modal/io_streams.py +458 -128
  90. modal/io_streams.pyi +433 -52
  91. modal/mount.py +216 -151
  92. modal/mount.pyi +225 -78
  93. modal/network_file_system.py +45 -62
  94. modal/network_file_system.pyi +277 -56
  95. modal/object.pyi +93 -17
  96. modal/parallel_map.py +942 -129
  97. modal/parallel_map.pyi +294 -15
  98. modal/partial_function.py +0 -2
  99. modal/partial_function.pyi +234 -19
  100. modal/proxy.py +17 -8
  101. modal/proxy.pyi +36 -3
  102. modal/queue.py +270 -65
  103. modal/queue.pyi +817 -57
  104. modal/runner.py +115 -101
  105. modal/runner.pyi +205 -49
  106. modal/sandbox.py +512 -136
  107. modal/sandbox.pyi +845 -111
  108. modal/schedule.py +1 -1
  109. modal/secret.py +300 -70
  110. modal/secret.pyi +589 -34
  111. modal/serving.py +7 -11
  112. modal/serving.pyi +7 -8
  113. modal/snapshot.py +11 -8
  114. modal/snapshot.pyi +25 -4
  115. modal/token_flow.py +4 -4
  116. modal/token_flow.pyi +28 -8
  117. modal/volume.py +416 -158
  118. modal/volume.pyi +1117 -121
  119. {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/METADATA +10 -9
  120. modal-1.2.3.dev7.dist-info/RECORD +195 -0
  121. modal_docs/mdmd/mdmd.py +17 -4
  122. modal_proto/api.proto +534 -79
  123. modal_proto/api_grpc.py +337 -1
  124. modal_proto/api_pb2.py +1522 -968
  125. modal_proto/api_pb2.pyi +1619 -134
  126. modal_proto/api_pb2_grpc.py +699 -4
  127. modal_proto/api_pb2_grpc.pyi +226 -14
  128. modal_proto/modal_api_grpc.py +175 -154
  129. modal_proto/sandbox_router.proto +145 -0
  130. modal_proto/sandbox_router_grpc.py +105 -0
  131. modal_proto/sandbox_router_pb2.py +149 -0
  132. modal_proto/sandbox_router_pb2.pyi +333 -0
  133. modal_proto/sandbox_router_pb2_grpc.py +203 -0
  134. modal_proto/sandbox_router_pb2_grpc.pyi +75 -0
  135. modal_proto/task_command_router.proto +144 -0
  136. modal_proto/task_command_router_grpc.py +105 -0
  137. modal_proto/task_command_router_pb2.py +149 -0
  138. modal_proto/task_command_router_pb2.pyi +333 -0
  139. modal_proto/task_command_router_pb2_grpc.py +203 -0
  140. modal_proto/task_command_router_pb2_grpc.pyi +75 -0
  141. modal_version/__init__.py +1 -1
  142. modal/requirements/PREVIEW.txt +0 -16
  143. modal/requirements/base-images.json +0 -26
  144. modal-1.0.3.dev10.dist-info/RECORD +0 -179
  145. modal_proto/modal_options_grpc.py +0 -3
  146. modal_proto/options.proto +0 -19
  147. modal_proto/options_grpc.py +0 -3
  148. modal_proto/options_pb2.py +0 -35
  149. modal_proto/options_pb2.pyi +0 -20
  150. modal_proto/options_pb2_grpc.py +0 -4
  151. modal_proto/options_pb2_grpc.pyi +0 -7
  152. /modal/{requirements → builder}/2023.12.312.txt +0 -0
  153. /modal/{requirements → builder}/2023.12.txt +0 -0
  154. /modal/{requirements → builder}/2024.04.txt +0 -0
  155. /modal/{requirements → builder}/2024.10.txt +0 -0
  156. /modal/{requirements → builder}/README.md +0 -0
  157. {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/WHEEL +0 -0
  158. {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/entry_points.txt +0 -0
  159. {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/licenses/LICENSE +0 -0
  160. {modal-1.0.3.dev10.dist-info → modal-1.2.3.dev7.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,203 @@
1
+ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2
+ """Client and server classes corresponding to protobuf-defined services."""
3
+ import grpc
4
+
5
+ from modal_proto import sandbox_router_pb2 as modal__proto_dot_sandbox__router__pb2
6
+
7
+
8
+ class SandboxRouterStub(object):
9
+ """Missing associated documentation comment in .proto file."""
10
+
11
+ def __init__(self, channel):
12
+ """Constructor.
13
+
14
+ Args:
15
+ channel: A grpc.Channel.
16
+ """
17
+ self.SandboxExecPoll = channel.unary_unary(
18
+ '/modal.sandbox_router.SandboxRouter/SandboxExecPoll',
19
+ request_serializer=modal__proto_dot_sandbox__router__pb2.SandboxExecPollRequest.SerializeToString,
20
+ response_deserializer=modal__proto_dot_sandbox__router__pb2.SandboxExecPollResponse.FromString,
21
+ )
22
+ self.SandboxExecStart = channel.unary_unary(
23
+ '/modal.sandbox_router.SandboxRouter/SandboxExecStart',
24
+ request_serializer=modal__proto_dot_sandbox__router__pb2.SandboxExecStartRequest.SerializeToString,
25
+ response_deserializer=modal__proto_dot_sandbox__router__pb2.SandboxExecStartResponse.FromString,
26
+ )
27
+ self.SandboxExecStdinWrite = channel.unary_unary(
28
+ '/modal.sandbox_router.SandboxRouter/SandboxExecStdinWrite',
29
+ request_serializer=modal__proto_dot_sandbox__router__pb2.SandboxExecStdinWriteRequest.SerializeToString,
30
+ response_deserializer=modal__proto_dot_sandbox__router__pb2.SandboxExecStdinWriteResponse.FromString,
31
+ )
32
+ self.SandboxExecStdioRead = channel.unary_stream(
33
+ '/modal.sandbox_router.SandboxRouter/SandboxExecStdioRead',
34
+ request_serializer=modal__proto_dot_sandbox__router__pb2.SandboxExecStdioReadRequest.SerializeToString,
35
+ response_deserializer=modal__proto_dot_sandbox__router__pb2.SandboxExecStdioReadResponse.FromString,
36
+ )
37
+ self.SandboxExecWait = channel.unary_unary(
38
+ '/modal.sandbox_router.SandboxRouter/SandboxExecWait',
39
+ request_serializer=modal__proto_dot_sandbox__router__pb2.SandboxExecWaitRequest.SerializeToString,
40
+ response_deserializer=modal__proto_dot_sandbox__router__pb2.SandboxExecWaitResponse.FromString,
41
+ )
42
+
43
+
44
+ class SandboxRouterServicer(object):
45
+ """Missing associated documentation comment in .proto file."""
46
+
47
+ def SandboxExecPoll(self, request, context):
48
+ """Poll for the exit status of an exec'd command.
49
+ """
50
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
51
+ context.set_details('Method not implemented!')
52
+ raise NotImplementedError('Method not implemented!')
53
+
54
+ def SandboxExecStart(self, request, context):
55
+ """Execute a command in the sandbox.
56
+ """
57
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
58
+ context.set_details('Method not implemented!')
59
+ raise NotImplementedError('Method not implemented!')
60
+
61
+ def SandboxExecStdinWrite(self, request, context):
62
+ """Write to the stdin stream of an exec'd command.
63
+ """
64
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
65
+ context.set_details('Method not implemented!')
66
+ raise NotImplementedError('Method not implemented!')
67
+
68
+ def SandboxExecStdioRead(self, request, context):
69
+ """Get a stream of output from the stdout or stderr stream of an exec'd command.
70
+ """
71
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
72
+ context.set_details('Method not implemented!')
73
+ raise NotImplementedError('Method not implemented!')
74
+
75
+ def SandboxExecWait(self, request, context):
76
+ """Wait for an exec'd command to exit and return the exit code.
77
+ """
78
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
79
+ context.set_details('Method not implemented!')
80
+ raise NotImplementedError('Method not implemented!')
81
+
82
+
83
+ def add_SandboxRouterServicer_to_server(servicer, server):
84
+ rpc_method_handlers = {
85
+ 'SandboxExecPoll': grpc.unary_unary_rpc_method_handler(
86
+ servicer.SandboxExecPoll,
87
+ request_deserializer=modal__proto_dot_sandbox__router__pb2.SandboxExecPollRequest.FromString,
88
+ response_serializer=modal__proto_dot_sandbox__router__pb2.SandboxExecPollResponse.SerializeToString,
89
+ ),
90
+ 'SandboxExecStart': grpc.unary_unary_rpc_method_handler(
91
+ servicer.SandboxExecStart,
92
+ request_deserializer=modal__proto_dot_sandbox__router__pb2.SandboxExecStartRequest.FromString,
93
+ response_serializer=modal__proto_dot_sandbox__router__pb2.SandboxExecStartResponse.SerializeToString,
94
+ ),
95
+ 'SandboxExecStdinWrite': grpc.unary_unary_rpc_method_handler(
96
+ servicer.SandboxExecStdinWrite,
97
+ request_deserializer=modal__proto_dot_sandbox__router__pb2.SandboxExecStdinWriteRequest.FromString,
98
+ response_serializer=modal__proto_dot_sandbox__router__pb2.SandboxExecStdinWriteResponse.SerializeToString,
99
+ ),
100
+ 'SandboxExecStdioRead': grpc.unary_stream_rpc_method_handler(
101
+ servicer.SandboxExecStdioRead,
102
+ request_deserializer=modal__proto_dot_sandbox__router__pb2.SandboxExecStdioReadRequest.FromString,
103
+ response_serializer=modal__proto_dot_sandbox__router__pb2.SandboxExecStdioReadResponse.SerializeToString,
104
+ ),
105
+ 'SandboxExecWait': grpc.unary_unary_rpc_method_handler(
106
+ servicer.SandboxExecWait,
107
+ request_deserializer=modal__proto_dot_sandbox__router__pb2.SandboxExecWaitRequest.FromString,
108
+ response_serializer=modal__proto_dot_sandbox__router__pb2.SandboxExecWaitResponse.SerializeToString,
109
+ ),
110
+ }
111
+ generic_handler = grpc.method_handlers_generic_handler(
112
+ 'modal.sandbox_router.SandboxRouter', rpc_method_handlers)
113
+ server.add_generic_rpc_handlers((generic_handler,))
114
+
115
+
116
+ # This class is part of an EXPERIMENTAL API.
117
+ class SandboxRouter(object):
118
+ """Missing associated documentation comment in .proto file."""
119
+
120
+ @staticmethod
121
+ def SandboxExecPoll(request,
122
+ target,
123
+ options=(),
124
+ channel_credentials=None,
125
+ call_credentials=None,
126
+ insecure=False,
127
+ compression=None,
128
+ wait_for_ready=None,
129
+ timeout=None,
130
+ metadata=None):
131
+ return grpc.experimental.unary_unary(request, target, '/modal.sandbox_router.SandboxRouter/SandboxExecPoll',
132
+ modal__proto_dot_sandbox__router__pb2.SandboxExecPollRequest.SerializeToString,
133
+ modal__proto_dot_sandbox__router__pb2.SandboxExecPollResponse.FromString,
134
+ options, channel_credentials,
135
+ insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
136
+
137
+ @staticmethod
138
+ def SandboxExecStart(request,
139
+ target,
140
+ options=(),
141
+ channel_credentials=None,
142
+ call_credentials=None,
143
+ insecure=False,
144
+ compression=None,
145
+ wait_for_ready=None,
146
+ timeout=None,
147
+ metadata=None):
148
+ return grpc.experimental.unary_unary(request, target, '/modal.sandbox_router.SandboxRouter/SandboxExecStart',
149
+ modal__proto_dot_sandbox__router__pb2.SandboxExecStartRequest.SerializeToString,
150
+ modal__proto_dot_sandbox__router__pb2.SandboxExecStartResponse.FromString,
151
+ options, channel_credentials,
152
+ insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
153
+
154
+ @staticmethod
155
+ def SandboxExecStdinWrite(request,
156
+ target,
157
+ options=(),
158
+ channel_credentials=None,
159
+ call_credentials=None,
160
+ insecure=False,
161
+ compression=None,
162
+ wait_for_ready=None,
163
+ timeout=None,
164
+ metadata=None):
165
+ return grpc.experimental.unary_unary(request, target, '/modal.sandbox_router.SandboxRouter/SandboxExecStdinWrite',
166
+ modal__proto_dot_sandbox__router__pb2.SandboxExecStdinWriteRequest.SerializeToString,
167
+ modal__proto_dot_sandbox__router__pb2.SandboxExecStdinWriteResponse.FromString,
168
+ options, channel_credentials,
169
+ insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
170
+
171
+ @staticmethod
172
+ def SandboxExecStdioRead(request,
173
+ target,
174
+ options=(),
175
+ channel_credentials=None,
176
+ call_credentials=None,
177
+ insecure=False,
178
+ compression=None,
179
+ wait_for_ready=None,
180
+ timeout=None,
181
+ metadata=None):
182
+ return grpc.experimental.unary_stream(request, target, '/modal.sandbox_router.SandboxRouter/SandboxExecStdioRead',
183
+ modal__proto_dot_sandbox__router__pb2.SandboxExecStdioReadRequest.SerializeToString,
184
+ modal__proto_dot_sandbox__router__pb2.SandboxExecStdioReadResponse.FromString,
185
+ options, channel_credentials,
186
+ insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
187
+
188
+ @staticmethod
189
+ def SandboxExecWait(request,
190
+ target,
191
+ options=(),
192
+ channel_credentials=None,
193
+ call_credentials=None,
194
+ insecure=False,
195
+ compression=None,
196
+ wait_for_ready=None,
197
+ timeout=None,
198
+ metadata=None):
199
+ return grpc.experimental.unary_unary(request, target, '/modal.sandbox_router.SandboxRouter/SandboxExecWait',
200
+ modal__proto_dot_sandbox__router__pb2.SandboxExecWaitRequest.SerializeToString,
201
+ modal__proto_dot_sandbox__router__pb2.SandboxExecWaitResponse.FromString,
202
+ options, channel_credentials,
203
+ insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@@ -0,0 +1,75 @@
1
+ """
2
+ @generated by mypy-protobuf. Do not edit manually!
3
+ isort:skip_file
4
+ """
5
+ import abc
6
+ import collections.abc
7
+ import grpc
8
+ import modal_proto.sandbox_router_pb2
9
+
10
+ class SandboxRouterStub:
11
+ def __init__(self, channel: grpc.Channel) -> None: ...
12
+ SandboxExecPoll: grpc.UnaryUnaryMultiCallable[
13
+ modal_proto.sandbox_router_pb2.SandboxExecPollRequest,
14
+ modal_proto.sandbox_router_pb2.SandboxExecPollResponse,
15
+ ]
16
+ """Poll for the exit status of an exec'd command."""
17
+ SandboxExecStart: grpc.UnaryUnaryMultiCallable[
18
+ modal_proto.sandbox_router_pb2.SandboxExecStartRequest,
19
+ modal_proto.sandbox_router_pb2.SandboxExecStartResponse,
20
+ ]
21
+ """Execute a command in the sandbox."""
22
+ SandboxExecStdinWrite: grpc.UnaryUnaryMultiCallable[
23
+ modal_proto.sandbox_router_pb2.SandboxExecStdinWriteRequest,
24
+ modal_proto.sandbox_router_pb2.SandboxExecStdinWriteResponse,
25
+ ]
26
+ """Write to the stdin stream of an exec'd command."""
27
+ SandboxExecStdioRead: grpc.UnaryStreamMultiCallable[
28
+ modal_proto.sandbox_router_pb2.SandboxExecStdioReadRequest,
29
+ modal_proto.sandbox_router_pb2.SandboxExecStdioReadResponse,
30
+ ]
31
+ """Get a stream of output from the stdout or stderr stream of an exec'd command."""
32
+ SandboxExecWait: grpc.UnaryUnaryMultiCallable[
33
+ modal_proto.sandbox_router_pb2.SandboxExecWaitRequest,
34
+ modal_proto.sandbox_router_pb2.SandboxExecWaitResponse,
35
+ ]
36
+ """Wait for an exec'd command to exit and return the exit code."""
37
+
38
+ class SandboxRouterServicer(metaclass=abc.ABCMeta):
39
+ @abc.abstractmethod
40
+ def SandboxExecPoll(
41
+ self,
42
+ request: modal_proto.sandbox_router_pb2.SandboxExecPollRequest,
43
+ context: grpc.ServicerContext,
44
+ ) -> modal_proto.sandbox_router_pb2.SandboxExecPollResponse:
45
+ """Poll for the exit status of an exec'd command."""
46
+ @abc.abstractmethod
47
+ def SandboxExecStart(
48
+ self,
49
+ request: modal_proto.sandbox_router_pb2.SandboxExecStartRequest,
50
+ context: grpc.ServicerContext,
51
+ ) -> modal_proto.sandbox_router_pb2.SandboxExecStartResponse:
52
+ """Execute a command in the sandbox."""
53
+ @abc.abstractmethod
54
+ def SandboxExecStdinWrite(
55
+ self,
56
+ request: modal_proto.sandbox_router_pb2.SandboxExecStdinWriteRequest,
57
+ context: grpc.ServicerContext,
58
+ ) -> modal_proto.sandbox_router_pb2.SandboxExecStdinWriteResponse:
59
+ """Write to the stdin stream of an exec'd command."""
60
+ @abc.abstractmethod
61
+ def SandboxExecStdioRead(
62
+ self,
63
+ request: modal_proto.sandbox_router_pb2.SandboxExecStdioReadRequest,
64
+ context: grpc.ServicerContext,
65
+ ) -> collections.abc.Iterator[modal_proto.sandbox_router_pb2.SandboxExecStdioReadResponse]:
66
+ """Get a stream of output from the stdout or stderr stream of an exec'd command."""
67
+ @abc.abstractmethod
68
+ def SandboxExecWait(
69
+ self,
70
+ request: modal_proto.sandbox_router_pb2.SandboxExecWaitRequest,
71
+ context: grpc.ServicerContext,
72
+ ) -> modal_proto.sandbox_router_pb2.SandboxExecWaitResponse:
73
+ """Wait for an exec'd command to exit and return the exit code."""
74
+
75
+ def add_SandboxRouterServicer_to_server(servicer: SandboxRouterServicer, server: grpc.Server) -> None: ...
@@ -0,0 +1,144 @@
1
+ syntax = "proto3";
2
+
3
+ option go_package = "github.com/modal-labs/modal/go/proto";
4
+
5
+ import "modal_proto/api.proto";
6
+
7
+ package modal.task_command_router;
8
+
9
+ enum TaskExecStderrConfig {
10
+ // The output will be discarded.
11
+ TASK_EXEC_STDERR_CONFIG_DEVNULL = 0;
12
+ // The output will be streamed to the client.
13
+ TASK_EXEC_STDERR_CONFIG_PIPE = 1;
14
+ // A special value that can be used to indicate that the stderr stream should
15
+ // be merged with the stdout stream.
16
+ TASK_EXEC_STDERR_CONFIG_STDOUT = 2;
17
+ }
18
+
19
+ enum TaskExecStdioFileDescriptor {
20
+ // Read from stdout.
21
+ TASK_EXEC_STDIO_FILE_DESCRIPTOR_STDOUT = 0;
22
+ // Read from stderr.
23
+ TASK_EXEC_STDIO_FILE_DESCRIPTOR_STDERR = 1;
24
+ }
25
+
26
+ enum TaskExecStdoutConfig {
27
+ // The output will be discarded.
28
+ TASK_EXEC_STDOUT_CONFIG_DEVNULL = 0;
29
+ // The output will be streamed to the client.
30
+ TASK_EXEC_STDOUT_CONFIG_PIPE = 1;
31
+ }
32
+
33
+ message TaskExecPollRequest {
34
+ // The ID of the task running the exec'd command.
35
+ string task_id = 1;
36
+ // The execution ID of the command to wait on.
37
+ string exec_id = 2;
38
+ }
39
+
40
+ // The response to a TaskExecPollRequest. If the exec'd command has not
41
+ // completed, exit_status will be unset.
42
+ message TaskExecPollResponse {
43
+ oneof exit_status {
44
+ // The exit code of the command.
45
+ int32 code = 1;
46
+ // The signal that terminated the command.
47
+ int32 signal = 2;
48
+ }
49
+ // TODO(saltzm): Give a way for the user to distinguish between normal exit
50
+ // and termination by Modal (due to task timeout, exec exceeded deadline, etc.)
51
+ }
52
+
53
+ message TaskExecStartRequest {
54
+ // The ID of the task to execute the command in.
55
+ string task_id = 1;
56
+ // Execution ID. This ID will be used to identify the execution for other
57
+ // requests and ensure exec commands are idempotent.
58
+ string exec_id = 2;
59
+ // Command arguments to execute.
60
+ repeated string command_args= 3;
61
+ // Configures how the stdout of the command will be handled.
62
+ TaskExecStdoutConfig stdout_config = 4;
63
+ // Configures how the stderr of the command will be handled.
64
+ TaskExecStderrConfig stderr_config = 5;
65
+ // Timeout in seconds for the exec'd command to exit. If the command does not
66
+ // exit within this duration, the command will be killed. This is NOT the
67
+ // timeout for the ExecStartRequest RPC to complete.
68
+ optional uint32 timeout_secs = 6;
69
+ // Working directory for the command.
70
+ optional string workdir = 7;
71
+ // Secret IDs to mount into the task.
72
+ repeated string secret_ids = 8;
73
+ // PTY info for the command.
74
+ optional modal.client.PTYInfo pty_info = 9;
75
+ // Enable debugging capabilities on the container runtime. Used only for
76
+ // internal debugging.
77
+ bool runtime_debug = 10;
78
+ }
79
+
80
+ message TaskExecStartResponse { }
81
+
82
+ message TaskExecStdinWriteRequest {
83
+ // The ID of the task running the exec'd command.
84
+ string task_id = 1;
85
+ // The execution ID of the command to write to.
86
+ string exec_id = 2;
87
+ // The offset to start writing to. This is used to resume writing from the
88
+ // last write position if the connection is closed and reopened.
89
+ uint64 offset = 3;
90
+ bytes data = 4;
91
+ // If true, close the stdin stream after writing any provided data.
92
+ // This signals EOF to the exec'd process.
93
+ bool eof = 5;
94
+ }
95
+
96
+ message TaskExecStdinWriteResponse { }
97
+
98
+ message TaskExecStdioReadRequest {
99
+ // The ID of the task running the exec'd command.
100
+ string task_id = 1;
101
+ // The execution ID of the command to read from.
102
+ string exec_id = 2;
103
+ // The offset to start reading from. This is used to resume reading from the
104
+ // last read position if the connection is closed and reopened.
105
+ uint64 offset = 3;
106
+ // Which file descriptor to read from.
107
+ TaskExecStdioFileDescriptor file_descriptor = 4;
108
+ }
109
+
110
+ message TaskExecStdioReadResponse {
111
+ // The data read from the file descriptor.
112
+ bytes data = 1;
113
+ }
114
+
115
+ message TaskExecWaitRequest {
116
+ // The ID of the task running the exec'd command.
117
+ string task_id = 1;
118
+ // The execution ID of the command to wait on.
119
+ string exec_id = 2;
120
+ }
121
+
122
+ message TaskExecWaitResponse {
123
+ oneof exit_status {
124
+ // The exit code of the command.
125
+ int32 code = 1;
126
+ // The signal that terminated the command.
127
+ int32 signal = 2;
128
+ }
129
+ // TODO(saltzm): Give a way for the user to distinguish between normal exit
130
+ // and termination by Modal (due to task timeout, exec exceeded deadline, etc.)
131
+ }
132
+
133
+ service TaskCommandRouter {
134
+ // Poll for the exit status of an exec'd command.
135
+ rpc TaskExecPoll(TaskExecPollRequest) returns (TaskExecPollResponse);
136
+ // Execute a command in the task.
137
+ rpc TaskExecStart(TaskExecStartRequest) returns (TaskExecStartResponse);
138
+ // Write to the stdin stream of an exec'd command.
139
+ rpc TaskExecStdinWrite(TaskExecStdinWriteRequest) returns (TaskExecStdinWriteResponse);
140
+ // Get a stream of output from the stdout or stderr stream of an exec'd command.
141
+ rpc TaskExecStdioRead(TaskExecStdioReadRequest) returns (stream TaskExecStdioReadResponse);
142
+ // Wait for an exec'd command to exit and return the exit code.
143
+ rpc TaskExecWait(TaskExecWaitRequest) returns (TaskExecWaitResponse);
144
+ }
@@ -0,0 +1,105 @@
1
+ # Generated by the Protocol Buffers compiler. DO NOT EDIT!
2
+ # source: modal_proto/task_command_router.proto
3
+ # plugin: grpclib.plugin.main
4
+ import abc
5
+ import typing
6
+
7
+ import grpclib.const
8
+ import grpclib.client
9
+ if typing.TYPE_CHECKING:
10
+ import grpclib.server
11
+
12
+ import modal_proto.api_pb2
13
+ import modal_proto.task_command_router_pb2
14
+
15
+
16
+ class TaskCommandRouterBase(abc.ABC):
17
+
18
+ @abc.abstractmethod
19
+ async def TaskExecPoll(self, stream: 'grpclib.server.Stream[modal_proto.task_command_router_pb2.TaskExecPollRequest, modal_proto.task_command_router_pb2.TaskExecPollResponse]') -> None:
20
+ pass
21
+
22
+ @abc.abstractmethod
23
+ async def TaskExecStart(self, stream: 'grpclib.server.Stream[modal_proto.task_command_router_pb2.TaskExecStartRequest, modal_proto.task_command_router_pb2.TaskExecStartResponse]') -> None:
24
+ pass
25
+
26
+ @abc.abstractmethod
27
+ async def TaskExecStdinWrite(self, stream: 'grpclib.server.Stream[modal_proto.task_command_router_pb2.TaskExecStdinWriteRequest, modal_proto.task_command_router_pb2.TaskExecStdinWriteResponse]') -> None:
28
+ pass
29
+
30
+ @abc.abstractmethod
31
+ async def TaskExecStdioRead(self, stream: 'grpclib.server.Stream[modal_proto.task_command_router_pb2.TaskExecStdioReadRequest, modal_proto.task_command_router_pb2.TaskExecStdioReadResponse]') -> None:
32
+ pass
33
+
34
+ @abc.abstractmethod
35
+ async def TaskExecWait(self, stream: 'grpclib.server.Stream[modal_proto.task_command_router_pb2.TaskExecWaitRequest, modal_proto.task_command_router_pb2.TaskExecWaitResponse]') -> None:
36
+ pass
37
+
38
+ def __mapping__(self) -> typing.Dict[str, grpclib.const.Handler]:
39
+ return {
40
+ '/modal.task_command_router.TaskCommandRouter/TaskExecPoll': grpclib.const.Handler(
41
+ self.TaskExecPoll,
42
+ grpclib.const.Cardinality.UNARY_UNARY,
43
+ modal_proto.task_command_router_pb2.TaskExecPollRequest,
44
+ modal_proto.task_command_router_pb2.TaskExecPollResponse,
45
+ ),
46
+ '/modal.task_command_router.TaskCommandRouter/TaskExecStart': grpclib.const.Handler(
47
+ self.TaskExecStart,
48
+ grpclib.const.Cardinality.UNARY_UNARY,
49
+ modal_proto.task_command_router_pb2.TaskExecStartRequest,
50
+ modal_proto.task_command_router_pb2.TaskExecStartResponse,
51
+ ),
52
+ '/modal.task_command_router.TaskCommandRouter/TaskExecStdinWrite': grpclib.const.Handler(
53
+ self.TaskExecStdinWrite,
54
+ grpclib.const.Cardinality.UNARY_UNARY,
55
+ modal_proto.task_command_router_pb2.TaskExecStdinWriteRequest,
56
+ modal_proto.task_command_router_pb2.TaskExecStdinWriteResponse,
57
+ ),
58
+ '/modal.task_command_router.TaskCommandRouter/TaskExecStdioRead': grpclib.const.Handler(
59
+ self.TaskExecStdioRead,
60
+ grpclib.const.Cardinality.UNARY_STREAM,
61
+ modal_proto.task_command_router_pb2.TaskExecStdioReadRequest,
62
+ modal_proto.task_command_router_pb2.TaskExecStdioReadResponse,
63
+ ),
64
+ '/modal.task_command_router.TaskCommandRouter/TaskExecWait': grpclib.const.Handler(
65
+ self.TaskExecWait,
66
+ grpclib.const.Cardinality.UNARY_UNARY,
67
+ modal_proto.task_command_router_pb2.TaskExecWaitRequest,
68
+ modal_proto.task_command_router_pb2.TaskExecWaitResponse,
69
+ ),
70
+ }
71
+
72
+
73
+ class TaskCommandRouterStub:
74
+
75
+ def __init__(self, channel: grpclib.client.Channel) -> None:
76
+ self.TaskExecPoll = grpclib.client.UnaryUnaryMethod(
77
+ channel,
78
+ '/modal.task_command_router.TaskCommandRouter/TaskExecPoll',
79
+ modal_proto.task_command_router_pb2.TaskExecPollRequest,
80
+ modal_proto.task_command_router_pb2.TaskExecPollResponse,
81
+ )
82
+ self.TaskExecStart = grpclib.client.UnaryUnaryMethod(
83
+ channel,
84
+ '/modal.task_command_router.TaskCommandRouter/TaskExecStart',
85
+ modal_proto.task_command_router_pb2.TaskExecStartRequest,
86
+ modal_proto.task_command_router_pb2.TaskExecStartResponse,
87
+ )
88
+ self.TaskExecStdinWrite = grpclib.client.UnaryUnaryMethod(
89
+ channel,
90
+ '/modal.task_command_router.TaskCommandRouter/TaskExecStdinWrite',
91
+ modal_proto.task_command_router_pb2.TaskExecStdinWriteRequest,
92
+ modal_proto.task_command_router_pb2.TaskExecStdinWriteResponse,
93
+ )
94
+ self.TaskExecStdioRead = grpclib.client.UnaryStreamMethod(
95
+ channel,
96
+ '/modal.task_command_router.TaskCommandRouter/TaskExecStdioRead',
97
+ modal_proto.task_command_router_pb2.TaskExecStdioReadRequest,
98
+ modal_proto.task_command_router_pb2.TaskExecStdioReadResponse,
99
+ )
100
+ self.TaskExecWait = grpclib.client.UnaryUnaryMethod(
101
+ channel,
102
+ '/modal.task_command_router.TaskCommandRouter/TaskExecWait',
103
+ modal_proto.task_command_router_pb2.TaskExecWaitRequest,
104
+ modal_proto.task_command_router_pb2.TaskExecWaitResponse,
105
+ )