modal 1.0.5.dev2__py3-none-any.whl → 1.0.5.dev3__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.
modal/client.pyi CHANGED
@@ -31,28 +31,94 @@ class _Client:
31
31
  server_url: str,
32
32
  client_type: int,
33
33
  credentials: typing.Optional[tuple[str, str]],
34
- version: str = "1.0.5.dev2",
35
- ): ...
34
+ version: str = "1.0.5.dev3",
35
+ ):
36
+ """mdmd:hidden
37
+ The Modal client object is not intended to be instantiated directly by users.
38
+ """
39
+ ...
40
+
36
41
  def is_closed(self) -> bool: ...
37
42
  @property
38
- def stub(self) -> modal_proto.modal_api_grpc.ModalClientModal: ...
39
- async def get_stub(self, server_url: str) -> modal_proto.modal_api_grpc.ModalClientModal: ...
43
+ def stub(self) -> modal_proto.modal_api_grpc.ModalClientModal:
44
+ """mdmd:hidden
45
+ The default stub. Stubs can safely be used across forks / client snapshots.
46
+
47
+ This is useful if you want to make requests to the default Modal server in us-east, for example
48
+ control plane requests.
49
+
50
+ This is equivalent to client.get_stub(default_server_url), but it's cached, so it's a bit faster.
51
+ """
52
+ ...
53
+
54
+ async def get_stub(self, server_url: str) -> modal_proto.modal_api_grpc.ModalClientModal:
55
+ """mdmd:hidden
56
+ Get a stub for a specific server URL. Stubs can safely be used across forks / client snapshots.
57
+
58
+ This is useful if you want to make requests to a regional Modal server, for example low-latency
59
+ function calls in us-west.
60
+
61
+ This function is O(n) where n is the number of RPCs in ModalClient.
62
+ """
63
+ ...
64
+
40
65
  async def _open(self): ...
41
66
  async def _close(self, prep_for_restore: bool = False): ...
42
- async def hello(self): ...
67
+ async def hello(self):
68
+ """Connect to server and retrieve version information; raise appropriate error for various failures."""
69
+ ...
70
+
43
71
  async def __aenter__(self): ...
44
72
  async def __aexit__(self, exc_type, exc, tb): ...
45
73
  @classmethod
46
- def anonymous(cls, server_url: str) -> typing.AsyncContextManager[_Client]: ...
74
+ def anonymous(cls, server_url: str) -> typing.AsyncContextManager[_Client]:
75
+ """mdmd:hidden
76
+ Create a connection with no credentials; to be used for token creation.
77
+ """
78
+ ...
79
+
47
80
  @classmethod
48
- async def from_env(cls, _override_config=None) -> _Client: ...
81
+ async def from_env(cls, _override_config=None) -> _Client:
82
+ """mdmd:hidden
83
+ Singleton that is instantiated from the Modal config and reused on subsequent calls.
84
+ """
85
+ ...
86
+
49
87
  @classmethod
50
- async def from_credentials(cls, token_id: str, token_secret: str) -> _Client: ...
88
+ async def from_credentials(cls, token_id: str, token_secret: str) -> _Client:
89
+ """Constructor based on token credentials; useful for managing Modal on behalf of third-party users.
90
+
91
+ **Usage:**
92
+
93
+ ```python notest
94
+ client = modal.Client.from_credentials("my_token_id", "my_token_secret")
95
+
96
+ modal.Sandbox.create("echo", "hi", client=client, app=app)
97
+ ```
98
+ """
99
+ ...
100
+
51
101
  @classmethod
52
- async def verify(cls, server_url: str, credentials: tuple[str, str]) -> None: ...
102
+ async def verify(cls, server_url: str, credentials: tuple[str, str]) -> None:
103
+ """mdmd:hidden
104
+ Check whether can the client can connect to this server with these credentials; raise if not.
105
+ """
106
+ ...
107
+
53
108
  @classmethod
54
- def set_env_client(cls, client: typing.Optional[_Client]): ...
55
- async def _call_safely(self, coro, readable_method: str): ...
109
+ def set_env_client(cls, client: typing.Optional[_Client]):
110
+ """mdmd:hidden"""
111
+ ...
112
+
113
+ async def _call_safely(self, coro, readable_method: str):
114
+ """Runs coroutine wrapped in a task that's part of the client's task context
115
+
116
+ * Raises ClientClosed in case the client is closed while the coroutine is executed
117
+ * Logs warning if call is made outside of the event loop that the client is running in,
118
+ and execute without the cancellation context in that case
119
+ """
120
+ ...
121
+
56
122
  async def _reset_on_pid_change(self): ...
