modal 0.72.4__py3-none-any.whl → 0.72.48__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 (73) hide show
  1. modal/_container_entrypoint.py +5 -10
  2. modal/_object.py +297 -0
  3. modal/_resolver.py +7 -5
  4. modal/_runtime/container_io_manager.py +0 -11
  5. modal/_runtime/user_code_imports.py +7 -7
  6. modal/_serialization.py +4 -3
  7. modal/_tunnel.py +1 -1
  8. modal/app.py +14 -61
  9. modal/app.pyi +25 -25
  10. modal/cli/app.py +3 -2
  11. modal/cli/container.py +1 -1
  12. modal/cli/import_refs.py +185 -113
  13. modal/cli/launch.py +10 -5
  14. modal/cli/programs/run_jupyter.py +2 -2
  15. modal/cli/programs/vscode.py +3 -3
  16. modal/cli/run.py +134 -68
  17. modal/client.py +1 -0
  18. modal/client.pyi +18 -14
  19. modal/cloud_bucket_mount.py +4 -0
  20. modal/cloud_bucket_mount.pyi +4 -0
  21. modal/cls.py +33 -5
  22. modal/cls.pyi +20 -5
  23. modal/container_process.pyi +8 -6
  24. modal/dict.py +1 -1
  25. modal/dict.pyi +32 -29
  26. modal/environments.py +1 -1
  27. modal/environments.pyi +2 -1
  28. modal/experimental.py +47 -11
  29. modal/experimental.pyi +29 -0
  30. modal/file_io.pyi +30 -28
  31. modal/file_pattern_matcher.py +32 -25
  32. modal/functions.py +31 -23
  33. modal/functions.pyi +57 -50
  34. modal/gpu.py +19 -26
  35. modal/image.py +47 -19
  36. modal/image.pyi +28 -21
  37. modal/io_streams.pyi +14 -12
  38. modal/mount.py +14 -5
  39. modal/mount.pyi +28 -25
  40. modal/network_file_system.py +7 -7
  41. modal/network_file_system.pyi +27 -24
  42. modal/object.py +2 -265
  43. modal/object.pyi +46 -130
  44. modal/parallel_map.py +2 -2
  45. modal/parallel_map.pyi +10 -7
  46. modal/partial_function.py +22 -3
  47. modal/partial_function.pyi +45 -27
  48. modal/proxy.py +1 -1
  49. modal/proxy.pyi +2 -1
  50. modal/queue.py +1 -1
  51. modal/queue.pyi +26 -23
  52. modal/runner.py +14 -3
  53. modal/sandbox.py +11 -7
  54. modal/sandbox.pyi +30 -27
  55. modal/secret.py +1 -1
  56. modal/secret.pyi +2 -1
  57. modal/token_flow.pyi +6 -4
  58. modal/volume.py +1 -1
  59. modal/volume.pyi +36 -33
  60. {modal-0.72.4.dist-info → modal-0.72.48.dist-info}/METADATA +2 -2
  61. {modal-0.72.4.dist-info → modal-0.72.48.dist-info}/RECORD +73 -71
  62. modal_proto/api.proto +151 -4
  63. modal_proto/api_grpc.py +113 -0
  64. modal_proto/api_pb2.py +998 -795
  65. modal_proto/api_pb2.pyi +430 -11
  66. modal_proto/api_pb2_grpc.py +233 -1
  67. modal_proto/api_pb2_grpc.pyi +75 -3
  68. modal_proto/modal_api_grpc.py +7 -0
  69. modal_version/_version_generated.py +1 -1
  70. {modal-0.72.4.dist-info → modal-0.72.48.dist-info}/LICENSE +0 -0
  71. {modal-0.72.4.dist-info → modal-0.72.48.dist-info}/WHEEL +0 -0
  72. {modal-0.72.4.dist-info → modal-0.72.48.dist-info}/entry_points.txt +0 -0
  73. {modal-0.72.4.dist-info → modal-0.72.48.dist-info}/top_level.txt +0 -0
modal/object.pyi CHANGED
@@ -5,117 +5,30 @@ import modal.client
5
5
  import typing
6
6
  import typing_extensions
7
7
 
