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.
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/PKG-INFO +4 -1
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/blob_utils.py +3 -1
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/grpc_utils.py +85 -8
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/http_utils.py +20 -1
- modal-1.5.1.dev14/modal/_utils/proxy_support.py +102 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/task_command_router_client.py +2 -2
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/app.py +8 -8
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/app.pyi +14 -14
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/client.pyi +2 -2
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/config.py +1 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal.egg-info/PKG-INFO +4 -1
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal.egg-info/SOURCES.txt +1 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal.egg-info/requires.txt +4 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_version/__init__.py +1 -1
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/pyproject.toml +5 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/LICENSE +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/README.md +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/__init__.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/__main__.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_billing.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_clustered_functions.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_clustered_functions.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_container_entrypoint.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_environments.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_function_variants.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_functions.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_grpc_client.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_image.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_ipython.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_load_context.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_location.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_logs.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_object.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_output/__init__.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_output/manager.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_output/pty.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_output/rich.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_output/status.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_partial_function.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_resolver.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_resources.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/__init__.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/asgi.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/execution_context.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/task_lifecycle_manager.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/telemetry.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_serialization.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_server.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_traceback.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_tunnel.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_tunnel.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_type_manager.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/__init__.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/app_utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/async_utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/browser_utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/deprecation.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/docker_utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/function_utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/git_utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/hash_utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/logger.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/mount_utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/name_utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/package_utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/shell_utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_utils/time_utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_vendor/__init__.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_vendor/tblib.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_vendor/version.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_watcher.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/_workspace.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/billing.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/billing.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/2023.12.txt +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/2024.04.txt +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/2024.10.txt +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/2025.06.txt +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/README.md +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/builder/base-images.json +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/call_graph.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/__init__.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/_download.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/_help.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/_traceback.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/app.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/billing.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/bootstrap.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/changelog.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/cluster.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/config.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/container.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/dashboard.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/dict.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/entry_point.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/environment.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/image.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/import_refs.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/launch.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/logo.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/network_file_system.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/profile.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/programs/__init__.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/programs/vscode.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/queues.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/run.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/secret.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/selector.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/shell.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/skills.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/token.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/utils.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cli/volume.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/client.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cls.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/cls.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/container_process.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/container_process.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/dict.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/dict.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/environments.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/environments.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/exception.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/experimental/__init__.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/experimental/flash.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/experimental/flash.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/experimental/ipython.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/file_io.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/file_io.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/file_pattern_matcher.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/functions.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/functions.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/image.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/image.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/io_streams.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/io_streams.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/mount.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/mount.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/network_file_system.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/network_file_system.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/object.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/object.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/output.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/parallel_map.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/parallel_map.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/partial_function.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/partial_function.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/proxy.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/proxy.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/py.typed +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/queue.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/queue.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/retries.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/runner.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/runner.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/running_app.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/sandbox.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/sandbox.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/sandbox_fs.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/sandbox_fs.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/schedule.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/scheduler_placement.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/secret.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/secret.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/server.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/server.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/serving.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/serving.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/skills/modal/SKILL.md +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/snapshot.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/snapshot.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/stream_type.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/token_flow.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/token_flow.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/volume.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/volume.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/workspace.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal/workspace.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal.egg-info/top_level.txt +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/__init__.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_docs/mdmd/types.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/__init__.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/api_grpc.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/api_pb2.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/api_pb2.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/py.typed +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.5.1.dev12 → modal-1.5.1.dev14}/modal_version/__main__.py +0 -0
- {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.
|
|
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,
|
|
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.
|
|
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
|
|
69
|
-
|
|
70
|
-
|
|
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(
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
@@ -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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|