57
123
  async def _get_channel(self, server_url: str) -> grpclib.client.Channel: ...
58
124
  async def _call_unary(
@@ -94,15 +160,48 @@ class Client:
94
160
  server_url: str,
95
161
  client_type: int,
96
162
  credentials: typing.Optional[tuple[str, str]],
97
- version: str = "1.0.5.dev2",
98
- ): ...
163
+ version: str = "1.0.5.dev3",
164
+ ):
165
+ """mdmd:hidden
166
+ The Modal client object is not intended to be instantiated directly by users.
167
+ """
168
+ ...
169
+
99
170
  def is_closed(self) -> bool: ...
100
171
  @property
101
- def stub(self) -> modal_proto.modal_api_grpc.ModalClientModal: ...
172
+ def stub(self) -> modal_proto.modal_api_grpc.ModalClientModal:
173
+ """mdmd:hidden
174
+ The default stub. Stubs can safely be used across forks / client snapshots.
175
+
176
+ This is useful if you want to make requests to the default Modal server in us-east, for example
177
+ control plane requests.
178
+
179
+ This is equivalent to client.get_stub(default_server_url), but it's cached, so it's a bit faster.
180
+ """
181
+ ...
102
182
 
103
183
  class __get_stub_spec(typing_extensions.Protocol[SUPERSELF]):
104
- def __call__(self, /, server_url: str) -> modal_proto.modal_api_grpc.ModalClientModal: ...
105
- async def aio(self, /, server_url: str) -> modal_proto.modal_api_grpc.ModalClientModal: ...
184
+ def __call__(self, /, server_url: str) -> modal_proto.modal_api_grpc.ModalClientModal:
185
+ """mdmd:hidden
186
+ Get a stub for a specific server URL. Stubs can safely be used across forks / client snapshots.
187
+
188
+ This is useful if you want to make requests to a regional Modal server, for example low-latency
189
+ function calls in us-west.
190
+
191
+ This function is O(n) where n is the number of RPCs in ModalClient.
192
+ """
193
+ ...
194
+
195
+ async def aio(self, /, server_url: str) -> modal_proto.modal_api_grpc.ModalClientModal:
196
+ """mdmd:hidden
197
+ Get a stub for a specific server URL. Stubs can safely be used across forks / client snapshots.
198
+
199
+ This is useful if you want to make requests to a regional Modal server, for example low-latency
200
+ function calls in us-west.
201
+
202
+ This function is O(n) where n is the number of RPCs in ModalClient.
203
+ """
204
+ ...
106
205
 
107
206
  get_stub: __get_stub_spec[typing_extensions.Self]
108
207
 
@@ -119,8 +218,13 @@ class Client:
119
218
  _close: ___close_spec[typing_extensions.Self]
120
219
 
121
220
  class __hello_spec(typing_extensions.Protocol[SUPERSELF]):
122
- def __call__(self, /): ...
123
- async def aio(self, /): ...
221
+ def __call__(self, /):
222
+ """Connect to server and retrieve version information; raise appropriate error for various failures."""
223
+ ...
224
+
225
+ async def aio(self, /):
226
+ """Connect to server and retrieve version information; raise appropriate error for various failures."""
227
+ ...
124
228
 
125
229
  hello: __hello_spec[typing_extensions.Self]
126
230
 
@@ -129,19 +233,63 @@ class Client:
129
233
  def __exit__(self, exc_type, exc, tb): ...
130
234
  async def __aexit__(self, exc_type, exc, tb): ...
131
235
  @classmethod
132
- def anonymous(cls, server_url: str) -> synchronicity.combined_types.AsyncAndBlockingContextManager[Client]: ...
236
+ def anonymous(cls, server_url: str) -> synchronicity.combined_types.AsyncAndBlockingContextManager[Client]:
237
+ """mdmd:hidden
238
+ Create a connection with no credentials; to be used for token creation.
239
+ """
240
+ ...
241
+
133
242
  @classmethod
134
- def from_env(cls, _override_config=None) -> Client: ...
243
+ def from_env(cls, _override_config=None) -> Client:
244
+ """mdmd:hidden
245
+ Singleton that is instantiated from the Modal config and reused on subsequent calls.
246
+ """
247
+ ...
248
+
135
249
  @classmethod