8
- O = typing.TypeVar("O", bound="_Object")
9
-
10
- _BLOCKING_O = typing.TypeVar("_BLOCKING_O", bound="Object")
11
-
12
- def _get_environment_name(
13
- environment_name: typing.Optional[str] = None, resolver: typing.Optional[modal._resolver.Resolver] = None
14
- ) -> typing.Optional[str]: ...
15
-
16
- class _Object:
17
- _type_prefix: typing.ClassVar[typing.Optional[str]]
18
- _prefix_to_type: typing.ClassVar[dict[str, type]]
19
- _load: typing.Optional[
20
- typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
21
- ]
22
- _preload: typing.Optional[
23
- typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
24
- ]
25
- _rep: str
26
- _is_another_app: bool
27
- _hydrate_lazily: bool
28
- _deps: typing.Optional[typing.Callable[..., list[_Object]]]
29
- _deduplication_key: typing.Optional[typing.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]]
30
- _object_id: str
31
- _client: modal.client._Client
32
- _is_hydrated: bool
33
- _is_rehydrated: bool
34
-
35
- @classmethod
36
- def __init_subclass__(cls, type_prefix: typing.Optional[str] = None): ...
37
- def __init__(self, *args, **kwargs): ...
38
- def _init(
39
- self,
40
- rep: str,
41
- load: typing.Optional[
42
- typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
43
- ] = None,
44
- is_another_app: bool = False,
45
- preload: typing.Optional[
46
- typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
47
- ] = None,
48
- hydrate_lazily: bool = False,
49
- deps: typing.Optional[typing.Callable[..., list[_Object]]] = None,
50
- deduplication_key: typing.Optional[
51
- typing.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]
52
- ] = None,
53
- ): ...
54
- def _unhydrate(self): ...
55
- def _initialize_from_empty(self): ...
56
- def _initialize_from_other(self, other): ...
57
- def _hydrate(
58
- self, object_id: str, client: modal.client._Client, metadata: typing.Optional[google.protobuf.message.Message]
59
- ): ...
60
- def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
61
- def _get_metadata(self) -> typing.Optional[google.protobuf.message.Message]: ...
62
- def _validate_is_hydrated(self: O): ...
63
- def clone(self: O) -> O: ...
64
- @classmethod
65
- def _from_loader(
66
- cls,
67
- load: typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]],
68
- rep: str,
69
- is_another_app: bool = False,
70
- preload: typing.Optional[
71
- typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
72
- ] = None,
73
- hydrate_lazily: bool = False,
74
- deps: typing.Optional[typing.Callable[..., collections.abc.Sequence[_Object]]] = None,
75
- deduplication_key: typing.Optional[
76
- typing.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]
77
- ] = None,
78
- ): ...
79
- @classmethod
80
- def _get_type_from_id(cls: type[O], object_id: str) -> type[O]: ...
81
- @classmethod
82
- def _is_id_type(cls: type[O], object_id) -> bool: ...
83
- @classmethod
84
- def _new_hydrated(
85
- cls: type[O],
86
- object_id: str,
87
- client: modal.client._Client,
88
- handle_metadata: typing.Optional[google.protobuf.message.Message],
89
- is_another_app: bool = False,
90
- ) -> O: ...
91
- def _hydrate_from_other(self, other: O): ...
92
- def __repr__(self): ...
93
- @property
94
- def local_uuid(self): ...
95
- @property
96
- def object_id(self) -> str: ...
97
- @property
98
- def is_hydrated(self) -> bool: ...
99
- @property
100
- def deps(self) -> typing.Callable[..., list[_Object]]: ...
101
- async def resolve(self, client: typing.Optional[modal.client._Client] = None): ...
8
+ SUPERSELF = typing.TypeVar("SUPERSELF", covariant=True)
102
9
 
103
10
  class Object:
104
11
  _type_prefix: typing.ClassVar[typing.Optional[str]]
105
12
  _prefix_to_type: typing.ClassVar[dict[str, type]]
106
13
  _load: typing.Optional[
107
- typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
14
+ collections.abc.Callable[
15
+ [typing_extensions.Self, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]
16
+ ]
108
17
  ]
109
18
  _preload: typing.Optional[
110
- typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
19
+ collections.abc.Callable[
20
+ [typing_extensions.Self, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]
21
+ ]
111
22
  ]
112
23
  _rep: str
113
24
  _is_another_app: bool
114
25
  _hydrate_lazily: bool
115
- _deps: typing.Optional[typing.Callable[..., list[Object]]]
116
- _deduplication_key: typing.Optional[typing.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]]
117
- _object_id: str
118
- _client: modal.client.Client
26
+ _deps: typing.Optional[collections.abc.Callable[..., collections.abc.Sequence[Object]]]
27
+ _deduplication_key: typing.Optional[
28
+ collections.abc.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]
29
+ ]
30
+ _object_id: typing.Optional[str]
31
+ _client: typing.Optional[modal.client.Client]
119
32
  _is_hydrated: bool
120
33
  _is_rehydrated: bool
121
34
 
@@ -123,43 +36,43 @@ class Object:
123
36
  @classmethod
