modal 1.5.1.dev12__tar.gz → 1.5.1.dev14__tar.gz

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 (226) hide show
  1. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/PKG-INFO +4 -1
  2. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/blob_utils.py +3 -1
  3. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/grpc_utils.py +85 -8
  4. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/http_utils.py +20 -1
  5. modal-1.5.1.dev14/modal/_utils/proxy_support.py +102 -0
  6. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/task_command_router_client.py +2 -2
  7. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/app.py +8 -8
  8. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/app.pyi +14 -14
  9. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/client.pyi +2 -2
  10. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/config.py +1 -0
  11. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal.egg-info/PKG-INFO +4 -1
  12. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal.egg-info/SOURCES.txt +1 -0
  13. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal.egg-info/requires.txt +4 -0
  14. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_version/__init__.py +1 -1
  15. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/pyproject.toml +5 -0
  16. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/LICENSE +0 -0
  17. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/README.md +0 -0
  18. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/__init__.py +0 -0
  19. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/__main__.py +0 -0
  20. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_billing.py +0 -0
  21. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_clustered_functions.py +0 -0
  22. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_clustered_functions.pyi +0 -0
  23. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_container_entrypoint.py +0 -0
  24. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_environments.py +0 -0
  25. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_function_variants.py +0 -0
  26. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_functions.py +0 -0
  27. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_grpc_client.py +0 -0
  28. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_image.py +0 -0
  29. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_ipython.py +0 -0
  30. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_load_context.py +0 -0
  31. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_location.py +0 -0
  32. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_logs.py +0 -0
  33. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_object.py +0 -0
  34. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_output/__init__.py +0 -0
  35. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_output/manager.py +0 -0
  36. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_output/pty.py +0 -0
  37. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_output/rich.py +0 -0
  38. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_output/status.py +0 -0
  39. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_partial_function.py +0 -0
  40. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_resolver.py +0 -0
  41. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_resources.py +0 -0
  42. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/__init__.py +0 -0
  43. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/asgi.py +0 -0
  44. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/container_io_manager.py +0 -0
  45. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/container_io_manager.pyi +0 -0
  46. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/execution_context.py +0 -0
  47. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/execution_context.pyi +0 -0
  48. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/gpu_memory_snapshot.py +0 -0
  49. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/task_lifecycle_manager.py +0 -0
  50. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
  51. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/telemetry.py +0 -0
  52. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/user_code_event_loop.py +0 -0
  53. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/user_code_imports.py +0 -0
  54. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_serialization.py +0 -0
  55. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_server.py +0 -0
  56. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_traceback.py +0 -0
  57. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_tunnel.py +0 -0
  58. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_tunnel.pyi +0 -0
  59. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_type_manager.py +0 -0
  60. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/__init__.py +0 -0
  61. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/app_utils.py +0 -0
  62. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/async_utils.py +0 -0
  63. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/auth_token_manager.py +0 -0
  64. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/browser_utils.py +0 -0
  65. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/bytes_io_segment_payload.py +0 -0
  66. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/deprecation.py +0 -0
  67. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/docker_utils.py +0 -0
  68. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/function_utils.py +0 -0
  69. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/git_utils.py +0 -0
  70. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/grpc_testing.py +0 -0
  71. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/hash_utils.py +0 -0
  72. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/jwt_utils.py +0 -0
  73. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/logger.py +0 -0
  74. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/mount_utils.py +0 -0
  75. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/name_utils.py +0 -0
  76. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/package_utils.py +0 -0
  77. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/pattern_utils.py +0 -0
  78. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/rand_pb_testing.py +0 -0
  79. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/sandbox_fs_utils.py +0 -0
  80. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/shell_utils.py +0 -0
  81. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/time_utils.py +0 -0
  82. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_vendor/__init__.py +0 -0
  83. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_vendor/a2wsgi_wsgi.py +0 -0
  84. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_vendor/cloudpickle.py +0 -0
  85. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_vendor/tblib.py +0 -0
  86. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_vendor/version.py +0 -0
  87. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_watcher.py +0 -0
  88. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_workspace.py +0 -0
  89. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/billing.py +0 -0
  90. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/billing.pyi +0 -0
  91. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/2023.12.312.txt +0 -0
  92. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/2023.12.txt +0 -0
  93. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/2024.04.txt +0 -0
  94. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/2024.10.txt +0 -0
  95. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/2025.06.txt +0 -0
  96. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/PREVIEW.txt +0 -0
  97. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/README.md +0 -0
  98. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/base-images.json +0 -0
  99. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/call_graph.py +0 -0
  100. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/__init__.py +0 -0
  101. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/_download.py +0 -0
  102. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/_help.py +0 -0
  103. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/_traceback.py +0 -0
  104. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/app.py +0 -0
  105. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/billing.py +0 -0
  106. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/bootstrap.py +0 -0
  107. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/changelog.py +0 -0
  108. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/cluster.py +0 -0
  109. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/config.py +0 -0
  110. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/container.py +0 -0
  111. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/dashboard.py +0 -0
  112. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/dict.py +0 -0
  113. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/entry_point.py +0 -0
  114. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/environment.py +0 -0
  115. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/image.py +0 -0
  116. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/import_refs.py +0 -0
  117. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/launch.py +0 -0
  118. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/logo.py +0 -0
  119. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/network_file_system.py +0 -0
  120. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/profile.py +0 -0
  121. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/programs/__init__.py +0 -0
  122. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/programs/run_jupyter.py +0 -0
  123. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/programs/vscode.py +0 -0
  124. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/queues.py +0 -0
  125. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/run.py +0 -0
  126. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/secret.py +0 -0
  127. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/selector.py +0 -0
  128. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/shell.py +0 -0
  129. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/skills.py +0 -0
  130. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/token.py +0 -0
  131. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/utils.py +0 -0
  132. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/volume.py +0 -0
  133. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/client.py +0 -0
  134. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cloud_bucket_mount.py +0 -0
  135. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cloud_bucket_mount.pyi +0 -0
  136. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cls.py +0 -0
  137. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cls.pyi +0 -0
  138. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/container_process.py +0 -0
  139. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/container_process.pyi +0 -0
  140. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/dict.py +0 -0
  141. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/dict.pyi +0 -0
  142. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/environments.py +0 -0
  143. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/environments.pyi +0 -0
  144. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/exception.py +0 -0
  145. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/experimental/__init__.py +0 -0
  146. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/experimental/flash.py +0 -0
  147. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/experimental/flash.pyi +0 -0
  148. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/experimental/ipython.py +0 -0
  149. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/file_io.py +0 -0
  150. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/file_io.pyi +0 -0
  151. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/file_pattern_matcher.py +0 -0
  152. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/functions.py +0 -0
  153. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/functions.pyi +0 -0
  154. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/image.py +0 -0
  155. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/image.pyi +0 -0
  156. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/io_streams.py +0 -0
  157. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/io_streams.pyi +0 -0
  158. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/mount.py +0 -0
  159. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/mount.pyi +0 -0
  160. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/network_file_system.py +0 -0
  161. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/network_file_system.pyi +0 -0
  162. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/object.py +0 -0
  163. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/object.pyi +0 -0
  164. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/output.py +0 -0
  165. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/parallel_map.py +0 -0
  166. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/parallel_map.pyi +0 -0
  167. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/partial_function.py +0 -0
  168. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/partial_function.pyi +0 -0
  169. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/proxy.py +0 -0
  170. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/proxy.pyi +0 -0
  171. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/py.typed +0 -0
  172. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/queue.py +0 -0
  173. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/queue.pyi +0 -0
  174. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/retries.py +0 -0
  175. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/runner.py +0 -0
  176. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/runner.pyi +0 -0
  177. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/running_app.py +0 -0
  178. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/sandbox.py +0 -0
  179. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/sandbox.pyi +0 -0
  180. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/sandbox_fs.py +0 -0
  181. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/sandbox_fs.pyi +0 -0
  182. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/schedule.py +0 -0
  183. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/scheduler_placement.py +0 -0
  184. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/secret.py +0 -0
  185. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/secret.pyi +0 -0
  186. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/server.py +0 -0
  187. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/server.pyi +0 -0
  188. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/serving.py +0 -0
  189. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/serving.pyi +0 -0
  190. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/skills/modal/SKILL.md +0 -0
  191. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/snapshot.py +0 -0
  192. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/snapshot.pyi +0 -0
  193. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/stream_type.py +0 -0
  194. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/token_flow.py +0 -0
  195. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/token_flow.pyi +0 -0
  196. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/volume.py +0 -0
  197. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/volume.pyi +0 -0
  198. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/workspace.py +0 -0
  199. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/workspace.pyi +0 -0
  200. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal.egg-info/dependency_links.txt +0 -0
  201. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal.egg-info/entry_points.txt +0 -0
  202. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal.egg-info/top_level.txt +0 -0
  203. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/__init__.py +0 -0
  204. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/gen_cli_docs.py +0 -0
  205. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/gen_cli_docs_main.py +0 -0
  206. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/gen_reference_docs.py +0 -0
  207. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/gen_reference_docs_main.py +0 -0
  208. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/mdmd/__init__.py +0 -0
  209. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/mdmd/mdmd.py +0 -0
  210. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/mdmd/signatures.py +0 -0
  211. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/mdmd/types.py +0 -0
  212. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/__init__.py +0 -0
  213. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/api_grpc.py +0 -0
  214. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/api_pb2.py +0 -0
  215. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/api_pb2.pyi +0 -0
  216. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/api_pb2_grpc.py +0 -0
  217. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/api_pb2_grpc.pyi +0 -0
  218. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/modal_api_grpc.py +0 -0
  219. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/py.typed +0 -0
  220. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/task_command_router_grpc.py +0 -0
  221. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/task_command_router_pb2.py +0 -0
  222. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/task_command_router_pb2.pyi +0 -0
  223. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/task_command_router_pb2_grpc.py +0 -0
  224. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
  225. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_version/__main__.py +0 -0
  226. {modal-1.5.1.dev12 → modal-1.5.1.dev14}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.5.1.dev12