136
- def from_credentials(cls, token_id: str, token_secret: str) -> Client: ...
250
+ def from_credentials(cls, token_id: str, token_secret: str) -> Client:
251
+ """Constructor based on token credentials; useful for managing Modal on behalf of third-party users.
252
+
253
+ **Usage:**
254
+
255
+ ```python notest
256
+ client = modal.Client.from_credentials("my_token_id", "my_token_secret")
257
+
258
+ modal.Sandbox.create("echo", "hi", client=client, app=app)
259
+ ```
260
+ """
261
+ ...
262
+
137
263
  @classmethod
138
- def verify(cls, server_url: str, credentials: tuple[str, str]) -> None: ...
264
+ def verify(cls, server_url: str, credentials: tuple[str, str]) -> None:
265
+ """mdmd:hidden
266
+ Check whether can the client can connect to this server with these credentials; raise if not.
267
+ """
268
+ ...
269
+
139
270
  @classmethod
140
- def set_env_client(cls, client: typing.Optional[Client]): ...
271
+ def set_env_client(cls, client: typing.Optional[Client]):
272
+ """mdmd:hidden"""
273
+ ...
141
274
 
142
275
  class ___call_safely_spec(typing_extensions.Protocol[SUPERSELF]):
143
- def __call__(self, /, coro, readable_method: str): ...
144
- async def aio(self, /, coro, readable_method: str): ...
276
+ def __call__(self, /, coro, readable_method: str):
277
+ """Runs coroutine wrapped in a task that's part of the client's task context
278
+
279
+ * Raises ClientClosed in case the client is closed while the coroutine is executed
280
+ * Logs warning if call is made outside of the event loop that the client is running in,
281
+ and execute without the cancellation context in that case
282
+ """
283
+ ...
284
+
285
+ async def aio(self, /, coro, readable_method: str):
286
+ """Runs coroutine wrapped in a task that's part of the client's task context
287
+
288
+ * Raises ClientClosed in case the client is closed while the coroutine is executed
289
+ * Logs warning if call is made outside of the event loop that the client is running in,
290
+ and execute without the cancellation context in that case
291
+ """
292
+ ...
145
293
 
146
294
  _call_safely: ___call_safely_spec[typing_extensions.Self]
147
295
 
@@ -182,6 +330,26 @@ class Client:
182
330
  ) -> collections.abc.AsyncGenerator[typing.Any, None]: ...
183
331
 
184
332
  class UnaryUnaryWrapper(typing.Generic[RequestType, ResponseType]):
333
+ """Abstract base class for generic types.
334
+
335
+ A generic type is typically declared by inheriting from
336
+ this class parameterized with one or more type variables.
337
+ For example, a generic mapping type might be defined as::
338
+
339
+ class Mapping(Generic[KT, VT]):
340
+ def __getitem__(self, key: KT) -> VT:
341
+ ...
342
+ # Etc.
343
+
344
+ This class can then be used as follows::
345
+
346
+ def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:
347
+ try:
348
+ return mapping[key]
349
+ except KeyError:
350
+ return default
351
+ """
352
+
185
353
  wrapped_method: grpclib.client.UnaryUnaryMethod[RequestType, ResponseType]
186
354
  client: _Client
187
355
 
@@ -190,7 +358,10 @@ class UnaryUnaryWrapper(typing.Generic[RequestType, ResponseType]):
190
358
  wrapped_method: grpclib.client.UnaryUnaryMethod[RequestType, ResponseType],
191
359
  client: _Client,
192
360
  server_url: str,
193
- ): ...
361
+ ):
362
+ """Initialize self. See help(type(self)) for accurate signature."""
363
+ ...
364
+
194
365
  @property
195
366
  def name(self) -> str: ...
196
367
  async def __call__(
@@ -203,9 +374,31 @@ class UnaryUnaryWrapper(typing.Generic[RequestType, ResponseType]):
203
374
  collections.abc.Collection[tuple[str, typing.Union[str, bytes]]],
204
375
  None,
205
376
  ] = None,
206
- ) -> ResponseType: ...
377
+ ) -> ResponseType:
378
+ """Call self as a function."""
379
+ ...
207
380
 
208
381
  class UnaryStreamWrapper(typing.Generic[RequestType, ResponseType]):
382
+ """Abstract base class for generic types.
383
+
384
+ A generic type is typically declared by inheriting from
385
+ this class parameterized with one or more type variables.
386
+ For example, a generic mapping type might be defined as::
387
+
388
+ class Mapping(Generic[KT, VT]):
389
+ def __getitem__(self, key: KT) -> VT:
390
+ ...
391
+ # Etc.
392
+
393
+ This class can then be used as follows::
394
+
395
+ def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:
396
+ try:
397
+ return mapping[key]
398
+ except KeyError:
399
+ return default
400
+ """
401
+
209
402
  wrapped_method: grpclib.client.UnaryStreamMethod[RequestType, ResponseType]