124
37
  def __init_subclass__(cls, type_prefix: typing.Optional[str] = None): ...
125
38
 
126
- class ___init_spec(typing_extensions.Protocol):
39
+ class ___init_spec(typing_extensions.Protocol[SUPERSELF]):
127
40
  def __call__(
128
41
  self,
129
42
  rep: str,
130
43
  load: typing.Optional[
131
- typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], None]
44
+ collections.abc.Callable[[SUPERSELF, modal._resolver.Resolver, typing.Optional[str]], None]
132
45
  ] = None,
133
46
  is_another_app: bool = False,
134
47
  preload: typing.Optional[
135
- typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], None]
48
+ collections.abc.Callable[[SUPERSELF, modal._resolver.Resolver, typing.Optional[str]], None]
136
49
  ] = None,
137
50
  hydrate_lazily: bool = False,
138
- deps: typing.Optional[typing.Callable[..., list[Object]]] = None,
139
- deduplication_key: typing.Optional[typing.Callable[[], collections.abc.Hashable]] = None,
51
+ deps: typing.Optional[collections.abc.Callable[..., collections.abc.Sequence[Object]]] = None,
52
+ deduplication_key: typing.Optional[collections.abc.Callable[[], collections.abc.Hashable]] = None,
140
53
  ): ...
141
54
  def aio(
142
55
  self,
143
56
  rep: str,
144
57
  load: typing.Optional[
145
- typing.Callable[
146
- [_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]
58
+ collections.abc.Callable[
59
+ [SUPERSELF, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]
147
60
  ]
148
61
  ] = None,
149
62
  is_another_app: bool = False,
150
63
  preload: typing.Optional[
151
- typing.Callable[
152
- [_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]
64
+ collections.abc.Callable[
65
+ [SUPERSELF, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]
153
66
  ]
154
67
  ] = None,
155
68
  hydrate_lazily: bool = False,
156
- deps: typing.Optional[typing.Callable[..., list[Object]]] = None,
69
+ deps: typing.Optional[collections.abc.Callable[..., collections.abc.Sequence[Object]]] = None,
157
70
  deduplication_key: typing.Optional[
158
- typing.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]
71
+ collections.abc.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]
159
72
  ] = None,
160
73
  ): ...
161
74
 
162
- _init: ___init_spec
75
+ _init: ___init_spec[typing_extensions.Self]
163
76
 
164
77
  def _unhydrate(self): ...
165
78
  def _initialize_from_empty(self): ...
@@ -169,51 +82,54 @@ class Object:
169
82
  ): ...
170
83
  def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
171
84
  def _get_metadata(self) -> typing.Optional[google.protobuf.message.Message]: ...
172
- def _validate_is_hydrated(self: _BLOCKING_O): ...
173
- def clone(self: _BLOCKING_O) -> _BLOCKING_O: ...
85
+ def _validate_is_hydrated(self): ...
86
+ def clone(self) -> typing_extensions.Self: ...
174
87
  @classmethod
175
88
  def _from_loader(
176
89
  cls,
177
- load: typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], None],
90
+ load: collections.abc.Callable[[typing_extensions.Self, modal._resolver.Resolver, typing.Optional[str]], None],
178
91
  rep: str,
179
92
  is_another_app: bool = False,
180
93
  preload: typing.Optional[
181
- typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], None]
94
+ collections.abc.Callable[[typing_extensions.Self, modal._resolver.Resolver, typing.Optional[str]], None]
182
95
  ] = None,
183
96
  hydrate_lazily: bool = False,
184
- deps: typing.Optional[typing.Callable[..., collections.abc.Sequence[Object]]] = None,
185
- deduplication_key: typing.Optional[typing.Callable[[], collections.abc.Hashable]] = None,
97
+ deps: typing.Optional[collections.abc.Callable[..., collections.abc.Sequence[Object]]] = None,
98
+ deduplication_key: typing.Optional[collections.abc.Callable[[], collections.abc.Hashable]] = None,
186
99
  ): ...
100
+ @staticmethod
101
+ def _get_type_from_id(object_id: str) -> type[Object]: ...
187
102
  @classmethod
188
- def _get_type_from_id(cls: type[_BLOCKING_O], object_id: str) -> type[_BLOCKING_O]: ...
189
- @classmethod
190
- def _is_id_type(cls: type[_BLOCKING_O], object_id) -> bool: ...
103
+ def _is_id_type(cls, object_id) -> bool: ...
191
104
  @classmethod