3
+ Version: 1.5.1.dev14
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License-Expression: Apache-2.0
@@ -29,6 +29,9 @@ Requires-Dist: types-certifi
29
29
  Requires-Dist: types-toml
30
30
  Requires-Dist: watchfiles
31
31
  Requires-Dist: typing_extensions~=4.6
32
+ Provides-Extra: api-proxy-support
33
+ Requires-Dist: python-socks[asyncio]>=2.5; extra == "api-proxy-support"
34
+ Requires-Dist: aiohttp-socks>=0.8; extra == "api-proxy-support"
32
35
  Dynamic: license-file
33
36
 
34
37
  # Modal Python SDK
@@ -218,7 +218,9 @@ async def perform_multipart_upload(
218
218
 
219
219
  expected_multipart_etag = hashlib.md5(b"".join(bin_hash_parts)).hexdigest() + f"-{len(part_etags)}"
220
220
  resp = await ClientSessionRegistry.get_session().post(
221
- completion_url, data=completion_body.encode("ascii"), skip_auto_headers=["content-type"]
221
+ completion_url,
222
+ data=completion_body.encode("ascii"),
223
+ skip_auto_headers=["content-type"],
222
224
  )
223
225
  if resp.status != 200:
224
226
  try:
@@ -4,6 +4,7 @@ import contextlib
4
4
  import os
5
5
  import platform
6
6
  import socket
7
+ import ssl as ssl_module
7
8
  import time
8
9
  import typing
9
10
  import urllib.parse
@@ -11,7 +12,7 @@ import uuid
11
12
  from collections.abc import AsyncIterator, Sequence
12
13
  from dataclasses import dataclass, field
13
14
  from functools import cache
14
- from typing import Any, Optional, TypeVar
15
+ from typing import Any, Optional, TypeVar, Union
15
16
 
16
17
  import grpclib.client
17
18
  import grpclib.config
@@ -19,7 +20,8 @@ import grpclib.events
19
20
  from google.protobuf.message import Message
20
21
  from google.protobuf.symbol_database import SymbolDatabase
21
22
  from grpclib import GRPCError, Status
22
- from grpclib.encoding.base import StatusDetailsCodecBase
23
+ from grpclib.config import Configuration
24
+ from grpclib.encoding.base import CodecBase, StatusDetailsCodecBase
23
25
  from grpclib.exceptions import StreamTerminatedError
24
26
  from grpclib.protocol import H2Protocol
25
27
 
@@ -65,17 +67,89 @@ class Subchannel:
65
67
  return True
66
68
 
67
69
 
68
- class PermanentCloseableChannel(grpclib.client.Channel):
69
- def __init__(self, *args, closed_error_message: str, **kwargs):
70
- super().__init__(*args, **kwargs)
70
+ class ModalChannel(grpclib.client.Channel):
71
+ """Channel subclass with proxy support and graceful close guard.
72
+
73
+ Proxy support: routes connections through HTTP/SOCKS proxies by reading
74
+ standard env vars (HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, NO_PROXY).
75
+ Disabled when ``MODAL_DISABLE_API_PROXY=1`` is set.
76
+
77
+ Close guard: when ``closed_error_message`` is provided, raises
78
+ ``ClientClosed`` on new connection attempts after ``close()``.
79
+ """
80
+
81
+ def __init__(
82
+ self,
83
+ host: Optional[str] = None,
84
+ port: Optional[int] = None,
85
+ *,
86
+ loop: Optional[asyncio.AbstractEventLoop] = None,
87
+ path: Optional[str] = None,
88
+ codec: Optional[CodecBase] = None,
89
+ status_details_codec: Optional[StatusDetailsCodecBase] = None,
90
+ ssl: Union[None, bool, "ssl_module.SSLContext", "ssl_module.DefaultVerifyPaths"] = None,
91
+ config: Optional[Configuration] = None,
92
+ closed_error_message: Optional[str] = None,
93
+ ):
94
+ self.__use_unix_socket = path is not None
95
+ if not self.__use_unix_socket:
96
+ host = host if host is not None else "127.0.0.1"
97
+ port = port if port is not None else 50051
98
+
99
+ ssl_context: ssl_module.SSLContext | None
100
+ if ssl is True:
101
+ ssl_context = self._get_default_ssl_context()
102
+ elif isinstance(ssl, ssl_module.DefaultVerifyPaths):
103
+ ssl_context = self._get_default_ssl_context(verify_paths=ssl)
104
+ elif ssl is False:
105
+ ssl_context = None
106
+ else:
107
+ ssl_context = ssl
108
+
109
+ super().__init__(
110
+ host,
111
+ port,
112
+ loop=loop,
113
+ path=path,
114
+ codec=codec,
115
+ status_details_codec=status_details_codec,
116
+ ssl=ssl_context,
117
+ config=config,
118
+ )
119
+ self.__target_host = host
120
+ self.__target_port = port
121
+ self.__ssl_context = ssl_context
71
122
  self.__closed = False
72
123
  self.__closed_error_message = closed_error_message
73
124
 
74
125
  async def __connect__(self):
75
- if self.__closed:
126
+ if self.__closed and self.__closed_error_message is not None:
76
127
  raise ClientClosed(self.__closed_error_message)
77
128
  return await super().__connect__()
78
129
 
130
+ async def _create_connection(self) -> H2Protocol:
131
+ if self.__use_unix_socket:
132
+ return await super()._create_connection()
133
+
134
+ from .proxy_support import create_proxied_connection, get_proxy_url
135
+
136
+ assert self.__target_host is not None
137
+ assert self.__target_port is not None
138
+
139
+ ssl_context = self.__ssl_context
140
+ proxy_url = get_proxy_url(self.__target_host, use_ssl=ssl_context is not None)
141
+ if proxy_url is None:
142
+ return await super()._create_connection()
143
+
144
+ protocol = await create_proxied_connection(
145
+ self._protocol_factory,
146
+ self.__target_host,
147
+ self.__target_port,
148
+ proxy_url=proxy_url,
149
+ ssl_context=ssl_context,
150
+ )
151
+ return protocol
152
+
79
153
  def close(self):
80
154
  self.__closed = True
81
155
  return super().close()
@@ -116,7 +190,10 @@ class ConnectionManager:
116
190
 
117
191
  async def get_or_create_channel(self, server_url: str) -> grpclib.client.Channel:
118
192
  if server_url not in self._channels:
119
- self._channels[server_url] = create_channel(server_url, self._metadata)
193
+ self._channels[server_url] = create_channel(
194
+ server_url,
195
+ self._metadata,
196
+ )
120
197
  try:
121
198
  await connect_channel(self._channels[server_url])
122
199
  except (OSError, asyncio.TimeoutError) as exc:
@@ -207,7 +284,7 @@ def create_channel(
207
284
  ssl = o.scheme.endswith("s")
208
285
  host = parts[0]
209
286
  port = int(parts[1]) if len(parts) == 2 else 443 if ssl else 80
210
- channel = grpclib.client.Channel(host, port, ssl=ssl, config=config, status_details_codec=custom_detail_codec)
287
+ channel = ModalChannel(host, port, ssl=ssl, config=config, status_details_codec=custom_detail_codec)
211
288
  else:
212
289
  raise Exception(f"Unknown scheme: {o.scheme}")
213
290
 
@@ -27,8 +27,27 @@ def _http_client_with_tls(timeout: float | None) -> "ClientSession":
27
27
  import certifi
28
28
  from aiohttp import ClientSession, ClientTimeout, TCPConnector
29
29
 
30
+ from .proxy_support import get_proxy_url
31
+
30
32
  ssl_context = ssl.create_default_context(cafile=certifi.where())
31
- connector = TCPConnector(ssl=ssl_context)
33
+
34
+ connector: TCPConnector
35
+ proxy_url = get_proxy_url(None, use_ssl=True)
36
+ if proxy_url:
37
+ try:
38
+ from aiohttp_socks import ProxyConnector
39
+ except ImportError:
40
+ raise ImportError(
41
+ f"A proxy is configured ({proxy_url}) but the 'aiohttp-socks' package "
42
+ "is not installed. Install it with: pip install 'modal[api-proxy-support]'"
43
+ ) from None
44
+ from .proxy_support import _normalize_proxy_url
45
+
46
+ normalized_url, rdns = _normalize_proxy_url(proxy_url)
47
+ connector = ProxyConnector.from_url(normalized_url, rdns=rdns, ssl=ssl_context)
48
+ else:
49
+ connector = TCPConnector(ssl=ssl_context)
50
+
32
51
  return ClientSession(connector=connector, timeout=ClientTimeout(total=timeout))
33
52
 
34
53
 
@@ -0,0 +1,102 @@
1
+ # Copyright Modal Labs 2026
2
+ """Proxy support for gRPC (grpclib) and HTTP (aiohttp) connections.
3
+
4
+ By default, the Modal client reads standard proxy environment variables
5
+ (HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, NO_PROXY and their lowercase
6
+ variants). Set ``MODAL_DISABLE_API_PROXY=1`` to opt out.
7
+
8
+ Supported proxy types:
9
+ - HTTP CONNECT (``http://host:port``)
10
+ - SOCKS4/4a/5/5h (``socks5://``, ``socks5h://``, etc.)
11
+
12
+ All proxy types require the optional ``python-socks[asyncio]`` package.
13
+ Install it via ``pip install modal[api-proxy-support]``.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import asyncio
19
+ import ssl
20
+ import urllib.parse
21
+ import urllib.request
22
+
23
+ from grpclib.protocol import H2Protocol
24
+
25
+
26
+ def get_proxy_url(host: str | None, *, use_ssl: bool) -> str | None:
27
+ """Return the proxy URL for the given target, respecting NO_PROXY when host is known."""
28
+ from ..config import config
29
+
30
+ if config.get("disable_api_proxy"):
31
+ return None
32
+
33
+ if host is not None and urllib.request.proxy_bypass(host):
34
+ return None
35
+
36
+ proxies = urllib.request.getproxies()
37
+ if not proxies:
38
+ return None
39
+
40
+ scheme = "https" if use_ssl else "http"
41
+ proxy_url = proxies.get(scheme) or proxies.get("all")
42
+ return proxy_url or None
43
+
44
+
45
+ def _normalize_proxy_url(proxy_url: str) -> tuple[str, bool]:
46
+ """Normalize a proxy URL for python-socks, which doesn't handle socks5h/socks4a.
47
+
48
+ Returns (normalized_url, rdns) where rdns=True for remote-DNS schemes.
49
+ """
50
+ parsed = urllib.parse.urlparse(proxy_url)
51
+ scheme = parsed.scheme.lower()
52
+ if scheme == "socks5h":
53
+ return urllib.parse.urlunparse(
54
+ ("socks5", parsed.netloc, parsed.path, parsed.params, parsed.query, parsed.fragment)
55
+ ), True
56
+ elif scheme == "socks4a":
57
+ return urllib.parse.urlunparse(
58
+ ("socks4", parsed.netloc, parsed.path, parsed.params, parsed.query, parsed.fragment)
59
+ ), True
60
+ return proxy_url, False
61
+
62
+
63
+ async def create_proxied_connection(
64
+ protocol_factory,
65
+ host: str,
66
+ port: int,
67
+ *,
68
+ proxy_url: str,
69
+ ssl_context: ssl.SSLContext | None = None,
70
+ ) -> H2Protocol:
71
+ """Create a gRPC connection through the configured proxy."""
72
+
73
+ try:
74
+ from python_socks.async_.asyncio import Proxy
75
+ except ImportError:
76
+ raise ImportError(
77
+ f"A proxy is configured ({proxy_url}) but the 'python-socks' package is not installed. "
78
+ "Install it with: pip install 'modal[api-proxy-support]'"
79
+ ) from None
80
+
81
+ normalized_url, rdns = _normalize_proxy_url(proxy_url)
82
+ proxy = Proxy.from_url(normalized_url, rdns=rdns)
83
+ sock = await proxy.connect(host, port)
84
+
85
+ loop = asyncio.get_running_loop()
86
+ try:
87
+ if ssl_context:
88
+ _, protocol = await loop.create_connection(
89
+ protocol_factory,
90
+ sock=sock,
91
+ ssl=ssl_context,
92
+ server_hostname=host,
93
+ )
94
+ else:
95
+ _, protocol = await loop.create_connection(
96
+ protocol_factory,
97
+ sock=sock,
98
+ )
99
+ except BaseException:
100
+ sock.close()
101
+ raise
102
+ return protocol
@@ -23,7 +23,7 @@ from modal_proto import api_pb2, task_command_router_pb2 as sr_pb2
23
23
  from modal_proto.task_command_router_grpc import TaskCommandRouterStub
24
24
 
25
25
  from .._grpc_client import grpc_error_converter
26
- from .._utils.grpc_utils import PermanentCloseableChannel
26
+ from .._utils.grpc_utils import ModalChannel
27
27
  from .async_utils import aclosing, retry
28
28
  from .grpc_utils import RETRYABLE_GRPC_STATUS_CODES
29
29
 
@@ -218,7 +218,7 @@ class TaskCommandRouterClient:
218
218
  host, _, port_str = o.netloc.partition(":")
219
219
  port = int(port_str) if port_str else (443 if o.scheme == "https" else 80)
220
220
 
221
- channel = PermanentCloseableChannel(
221
+ channel = ModalChannel(
222
222
  host,
223
223
  port,
224
224
  ssl=ssl_context,
@@ -1284,21 +1284,21 @@ class _App:
1284
1284
  cpu: float | tuple[float, float] | None = None, # CPU cores to request
1285
1285
  memory: int | tuple[int, int] | None = None, # Memory in MiB to request
1286
1286
  ephemeral_disk: int | None = None, # Ephemeral disk size in MiB
1287
+ target_concurrency: int | None = None, # Target concurrency for the server; 0 disables autoscaling
1287
1288
  min_containers: int | None = None, # Minimum number of containers to keep warm
1288
1289
  max_containers: int | None = None, # Maximum number of containers
1289
1290
  buffer_containers: int | None = None, # Additional idle containers under active load
1290
1291
  scaleup_window: int | None = None, # Stabilization window (seconds) of sustained demand before scaling up
1291
1292
  scaledown_window: int | None = None, # Max idle time before scaling down (seconds)
1292
1293
  proxy: _Proxy | None = None, # Modal Proxy to use in front of this server
1293
- unauthenticated: bool = False, # Whether the endpoint requires proxy authentication, required by default.
1294
1294
  port: int = 8000, # Port the HTTP server listens on
1295
+ unauthenticated: bool = False, # Whether the endpoint requires proxy authentication, required by default.
1296
+ h2_enabled: bool = False, # Enable HTTP/2
1295
1297
  startup_timeout: int = 30, # Maximum startup time in seconds
1296
1298
  exit_grace_period: int = 0, # Grace period for in-flight requests on shutdown
1297
1299
  routing_region: str = "us-east", # Region to route Server requests through
1298
- h2_enabled: bool = False, # Enable HTTP/2
1299
- target_concurrency: int | None = None, # Target concurrency for the server; 0 disables autoscaling
1300
+ compute_region: str | Sequence[str] | None = None, # Region(s) where containers can be scheduled
1300
1301
  cloud: str | None = None, # Cloud provider (aws, gcp, oci, auto)
1301
- region: str | Sequence[str] | None = None, # Region(s) to run on
1302
1302
  nonpreemptible: bool = False, # Whether to use non-preemptible instances
1303
1303
  enable_memory_snapshot: bool = False, # Enable memory checkpointing
1304
1304
  i6pn: bool | None = None, # Enable IPv6 container networking
@@ -1328,6 +1328,7 @@ class _App:
1328
1328
  Specify, in MiB, a memory request which is the minimum memory required. Or, pass (request, limit) to
1329
1329
  additionally specify a hard limit in MiB.
1330
1330
  ephemeral_disk: Specify, in MiB, the ephemeral disk size for the server.
1331
+ target_concurrency: Target concurrency for the server; 0 disables autoscaling.
1331
1332
  min_containers: Minimum number of containers to keep warm.
1332
1333
  max_containers: Maximum number of containers.
1333
1334
  buffer_containers: Additional idle containers under active load.
@@ -1336,13 +1337,12 @@ class _App:
1336
1337
  proxy: Modal Proxy to use in front of this server.
1337
1338
  port: Port the HTTP server listens on.
1338
1339
  unauthenticated: Whether the endpoint requires proxy authentication, required by default.
1340
+ h2_enabled: Enable HTTP/2.
1339
1341
  startup_timeout: Maximum startup time in seconds.
1340
1342
  exit_grace_period: Grace period for in-flight requests on shutdown.
1341
1343
  routing_region: Region to route Server requests through.
1342
- h2_enabled: Enable HTTP/2.
1343
- target_concurrency: Target concurrency for the server; 0 disables autoscaling.
1344
+ compute_region: Region(s) where containers can be scheduled.
1344
1345
  cloud: Cloud provider (aws, gcp, oci, auto).
1345
- region: Region(s) to run on.
1346
1346
  nonpreemptible: Whether to use non-preemptible instances.
1347
1347
  enable_memory_snapshot: Enable memory checkpointing.
1348
1348
  i6pn: Enable IPv6 container networking.
@@ -1441,7 +1441,7 @@ class _App:
1441
1441
  batch_wait_ms=None, # No support for Server level batching
1442
1442
  startup_timeout=startup_timeout,
1443
1443
  cloud=cloud,
1444
- region=region,
1444
+ region=compute_region,
1445
1445
  nonpreemptible=nonpreemptible,
1446
1446
  enable_memory_snapshot=enable_memory_snapshot,
1447
1447
  single_use_containers=False, # No support for single-use server containers
@@ -745,21 +745,21 @@ class _App:
745
745
  cpu: typing.Union[float, tuple[float, float], None] = None,
746
746
  memory: typing.Union[int, tuple[int, int], None] = None,
747
747
  ephemeral_disk: typing.Optional[int] = None,
748
+ target_concurrency: typing.Optional[int] = None,
748
749
  min_containers: typing.Optional[int] = None,
749
750
  max_containers: typing.Optional[int] = None,
750
751
  buffer_containers: typing.Optional[int] = None,
751
752
  scaleup_window: typing.Optional[int] = None,
752
753
  scaledown_window: typing.Optional[int] = None,
753
754
  proxy: typing.Optional[modal.proxy._Proxy] = None,
754
- unauthenticated: bool = False,
755
755
  port: int = 8000,
756
+ unauthenticated: bool = False,
757
+ h2_enabled: bool = False,
756
758
  startup_timeout: int = 30,
757
759
  exit_grace_period: int = 0,
758
760
  routing_region: str = "us-east",
759
- h2_enabled: bool = False,
760
- target_concurrency: typing.Optional[int] = None,
761
+ compute_region: typing.Union[str, collections.abc.Sequence[str], None] = None,
761
762
  cloud: typing.Optional[str] = None,
762
- region: typing.Union[str, collections.abc.Sequence[str], None] = None,
763
763
  nonpreemptible: bool = False,
764
764
  enable_memory_snapshot: bool = False,
765
765
  i6pn: typing.Optional[bool] = None,
@@ -789,6 +789,7 @@ class _App:
789
789
  Specify, in MiB, a memory request which is the minimum memory required. Or, pass (request, limit) to
790
790
  additionally specify a hard limit in MiB.
791
791
  ephemeral_disk: Specify, in MiB, the ephemeral disk size for the server.
792
+ target_concurrency: Target concurrency for the server; 0 disables autoscaling.
792
793
  min_containers: Minimum number of containers to keep warm.
793
794
  max_containers: Maximum number of containers.
794
795
  buffer_containers: Additional idle containers under active load.
@@ -797,13 +798,12 @@ class _App:
797
798
  proxy: Modal Proxy to use in front of this server.
798
799
  port: Port the HTTP server listens on.
799
800
  unauthenticated: Whether the endpoint requires proxy authentication, required by default.
801
+ h2_enabled: Enable HTTP/2.
800
802
  startup_timeout: Maximum startup time in seconds.
801
803
  exit_grace_period: Grace period for in-flight requests on shutdown.
802
804
  routing_region: Region to route Server requests through.
803
- h2_enabled: Enable HTTP/2.
804
- target_concurrency: Target concurrency for the server; 0 disables autoscaling.
805
+ compute_region: Region(s) where containers can be scheduled.
805
806
  cloud: Cloud provider (aws, gcp, oci, auto).
806
- region: Region(s) to run on.
807
807
  nonpreemptible: Whether to use non-preemptible instances.
808
808
  enable_memory_snapshot: Enable memory checkpointing.
809
809
  i6pn: Enable IPv6 container networking.
@@ -1748,21 +1748,21 @@ class App:
1748
1748
  cpu: typing.Union[float, tuple[float, float], None] = None,
1749
1749
  memory: typing.Union[int, tuple[int, int], None] = None,
1750
1750
  ephemeral_disk: typing.Optional[int] = None,
1751
+ target_concurrency: typing.Optional[int] = None,
1751
1752
  min_containers: typing.Optional[int] = None,
1752
1753
  max_containers: typing.Optional[int] = None,
1753
1754
  buffer_containers: typing.Optional[int] = None,
1754
1755
  scaleup_window: typing.Optional[int] = None,
1755
1756
  scaledown_window: typing.Optional[int] = None,
1756
1757
  proxy: typing.Optional[modal.proxy.Proxy] = None,
1757
- unauthenticated: bool = False,
1758
1758
  port: int = 8000,
1759
+ unauthenticated: bool = False,
1760
+ h2_enabled: bool = False,
1759
1761
  startup_timeout: int = 30,
1760
1762
  exit_grace_period: int = 0,
1761
1763
  routing_region: str = "us-east",
1762
- h2_enabled: bool = False,
1763
- target_concurrency: typing.Optional[int] = None,
1764
+ compute_region: typing.Union[str, collections.abc.Sequence[str], None] = None,
1764
1765
  cloud: typing.Optional[str] = None,
1765
- region: typing.Union[str, collections.abc.Sequence[str], None] = None,
1766
1766
  nonpreemptible: bool = False,
1767
1767
  enable_memory_snapshot: bool = False,
1768
1768
  i6pn: typing.Optional[bool] = None,
@@ -1790,6 +1790,7 @@ class App:
1790
1790
  Specify, in MiB, a memory request which is the minimum memory required. Or, pass (request, limit) to
1791
1791
  additionally specify a hard limit in MiB.
1792
1792
  ephemeral_disk: Specify, in MiB, the ephemeral disk size for the server.
1793
+ target_concurrency: Target concurrency for the server; 0 disables autoscaling.
1793
1794
  min_containers: Minimum number of containers to keep warm.
1794
1795
  max_containers: Maximum number of containers.
1795
1796
  buffer_containers: Additional idle containers under active load.
@@ -1798,13 +1799,12 @@ class App:
1798
1799
  proxy: Modal Proxy to use in front of this server.
1799
1800
  port: Port the HTTP server listens on.
1800
1801
  unauthenticated: Whether the endpoint requires proxy authentication, required by default.
1802
+ h2_enabled: Enable HTTP/2.
1801
1803
  startup_timeout: Maximum startup time in seconds.
1802
1804
  exit_grace_period: Grace period for in-flight requests on shutdown.
1803
1805
  routing_region: Region to route Server requests through.
1804
- h2_enabled: Enable HTTP/2.
1805
- target_concurrency: Target concurrency for the server; 0 disables autoscaling.
1806
+ compute_region: Region(s) where containers can be scheduled.
1806
1807
  cloud: Cloud provider (aws, gcp, oci, auto).
1807
- region: Region(s) to run on.
1808
1808
  nonpreemptible: Whether to use non-preemptible instances.
1809
1809
  enable_memory_snapshot: Enable memory checkpointing.
1810
1810
  i6pn: Enable IPv6 container networking.
@@ -35,7 +35,7 @@ class _Client:
35
35
  server_url: str,
36
36
  client_type: int,
37
37
  credentials: typing.Optional[tuple[str, str]],
38
- version: str = "1.5.1.dev12",
38
+ version: str = "1.5.1.dev14",
39
39
  ):
40
40
  """mdmd:hidden
41
41
  The Modal client object is not intended to be instantiated directly by users.
@@ -205,7 +205,7 @@ class Client:
205
205
  server_url: str,
206
206
  client_type: int,
207
207
  credentials: typing.Optional[tuple[str, str]],
208
- version: str = "1.5.1.dev12",
208
+ version: str = "1.5.1.dev14",
209
209
  ):
210
210
  """mdmd:hidden
211
211
  The Modal client object is not intended to be instantiated directly by users.
@@ -302,6 +302,7 @@ _SETTINGS = {
302
302
  "dev_suffix": _Setting("", transform=_enforce_suffix_rules),
303
303
  "max_throttle_wait": _Setting(None, transform=lambda x: int(x) if x else None),
304
304
  "async_warnings": _Setting(True, transform=_to_boolean), # Activate synchronicity usage warnings
305
+ "disable_api_proxy": _Setting(False, transform=_to_boolean),
305
306
  }
306
307
 
307
308
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.5.1.dev12
3
+ Version: 1.5.1.dev14
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License-Expression: Apache-2.0
@@ -29,6 +29,9 @@ Requires-Dist: types-certifi
29
29
  Requires-Dist: types-toml
30
30
  Requires-Dist: watchfiles
31
31
  Requires-Dist: typing_extensions~=4.6
32
+ Provides-Extra: api-proxy-support
33
+ Requires-Dist: python-socks[asyncio]>=2.5; extra == "api-proxy-support"
34
+ Requires-Dist: aiohttp-socks>=0.8; extra == "api-proxy-support"
32
35
  Dynamic: license-file
33
36
 
34
37
  # Modal Python SDK
@@ -141,6 +141,7 @@ modal/_utils/mount_utils.py
141
141
  modal/_utils/name_utils.py
142
142
  modal/_utils/package_utils.py
143
143
  modal/_utils/pattern_utils.py
144
+ modal/_utils/proxy_support.py
144
145
  modal/_utils/rand_pb_testing.py
145
146
  modal/_utils/sandbox_fs_utils.py
146
147
  modal/_utils/shell_utils.py
@@ -16,3 +16,7 @@ grpclib<0.4.10,>=0.4.7
16
16
 
17
17
  [:python_version >= "3.14"]
18
18
  grpclib<0.4.10,>=0.4.9
19
+
20
+ [api-proxy-support]
21
+ python-socks[asyncio]>=2.5
22
+ aiohttp-socks>=0.8
@@ -1,4 +1,4 @@
1
1
  # Copyright Modal Labs 2026
2
2
  """Supplies the current version of the modal client library."""
3
3
 
4
- __version__ = "1.5.1.dev12"
4
+ __version__ = "1.5.1.dev14"
@@ -34,6 +34,9 @@ classifiers = [
34
34
  "Programming Language :: Python :: 3",
35
35
  ]
36
36
 
37
+ [project.optional-dependencies]
38
+ api-proxy-support = ["python-socks[asyncio]>=2.5", "aiohttp-socks>=0.8"]
39
+
37
40
  [dependency-groups]
38
41
  dev = [
39
42
  "fastapi~=0.125",
@@ -91,6 +94,8 @@ dev = [
91
94
  # this pip package to load zone keys like ``America/New_York``. Tiny and
92
95
  # harmless on other platforms.
93
96
  "tzdata",
97
+ "python-socks[asyncio]>=2.5",
98
+ "aiohttp-socks>=0.8",
94
99
  ]
95
100
 
96
101
  [tool.uv.extra-build-dependencies]
File without changes
File without changes
File without changes
File without changes