210
403
 
211
404
  def __init__(
@@ -213,7 +406,10 @@ class UnaryStreamWrapper(typing.Generic[RequestType, ResponseType]):
213
406
  wrapped_method: grpclib.client.UnaryStreamMethod[RequestType, ResponseType],
214
407
  client: _Client,
215
408
  server_url: str,
216
- ): ...
409
+ ):
410
+ """Initialize self. See help(type(self)) for accurate signature."""
411
+ ...
412
+
217
413
  @property
218
414
  def name(self) -> str: ...
219
415
  def unary_stream(self, request, metadata: typing.Optional[typing.Any] = None): ...
@@ -3,6 +3,95 @@ import modal_proto.api_pb2
3
3
  import typing
4
4
 
5
5
  class _CloudBucketMount:
6
+ """Mounts a cloud bucket to your container. Currently supports AWS S3 buckets.
7
+
8
+ S3 buckets are mounted using [AWS S3 Mountpoint](https://github.com/awslabs/mountpoint-s3).
9
+ S3 mounts are optimized for reading large files sequentially. It does not support every file operation; consult
10
+ [the AWS S3 Mountpoint documentation](https://github.com/awslabs/mountpoint-s3/blob/main/doc/SEMANTICS.md)
11
+ for more information.
12
+
13
+ **AWS S3 Usage**
14
+
15
+ ```python
16
+ import subprocess
17
+
18
+ app = modal.App()
19
+ secret = modal.Secret.from_name(
20
+ "aws-secret",
21
+ required_keys=["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
22
+ # Note: providing AWS_REGION can help when automatic detection of the bucket region fails.
23
+ )
24
+
25
+ @app.function(
26
+ volumes={
27
+ "/my-mount": modal.CloudBucketMount(
28
+ bucket_name="s3-bucket-name",
29
+ secret=secret,
30
+ read_only=True
31
+ )
32
+ }
33
+ )
34
+ def f():
35
+ subprocess.run(["ls", "/my-mount"], check=True)
36
+ ```
37
+
38
+ **Cloudflare R2 Usage**
39
+
40
+ Cloudflare R2 is [S3-compatible](https://developers.cloudflare.com/r2/api/s3/api/) so its setup looks
41
+ very similar to S3. But additionally the `bucket_endpoint_url` argument must be passed.
42
+
43
+ ```python
44
+ import subprocess
45
+
46
+ app = modal.App()
47
+ secret = modal.Secret.from_name(
48
+ "r2-secret",
49
+ required_keys=["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
50
+ )
51
+
52
+ @app.function(
53
+ volumes={
54
+ "/my-mount": modal.CloudBucketMount(
55
+ bucket_name="my-r2-bucket",
56
+ bucket_endpoint_url="https://<ACCOUNT ID>.r2.cloudflarestorage.com",
57
+ secret=secret,
58
+ read_only=True
59
+ )
60
+ }
61
+ )
62
+ def f():
63
+ subprocess.run(["ls", "/my-mount"], check=True)
64
+ ```
65
+
66
+ **Google GCS Usage**
67
+
68
+ Google Cloud Storage (GCS) is [S3-compatible](https://cloud.google.com/storage/docs/interoperability).
69
+ GCS Buckets also require a secret with Google-specific key names (see below) populated with
70
+ a [HMAC key](https://cloud.google.com/storage/docs/authentication/managing-hmackeys#create).
71
+
72
+ ```python
73
+ import subprocess
74
+
75
+ app = modal.App()
76
+ gcp_hmac_secret = modal.Secret.from_name(
77
+ "gcp-secret",
78
+ required_keys=["GOOGLE_ACCESS_KEY_ID", "GOOGLE_ACCESS_KEY_SECRET"]
79
+ )
80
+
81
+ @app.function(
82
+ volumes={
83
+ "/my-mount": modal.CloudBucketMount(
84
+ bucket_name="my-gcs-bucket",
85
+ bucket_endpoint_url="https://storage.googleapis.com",
86
+ secret=gcp_hmac_secret,
87
+ )
88
+ }
89
+ )
90
+ def f():
91
+ subprocess.run(["ls", "/my-mount"], check=True)
92
+ ```
93
+ """
94
+
6
95
  bucket_name: str
7
96
  bucket_endpoint_url: typing.Optional[str]
8
97
  key_prefix: typing.Optional[str]
@@ -20,15 +109,114 @@ class _CloudBucketMount:
20
109
  oidc_auth_role_arn: typing.Optional[str] = None,