192
105
  def _new_hydrated(
193
- cls: type[_BLOCKING_O],
106
+ cls,
194
107
  object_id: str,
195
108
  client: modal.client.Client,
196
109
  handle_metadata: typing.Optional[google.protobuf.message.Message],
197
110
  is_another_app: bool = False,
198
- ) -> _BLOCKING_O: ...
199
- def _hydrate_from_other(self, other: _BLOCKING_O): ...
111
+ ) -> typing_extensions.Self: ...
112
+ def _hydrate_from_other(self, other: typing_extensions.Self): ...
200
113
  def __repr__(self): ...
201
114
  @property
202
115
  def local_uuid(self): ...
203
116
  @property
204
117
  def object_id(self) -> str: ...
205
118
  @property
119
+ def client(self) -> modal.client.Client: ...
120
+ @property
206
121
  def is_hydrated(self) -> bool: ...
207
122
  @property
208
- def deps(self) -> typing.Callable[..., list[Object]]: ...
123
+ def deps(self) -> collections.abc.Callable[..., collections.abc.Sequence[Object]]: ...
209
124
 
210
- class __resolve_spec(typing_extensions.Protocol):
125
+ class __resolve_spec(typing_extensions.Protocol[SUPERSELF]):
211
126
  def __call__(self, client: typing.Optional[modal.client.Client] = None): ...
212
127
  async def aio(self, client: typing.Optional[modal.client.Client] = None): ...
213
128
 
214
- resolve: __resolve_spec
129
+ resolve: __resolve_spec[typing_extensions.Self]
215
130
 
216
- def live_method(method): ...
217
- def live_method_gen(method): ...
131
+ class __hydrate_spec(typing_extensions.Protocol[SUPERSELF]):
132
+ def __call__(self, client: typing.Optional[modal.client.Client] = None) -> SUPERSELF: ...
133
+ async def aio(self, client: typing.Optional[modal.client.Client] = None) -> SUPERSELF: ...
218
134
 