21
110
  read_only: bool = False,
22
111
  requester_pays: bool = False,
23
- ) -> None: ...
24
- def __repr__(self): ...
25
- def __eq__(self, other): ...
112
+ ) -> None:
113
+ """Initialize self. See help(type(self)) for accurate signature."""
114
+ ...
115
+
116
+ def __repr__(self):
117
+ """Return repr(self)."""
118
+ ...
119
+
120
+ def __eq__(self, other):
121
+ """Return self==value."""
122
+ ...
26
123
 
27
124
  def cloud_bucket_mounts_to_proto(
28
125
  mounts: list[tuple[str, _CloudBucketMount]],
29
- ) -> list[modal_proto.api_pb2.CloudBucketMount]: ...
126
+ ) -> list[modal_proto.api_pb2.CloudBucketMount]:
127
+ """Helper function to convert `CloudBucketMount` to a list of protobufs that can be passed to the server."""
128
+ ...
30
129
 
31
130
  class CloudBucketMount:
131
+ """Mounts a cloud bucket to your container. Currently supports AWS S3 buckets.
132
+
133
+ S3 buckets are mounted using [AWS S3 Mountpoint](https://github.com/awslabs/mountpoint-s3).
134
+ S3 mounts are optimized for reading large files sequentially. It does not support every file operation; consult
135
+ [the AWS S3 Mountpoint documentation](https://github.com/awslabs/mountpoint-s3/blob/main/doc/SEMANTICS.md)
136
+ for more information.
137
+
138
+ **AWS S3 Usage**
139
+
140
+ ```python
141
+ import subprocess
142
+
143
+ app = modal.App()
144
+ secret = modal.Secret.from_name(
145
+ "aws-secret",
146
+ required_keys=["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
147
+ # Note: providing AWS_REGION can help when automatic detection of the bucket region fails.
148
+ )
149
+
150
+ @app.function(
151
+ volumes={
152
+ "/my-mount": modal.CloudBucketMount(
153
+ bucket_name="s3-bucket-name",
154
+ secret=secret,
155
+ read_only=True
156
+ )
157
+ }
158
+ )
159
+ def f():
160
+ subprocess.run(["ls", "/my-mount"], check=True)
161
+ ```
162
+
163
+ **Cloudflare R2 Usage**
164
+
165
+ Cloudflare R2 is [S3-compatible](https://developers.cloudflare.com/r2/api/s3/api/) so its setup looks
166
+ very similar to S3. But additionally the `bucket_endpoint_url` argument must be passed.
167
+
168
+ ```python
169
+ import subprocess
170
+
171
+ app = modal.App()
172
+ secret = modal.Secret.from_name(
173
+ "r2-secret",
174
+ required_keys=["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
175
+ )
176
+
177
+ @app.function(
178
+ volumes={
179
+ "/my-mount": modal.CloudBucketMount(
180
+ bucket_name="my-r2-bucket",
181
+ bucket_endpoint_url="https://<ACCOUNT ID>.r2.cloudflarestorage.com",
182
+ secret=secret,
183
+ read_only=True
184
+ )
185
+ }
186
+ )
187
+ def f():
188
+ subprocess.run(["ls", "/my-mount"], check=True)
189
+ ```
190
+
191
+ **Google GCS Usage**
192
+
193
+ Google Cloud Storage (GCS) is [S3-compatible](https://cloud.google.com/storage/docs/interoperability).
194
+ GCS Buckets also require a secret with Google-specific key names (see below) populated with
195
+ a [HMAC key](https://cloud.google.com/storage/docs/authentication/managing-hmackeys#create).
196
+
197
+ ```python
198
+ import subprocess
199
+
200
+ app = modal.App()
201
+ gcp_hmac_secret = modal.Secret.from_name(
202
+ "gcp-secret",
203
+ required_keys=["GOOGLE_ACCESS_KEY_ID", "GOOGLE_ACCESS_KEY_SECRET"]
204
+ )
205
+
206
+ @app.function(
207
+ volumes={
208
+ "/my-mount": modal.CloudBucketMount(
209
+ bucket_name="my-gcs-bucket",
210
+ bucket_endpoint_url="https://storage.googleapis.com",
211
+ secret=gcp_hmac_secret,
212
+ )
213
+ }
214
+ )
215
+ def f():
216
+ subprocess.run(["ls", "/my-mount"], check=True)
217
+ ```
218
+ """
219
+
32
220
  bucket_name: str
33
221
  bucket_endpoint_url: typing.Optional[str]
34
222
  key_prefix: typing.Optional[str]