219
- EPHEMERAL_OBJECT_HEARTBEAT_SLEEP: int
135
+ hydrate: __hydrate_spec[typing_extensions.Self]
modal/parallel_map.py CHANGED
@@ -151,8 +151,8 @@ async def _map_invocation(
151
151
  if err.status != Status.RESOURCE_EXHAUSTED:
152
152
  raise err
153
153
  logger.warning(
154
- "Warning: map progress is limited. Common bottlenecks "
155
- "include slow iteration over results, or function backlogs."
154
+ f"Warning: map progress for function {function._function_name} is limited."
155
+ " Common bottlenecks include slow iteration over results, or function backlogs."
156
156
  )
157
157
 
158
158
  count_update()
modal/parallel_map.pyi CHANGED
@@ -1,3 +1,4 @@
1
+ import collections.abc
1
2
  import modal._utils.async_utils
2
3
  import modal.client
3
4
  import modal.functions
@@ -9,26 +10,28 @@ class _SynchronizedQueue:
9
10
  async def put(self, item): ...
10
11
  async def get(self): ...
11
12
 
13
+ SUPERSELF = typing.TypeVar("SUPERSELF", covariant=True)
14
+
12
15
  class SynchronizedQueue:
13
16
  def __init__(self, /, *args, **kwargs): ...
14
17
 
15
- class __init_spec(typing_extensions.Protocol):
18
+ class __init_spec(typing_extensions.Protocol[SUPERSELF]):
16
19
  def __call__(self): ...
17
20
  async def aio(self): ...
18
21
 
19
- init: __init_spec
22
+ init: __init_spec[typing_extensions.Self]
20
23
 
21
- class __put_spec(typing_extensions.Protocol):
24
+ class __put_spec(typing_extensions.Protocol[SUPERSELF]):
22
25
  def __call__(self, item): ...
23
26
  async def aio(self, item): ...
24
27
 
25
- put: __put_spec
28
+ put: __put_spec[typing_extensions.Self]
26
29
 
27
- class __get_spec(typing_extensions.Protocol):
30
+ class __get_spec(typing_extensions.Protocol[SUPERSELF]):
28
31
  def __call__(self): ...
29
32
  async def aio(self): ...
30
33
 
31
- get: __get_spec
34
+ get: __get_spec[typing_extensions.Self]
32
35
 
33
36
  class _OutputValue:
34
37
  value: typing.Any
@@ -43,7 +46,7 @@ def _map_invocation(
43
46
  client: modal.client._Client,
44
47
  order_outputs: bool,
45
48
  return_exceptions: bool,
46
- count_update_callback: typing.Optional[typing.Callable[[int, int], None]],
49
+ count_update_callback: typing.Optional[collections.abc.Callable[[int, int], None]],
47
50
  ): ...
48
51
  def _map_sync(
49
52
  self, *input_iterators, kwargs={}, order_outputs: bool = True, return_exceptions: bool = False
modal/partial_function.py CHANGED
@@ -89,6 +89,14 @@ class _PartialFunction(typing.Generic[P, ReturnType, OriginalReturnType]):
89
89
  self.force_build = force_build
90
90
  self.build_timeout = build_timeout
91
91
 
92
+ def _get_raw_f(self) -> Callable[P, ReturnType]:
93
+ return self.raw_f
94
+
95
+ def _is_web_endpoint(self) -> bool:
96
+ if self.webhook_config is None:
97
+ return False
98
+ return self.webhook_config.type != api_pb2.WEBHOOK_TYPE_UNSPECIFIED
99
+
92
100
  def __get__(self, obj, objtype=None) -> _Function[P, ReturnType, OriginalReturnType]:
93
101
  k = self.raw_f.__name__
94
102
  if obj: # accessing the method on an instance of a class, e.g. `MyClass().fun``
@@ -530,10 +538,12 @@ def _build(
530
538
  _warn_parentheses_missing=None, *, force: bool = False, timeout: int = 86400
531
539
  ) -> Callable[[Union[Callable[[Any], Any], _PartialFunction]], _PartialFunction]:
532
540
  """
533
- Decorator for methods that should execute at _build time_ to create a new layer
534
- in a `modal.Image`.
541
+ Decorator for methods that execute at _build time_ to create a new Image layer.
535
542
 
536
- See the [lifeycle function guide](https://modal.com/docs/guide/lifecycle-functions#build) for more information.
543
+ **Deprecated**: This function is deprecated. We recommend using `modal.Volume`
544
+ to store large assets (such as model weights) instead of writing them to the
545
+ Image during the build process. For other use cases, you can replace this
546
+ decorator with the `Image.run_function` method.
537
547
 
538
548
  **Usage**
539
549
 
@@ -552,6 +562,15 @@ def _build(
552
562
  if _warn_parentheses_missing is not None:
553
563
  raise InvalidError("Positional arguments are not allowed. Did you forget parentheses? Suggestion: `@build()`.")
554
564
 
565
+ deprecation_warning(
566
+ (2025, 1, 15),
567
+ "The `@modal.build` decorator is deprecated and will be removed in a future release."
568
+ "\n\nWe now recommend storing large assets (such as model weights) using a `modal.Volume`"
569
+ " instead of writing them directly into the `modal.Image` filesystem."
570
+ " For other use cases we recommend using `Image.run_function` instead."
571
+ "\n\nSee https://modal.com/docs/guide/modal-1-0-migration for more information.",
572
+ )
573
+
555
574
  def wrapper(f: Union[Callable[[Any], Any], _PartialFunction]) -> _PartialFunction:
556
575
  if isinstance(f, _PartialFunction):
557
576
  _disallow_wrapping_method(f, "build")
@@ -25,7 +25,7 @@ ReturnType = typing.TypeVar("ReturnType", covariant=True)
25
25
  OriginalReturnType = typing.TypeVar("OriginalReturnType", covariant=True)
26
26
 
27
27
  class _PartialFunction(typing.Generic[P, ReturnType, OriginalReturnType]):
28
- raw_f: typing.Callable[P, ReturnType]
28
+ raw_f: collections.abc.Callable[P, ReturnType]
29
29
  flags: _PartialFunctionFlags
30
30
  webhook_config: typing.Optional[modal_proto.api_pb2.WebhookConfig]
31
31
  is_generator: bool
@@ -38,7 +38,7 @@ class _PartialFunction(typing.Generic[P, ReturnType, OriginalReturnType]):
38
38
 
39
39
  def __init__(
40
40
  self,
41
- raw_f: typing.Callable[P, ReturnType],
41
+ raw_f: collections.abc.Callable[P, ReturnType],
42
42
  flags: _PartialFunctionFlags,
43
43
  webhook_config: typing.Optional[modal_proto.api_pb2.WebhookConfig] = None,
44
44
  is_generator: typing.Optional[bool] = None,
@@ -49,12 +49,14 @@ class _PartialFunction(typing.Generic[P, ReturnType, OriginalReturnType]):
49
49
  force_build: bool = False,
50
50
  build_timeout: typing.Optional[int] = None,
51
51
  ): ...
52
+ def _get_raw_f(self) -> collections.abc.Callable[P, ReturnType]: ...
53
+ def _is_web_endpoint(self) -> bool: ...
52
54
  def __get__(self, obj, objtype=None) -> modal.functions._Function[P, ReturnType, OriginalReturnType]: ...
53
55
  def __del__(self): ...
54
56
  def add_flags(self, flags) -> _PartialFunction: ...
55
57
 
56
58
  class PartialFunction(typing.Generic[P, ReturnType, OriginalReturnType]):
57
- raw_f: typing.Callable[P, ReturnType]
59
+ raw_f: collections.abc.Callable[P, ReturnType]
58
60
  flags: _PartialFunctionFlags
59
61
  webhook_config: typing.Optional[modal_proto.api_pb2.WebhookConfig]
60
62
  is_generator: bool
@@ -67,7 +69,7 @@ class PartialFunction(typing.Generic[P, ReturnType, OriginalReturnType]):
67
69
 
68
70
  def __init__(
69
71
  self,
70
- raw_f: typing.Callable[P, ReturnType],
72
+ raw_f: collections.abc.Callable[P, ReturnType],
71
73
  flags: _PartialFunctionFlags,
72
74
  webhook_config: typing.Optional[modal_proto.api_pb2.WebhookConfig] = None,
73
75
  is_generator: typing.Optional[bool] = None,
@@ -78,12 +80,16 @@ class PartialFunction(typing.Generic[P, ReturnType, OriginalReturnType]):
78
80
  force_build: bool = False,
79
81
  build_timeout: typing.Optional[int] = None,
80
82
  ): ...
83
+ def _get_raw_f(self) -> collections.abc.Callable[P, ReturnType]: ...
84
+ def _is_web_endpoint(self) -> bool: ...
81
85
  def __get__(self, obj, objtype=None) -> modal.functions.Function[P, ReturnType, OriginalReturnType]: ...
82
86
  def __del__(self): ...
83
87
  def add_flags(self, flags) -> PartialFunction: ...
84
88
 
85
89
  def _find_partial_methods_for_user_cls(user_cls: type[typing.Any], flags: int) -> dict[str, _PartialFunction]: ...
86
- def _find_callables_for_obj(user_obj: typing.Any, flags: int) -> dict[str, typing.Callable[..., typing.Any]]: ...
90
+ def _find_callables_for_obj(
91
+ user_obj: typing.Any, flags: int
92
+ ) -> dict[str, collections.abc.Callable[..., typing.Any]]: ...
87
93
 
88
94
  class _MethodDecoratorType:
89
95
  @typing.overload
@@ -93,13 +99,13 @@ class _MethodDecoratorType:
93
99
  @typing.overload
94
100
  def __call__(
95
101
  self,
96
- func: typing.Callable[
102
+ func: collections.abc.Callable[
97
103
  typing_extensions.Concatenate[typing.Any, P], collections.abc.Coroutine[typing.Any, typing.Any, ReturnType]
98
104
  ],
99
105
  ) -> PartialFunction[P, ReturnType, collections.abc.Coroutine[typing.Any, typing.Any, ReturnType]]: ...
100
106
  @typing.overload
101
107
  def __call__(
102
- self, func: typing.Callable[typing_extensions.Concatenate[typing.Any, P], ReturnType]
108
+ self, func: collections.abc.Callable[typing_extensions.Concatenate[typing.Any, P], ReturnType]
103
109
  ) -> PartialFunction[P, ReturnType, ReturnType]: ...
104
110
 
105
111
  def _method(
@@ -120,7 +126,9 @@ def _web_endpoint(
120
126
  custom_domains: typing.Optional[collections.abc.Iterable[str]] = None,
121
127
  requires_proxy_auth: bool = False,
122
128
  wait_for_response: bool = True,
123
- ) -> typing.Callable[[typing.Callable[P, ReturnType]], _PartialFunction[P, ReturnType, ReturnType]]: ...
129
+ ) -> collections.abc.Callable[
130
+ [collections.abc.Callable[P, ReturnType]], _PartialFunction[P, ReturnType, ReturnType]
131
+ ]: ...
124
132
  def _asgi_app(
125
133
  _warn_parentheses_missing=None,
126
134
  *,
@@ -128,7 +136,7 @@ def _asgi_app(
128
136
  custom_domains: typing.Optional[collections.abc.Iterable[str]] = None,
129
137
  requires_proxy_auth: bool = False,
130
138
  wait_for_response: bool = True,
131
- ) -> typing.Callable[[typing.Callable[..., typing.Any]], _PartialFunction]: ...
139
+ ) -> collections.abc.Callable[[collections.abc.Callable[..., typing.Any]], _PartialFunction]: ...
132
140
  def _wsgi_app(
133
141
  _warn_parentheses_missing=None,
134
142
  *,
@@ -136,7 +144,7 @@ def _wsgi_app(
136
144
  custom_domains: typing.Optional[collections.abc.Iterable[str]] = None,
137
145
  requires_proxy_auth: bool = False,
138
146
  wait_for_response: bool = True,
139
- ) -> typing.Callable[[typing.Callable[..., typing.Any]], _PartialFunction]: ...
147
+ ) -> collections.abc.Callable[[collections.abc.Callable[..., typing.Any]], _PartialFunction]: ...
140
148
  def _web_server(
141
149
  port: int,
142
150
  *,
@@ -144,31 +152,35 @@ def _web_server(
144
152
  label: typing.Optional[str] = None,
145
153
  custom_domains: typing.Optional[collections.abc.Iterable[str]] = None,
146
154
  requires_proxy_auth: bool = False,
147
- ) -> typing.Callable[[typing.Callable[..., typing.Any]], _PartialFunction]: ...
155
+ ) -> collections.abc.Callable[[collections.abc.Callable[..., typing.Any]], _PartialFunction]: ...
148
156
  def _disallow_wrapping_method(f: _PartialFunction, wrapper: str) -> None: ...
149
157
  def _build(
150
158
  _warn_parentheses_missing=None, *, force: bool = False, timeout: int = 86400
151
- ) -> typing.Callable[[typing.Union[typing.Callable[[typing.Any], typing.Any], _PartialFunction]], _PartialFunction]: ...
159
+ ) -> collections.abc.Callable[
160
+ [typing.Union[collections.abc.Callable[[typing.Any], typing.Any], _PartialFunction]], _PartialFunction
161
+ ]: ...
152
162
  def _enter(
153
163
  _warn_parentheses_missing=None, *, snap: bool = False
154
- ) -> typing.Callable[[typing.Union[typing.Callable[[typing.Any], typing.Any], _PartialFunction]], _PartialFunction]: ...
164
+ ) -> collections.abc.Callable[
165
+ [typing.Union[collections.abc.Callable[[typing.Any], typing.Any], _PartialFunction]], _PartialFunction
166
+ ]: ...
155
167
  def _exit(
156
168
  _warn_parentheses_missing=None,
157
- ) -> typing.Callable[
169
+ ) -> collections.abc.Callable[
158
170
  [
159
171
  typing.Union[
160
- typing.Callable[
172
+ collections.abc.Callable[
161
173
  [typing.Any, typing.Optional[type[BaseException]], typing.Optional[BaseException], typing.Any],
162
174
  typing.Any,
163
175
  ],
164
- typing.Callable[[typing.Any], typing.Any],
176
+ collections.abc.Callable[[typing.Any], typing.Any],
165
177
  ]
166
178
  ],
167
179
  _PartialFunction,
168
180
  ]: ...
169
181
  def _batched(
170
182
  _warn_parentheses_missing=None, *, max_batch_size: int, wait_ms: int
171
- ) -> typing.Callable[[typing.Callable[..., typing.Any]], _PartialFunction]: ...
183
+ ) -> collections.abc.Callable[[collections.abc.Callable[..., typing.Any]], _PartialFunction]: ...
172
184
  def method(
173
185
  _warn_parentheses_missing=None,
174
186
  *,
@@ -184,7 +196,9 @@ def web_endpoint(
184
196
  custom_domains: typing.Optional[collections.abc.Iterable[str]] = None,
185
197
  requires_proxy_auth: bool = False,
186
198
  wait_for_response: bool = True,
187
- ) -> typing.Callable[[typing.Callable[P, ReturnType]], PartialFunction[P, ReturnType, ReturnType]]: ...
199
+ ) -> collections.abc.Callable[
200
+ [collections.abc.Callable[P, ReturnType]], PartialFunction[P, ReturnType, ReturnType]
201
+ ]: ...
188
202
  def asgi_app(
189
203
  _warn_parentheses_missing=None,
190
204
  *,
@@ -192,7 +206,7 @@ def asgi_app(
192
206
  custom_domains: typing.Optional[collections.abc.Iterable[str]] = None,
193
207
  requires_proxy_auth: bool = False,
194
208
  wait_for_response: bool = True,
195
- ) -> typing.Callable[[typing.Callable[..., typing.Any]], PartialFunction]: ...
209
+ ) -> collections.abc.Callable[[collections.abc.Callable[..., typing.Any]], PartialFunction]: ...
196
210
  def wsgi_app(
197
211
  _warn_parentheses_missing=None,
198
212
  *,
@@ -200,7 +214,7 @@ def wsgi_app(
200
214
  custom_domains: typing.Optional[collections.abc.Iterable[str]] = None,
201
215
  requires_proxy_auth: bool = False,
202
216
  wait_for_response: bool = True,
203
- ) -> typing.Callable[[typing.Callable[..., typing.Any]], PartialFunction]: ...
217
+ ) -> collections.abc.Callable[[collections.abc.Callable[..., typing.Any]], PartialFunction]: ...
204
218
  def web_server(
205
219
  port: int,
206
220
  *,
@@ -208,27 +222,31 @@ def web_server(
208
222
  label: typing.Optional[str] = None,
209
223
  custom_domains: typing.Optional[collections.abc.Iterable[str]] = None,
210
224
  requires_proxy_auth: bool = False,
211
- ) -> typing.Callable[[typing.Callable[..., typing.Any]], PartialFunction]: ...
225
+ ) -> collections.abc.Callable[[collections.abc.Callable[..., typing.Any]], PartialFunction]: ...
212
226
  def build(
213
227
  _warn_parentheses_missing=None, *, force: bool = False, timeout: int = 86400
214
- ) -> typing.Callable[[typing.Union[typing.Callable[[typing.Any], typing.Any], PartialFunction]], PartialFunction]: ...
228
+ ) -> collections.abc.Callable[
229
+ [typing.Union[collections.abc.Callable[[typing.Any], typing.Any], PartialFunction]], PartialFunction
230
+ ]: ...
215
231
  def enter(
216
232
  _warn_parentheses_missing=None, *, snap: bool = False
217
- ) -> typing.Callable[[typing.Union[typing.Callable[[typing.Any], typing.Any], PartialFunction]], PartialFunction]: ...
233
+ ) -> collections.abc.Callable[
234
+ [typing.Union[collections.abc.Callable[[typing.Any], typing.Any], PartialFunction]], PartialFunction
235
+ ]: ...
218
236
  def exit(
219
237
  _warn_parentheses_missing=None,
220
- ) -> typing.Callable[
238
+ ) -> collections.abc.Callable[
221
239
  [
222
240
  typing.Union[
223
- typing.Callable[
241
+ collections.abc.Callable[
224
242
  [typing.Any, typing.Optional[type[BaseException]], typing.Optional[BaseException], typing.Any],
225
243
  typing.Any,
226
244
  ],
227
- typing.Callable[[typing.Any], typing.Any],
245
+ collections.abc.Callable[[typing.Any], typing.Any],
228
246
  ]
229
247
  ],
230
248
  PartialFunction,
231
249
  ]: ...
232
250
  def batched(
233
251
  _warn_parentheses_missing=None, *, max_batch_size: int, wait_ms: int
234
- ) -> typing.Callable[[typing.Callable[..., typing.Any]], PartialFunction]: ...
252
+ ) -> collections.abc.Callable[[collections.abc.Callable[..., typing.Any]], PartialFunction]: ...
modal/proxy.py CHANGED
@@ -3,9 +3,9 @@ from typing import Optional
3
3
 
4
4
  from modal_proto import api_pb2
5
5
 
6
+ from ._object import _get_environment_name, _Object
6
7
  from ._resolver import Resolver
7
8
  from ._utils.async_utils import synchronize_api
8
- from .object import _get_environment_name, _Object
9
9
 
10
10
 
11
11
  class _Proxy(_Object, type_prefix="pr"):
modal/proxy.pyi CHANGED
@@ -1,7 +1,8 @@
1
+ import modal._object
1
2
  import modal.object
2
3
  import typing
3
4
 
4
- class _Proxy(modal.object._Object):
5
+ class _Proxy(modal._object._Object):
5
6
  @staticmethod
6
7
  def from_name(name: str, environment_name: typing.Optional[str] = None) -> _Proxy: ...
7
8
 
modal/queue.py CHANGED
@@ -10,6 +10,7 @@ from synchronicity.async_wrap import asynccontextmanager
10
10
 
11
11
  from modal_proto import api_pb2
12
12
 
13
+ from ._object import EPHEMERAL_OBJECT_HEARTBEAT_SLEEP, _get_environment_name, _Object, live_method, live_method_gen
13
14
  from ._resolver import Resolver
14
15
  from ._serialization import deserialize, serialize
15
16
  from ._utils.async_utils import TaskContext, synchronize_api, warn_if_generator_is_not_consumed
@@ -18,7 +19,6 @@ from ._utils.grpc_utils import retry_transient_errors
18
19
  from ._utils.name_utils import check_object_name
19
20
  from .client import _Client
20
21
  from .exception import InvalidError, RequestSizeError
21
- from .object import EPHEMERAL_OBJECT_HEARTBEAT_SLEEP, _get_environment_name, _Object, live_method, live_method_gen
22
22
 
23
23
 
24
24
  class _Queue(_Object, type_prefix="qu"):