modal 1.3.6.dev8__tar.gz → 1.3.6.dev9__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.3.6.dev8 → modal-1.3.6.dev9}/PKG-INFO +1 -2
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/README.md +0 -1
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/async_utils.py +17 -2
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/blob_utils.py +2 -2
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/grpc_utils.py +15 -5
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/client.pyi +2 -2
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/functions.pyi +6 -6
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/volume.py +3 -3
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal.egg-info/PKG-INFO +1 -2
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_version/__init__.py +1 -1
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/pyproject.toml +47 -1
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/LICENSE +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/__init__.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/__main__.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_billing.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_clustered_functions.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_clustered_functions.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_container_entrypoint.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_functions.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_grpc_client.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_ipython.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_load_context.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_location.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_logs.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_object.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_output/__init__.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_output/manager.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_output/pty.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_output/rich.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_output/status.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_partial_function.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_resolver.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_resources.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_runtime/__init__.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_runtime/asgi.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_runtime/execution_context.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_runtime/telemetry.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_serialization.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_server.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_traceback.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_tunnel.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_tunnel.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_type_manager.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/__init__.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/app_utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/browser_utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/deprecation.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/docker_utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/function_utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/git_utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/hash_utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/http_utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/logger.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/mount_utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/name_utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/package_utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/shell_utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_utils/time_utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_vendor/__init__.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_vendor/tblib.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_vendor/version.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/_watcher.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/app.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/app.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/billing.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/builder/2023.12.txt +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/builder/2024.04.txt +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/builder/2024.10.txt +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/builder/2025.06.txt +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/builder/README.md +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/builder/base-images.json +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/call_graph.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/__init__.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/_download.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/_traceback.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/app.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/billing.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/changelog.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/cluster.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/config.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/container.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/dashboard.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/dict.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/entry_point.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/environment.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/import_refs.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/launch.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/network_file_system.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/profile.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/programs/__init__.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/programs/vscode.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/queues.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/run.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/secret.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/selector.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/shell.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/token.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/utils.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cli/volume.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/client.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cls.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/cls.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/config.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/container_process.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/container_process.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/dict.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/dict.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/environments.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/environments.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/exception.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/experimental/__init__.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/experimental/flash.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/experimental/flash.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/experimental/ipython.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/file_io.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/file_io.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/file_pattern_matcher.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/functions.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/gpu.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/image.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/image.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/io_streams.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/io_streams.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/mount.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/mount.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/network_file_system.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/network_file_system.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/object.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/object.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/output.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/parallel_map.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/parallel_map.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/partial_function.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/partial_function.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/proxy.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/proxy.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/py.typed +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/queue.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/queue.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/retries.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/runner.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/runner.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/running_app.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/sandbox.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/sandbox.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/sandbox_fs.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/sandbox_fs.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/schedule.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/scheduler_placement.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/secret.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/secret.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/server.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/server.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/serving.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/serving.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/snapshot.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/snapshot.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/stream_type.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/token_flow.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/token_flow.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal/volume.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal.egg-info/requires.txt +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal.egg-info/top_level.txt +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_docs/__init__.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_proto/__init__.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_proto/api_grpc.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_proto/api_pb2.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_proto/api_pb2.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_proto/py.typed +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/modal_version/__main__.py +0 -0
- {modal-1.3.6.dev8 → modal-1.3.6.dev9}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modal
|
|
3
|
-
Version: 1.3.6.
|
|
3
|
+
Version: 1.3.6.dev9
|
|
4
4
|
Summary: Python client library for Modal
|
|
5
5
|
Author-email: Modal Labs <support@modal.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -36,7 +36,6 @@ Dynamic: license-file
|
|
|
36
36
|
|
|
37
37
|
[](https://pypi.org/project/modal/)
|
|
38
38
|
[](https://github.com/modal-labs/modal-client/blob/master/LICENSE)
|
|
39
|
-
[](https://github.com/modal-labs/modal-client/actions/workflows/ci-cd.yml)
|
|
40
39
|
[](https://modal.com/slack)
|
|
41
40
|
|
|
42
41
|
The [Modal](https://modal.com/) Python SDK provides convenient, on-demand
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://pypi.org/project/modal/)
|
|
4
4
|
[](https://github.com/modal-labs/modal-client/blob/master/LICENSE)
|
|
5
|
-
[](https://github.com/modal-labs/modal-client/actions/workflows/ci-cd.yml)
|
|
6
5
|
[](https://modal.com/slack)
|
|
7
6
|
|
|
8
7
|
The [Modal](https://modal.com/) Python SDK provides convenient, on-demand
|
|
@@ -345,12 +345,24 @@ def synchronize_api(obj, target_module=None):
|
|
|
345
345
|
RETRY_N_ATTEMPTS_OVERRIDE: Optional[int] = None
|
|
346
346
|
|
|
347
347
|
|
|
348
|
-
def retry(
|
|
348
|
+
def retry(
|
|
349
|
+
direct_fn=None,
|
|
350
|
+
*,
|
|
351
|
+
n_attempts=3,
|
|
352
|
+
base_delay=0,
|
|
353
|
+
delay_factor=2,
|
|
354
|
+
attempt_timeout: Optional[float] = 90,
|
|
355
|
+
attempt_timeout_factor=1,
|
|
356
|
+
):
|
|
349
357
|
"""Decorator that calls an async function multiple times, with a given timeout.
|
|
350
358
|
|
|
351
359
|
If a `base_delay` is provided, the function is given an exponentially
|
|
352
360
|
increasing delay on each run, up until the maximum number of attempts.
|
|
353
361
|
|
|
362
|
+
If `attempt_timeout_factor` is set to a value > 1, the per-attempt timeout
|
|
363
|
+
increases exponentially (starting from `attempt_timeout`, multiplied by
|
|
364
|
+
`attempt_timeout_factor` after each failed attempt).
|
|
365
|
+
|
|
354
366
|
Usage:
|
|
355
367
|
|
|
356
368
|
```
|
|
@@ -375,10 +387,11 @@ def retry(direct_fn=None, *, n_attempts=3, base_delay=0, delay_factor=2, timeout
|
|
|
375
387
|
local_n_attempts = n_attempts
|
|
376
388
|
|
|
377
389
|
delay = base_delay
|
|
390
|
+
current_attempt_timeout = attempt_timeout
|
|
378
391
|
for i in range(local_n_attempts):
|
|
379
392
|
t0 = time.time()
|
|
380
393
|
try:
|
|
381
|
-
return await asyncio.wait_for(fn(*args, **kwargs), timeout=
|
|
394
|
+
return await asyncio.wait_for(fn(*args, **kwargs), timeout=current_attempt_timeout)
|
|
382
395
|
except asyncio.CancelledError:
|
|
383
396
|
logger.debug(f"Function {fn} was cancelled")
|
|
384
397
|
raise
|
|
@@ -392,6 +405,8 @@ def retry(direct_fn=None, *, n_attempts=3, base_delay=0, delay_factor=2, timeout
|
|
|
392
405
|
)
|
|
393
406
|
await asyncio.sleep(delay)
|
|
394
407
|
delay *= delay_factor
|
|
408
|
+
if current_attempt_timeout is not None:
|
|
409
|
+
current_attempt_timeout *= attempt_timeout_factor
|
|
395
410
|
|
|
396
411
|
return f_wrapped
|
|
397
412
|
|
|
@@ -58,7 +58,7 @@ MULTIPART_UPLOAD_THRESHOLD = 1024**3
|
|
|
58
58
|
BLOCK_SIZE: int = 8 * 1024 * 1024
|
|
59
59
|
|
|
60
60
|
|
|
61
|
-
@retry(n_attempts=3, base_delay=0.3,
|
|
61
|
+
@retry(n_attempts=3, base_delay=0.3, attempt_timeout=None)
|
|
62
62
|
async def _upload_to_s3_url(
|
|
63
63
|
upload_url,
|
|
64
64
|
payload: "BytesIOSegmentPayload",
|
|
@@ -310,7 +310,7 @@ async def blob_upload_file(
|
|
|
310
310
|
return blob_id
|
|
311
311
|
|
|
312
312
|
|
|
313
|
-
@retry(n_attempts=5, base_delay=0.1,
|
|
313
|
+
@retry(n_attempts=5, base_delay=0.1, attempt_timeout=None)
|
|
314
314
|
async def _download_from_url(download_url: str) -> bytes:
|
|
315
315
|
async with ClientSessionRegistry.get_session().get(download_url) as s3_resp:
|
|
316
316
|
# S3 signal to slow down request rate.
|
|
@@ -89,6 +89,10 @@ RETRYABLE_GRPC_STATUS_CODES = [
|
|
|
89
89
|
Status.UNKNOWN,
|
|
90
90
|
]
|
|
91
91
|
SERVER_RETRY_WARNING_TIME_INTERVAL = 30.0
|
|
92
|
+
# Initial per-attempt timeout for TCP/TLS handshake in connect_channel.
|
|
93
|
+
# Doubles each attempt (attempt_timeout_factor=2): 0.5 + 1 + 2 + 4 + 8 = 15.5s + ~1.5s inter-attempt delays.
|
|
94
|
+
CONNECT_TIMEOUT = 0.5
|
|
95
|
+
DEFAULT_MAX_RETRIES = 3
|
|
92
96
|
|
|
93
97
|
|
|
94
98
|
@dataclass
|
|
@@ -117,7 +121,7 @@ class ConnectionManager:
|
|
|
117
121
|
self._channels[server_url] = create_channel(server_url, self._metadata)
|
|
118
122
|
try:
|
|
119
123
|
await connect_channel(self._channels[server_url])
|
|
120
|
-
except OSError as exc:
|
|
124
|
+
except (OSError, asyncio.TimeoutError) as exc:
|
|
121
125
|
raise ConnectionError("Could not connect to the Modal server.") from exc
|
|
122
126
|
return self._channels[server_url]
|
|
123
127
|
|
|
@@ -221,7 +225,7 @@ def create_channel(
|
|
|
221
225
|
return channel
|
|
222
226
|
|
|
223
227
|
|
|
224
|
-
@retry(n_attempts=5, base_delay=0.1)
|
|
228
|
+
@retry(n_attempts=5, base_delay=0.1, attempt_timeout=CONNECT_TIMEOUT, attempt_timeout_factor=2)
|
|
225
229
|
async def connect_channel(channel: grpclib.client.Channel):
|
|
226
230
|
"""Connect to socket and raise exceptions when there is a connection issue."""
|
|
227
231
|
await channel.__connect__()
|
|
@@ -246,7 +250,7 @@ class Retry:
|
|
|
246
250
|
base_delay: float = 0.1
|
|
247
251
|
max_delay: float = 1
|
|
248
252
|
delay_factor: float = 2
|
|
249
|
-
max_retries: Optional[int] =
|
|
253
|
+
max_retries: Optional[int] = DEFAULT_MAX_RETRIES
|
|
250
254
|
additional_status_codes: list = field(default_factory=list)
|
|
251
255
|
attempt_timeout: Optional[float] = None # timeout for each attempt
|
|
252
256
|
total_timeout: Optional[float] = None # timeout for the entire function call
|
|
@@ -257,7 +261,7 @@ class Retry:
|
|
|
257
261
|
async def retry_transient_errors(
|
|
258
262
|
fn: "grpclib.client.UnaryUnaryMethod[RequestType, ResponseType]",
|
|
259
263
|
req: RequestType,
|
|
260
|
-
max_retries: Optional[int] =
|
|
264
|
+
max_retries: Optional[int] = DEFAULT_MAX_RETRIES,
|
|
261
265
|
) -> ResponseType:
|
|
262
266
|
"""Minimum API version of _retry_transient_errors that works with grpclib.client.UnaryUnaryMethod.
|
|
263
267
|
|
|
@@ -373,7 +377,13 @@ async def _retry_transient_errors(
|
|
|
373
377
|
try:
|
|
374
378
|
with suppress_tb_frame():
|
|
375
379
|
return await fn_callable(req, metadata=attempt_metadata, timeout=timeout)
|
|
376
|
-
except (
|
|
380
|
+
except (
|
|
381
|
+
StreamTerminatedError,
|
|
382
|
+
GRPCError,
|
|
383
|
+
OSError,
|
|
384
|
+
asyncio.TimeoutError,
|
|
385
|
+
AttributeError,
|
|
386
|
+
) as exc:
|
|
377
387
|
# Note that we only catch AttributeError to handle a specific case that works around a bug
|
|
378
388
|
# in grpclib<=0.4.7. See above (search for `write_appdata`).
|
|
379
389
|
|
|
@@ -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.3.6.
|
|
38
|
+
version: str = "1.3.6.dev9",
|
|
39
39
|
):
|
|
40
40
|
"""mdmd:hidden
|
|
41
41
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -171,7 +171,7 @@ class Client:
|
|
|
171
171
|
server_url: str,
|
|
172
172
|
client_type: int,
|
|
173
173
|
credentials: typing.Optional[tuple[str, str]],
|
|
174
|
-
version: str = "1.3.6.
|
|
174
|
+
version: str = "1.3.6.dev9",
|
|
175
175
|
):
|
|
176
176
|
"""mdmd:hidden
|
|
177
177
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -408,7 +408,7 @@ class Function(
|
|
|
408
408
|
|
|
409
409
|
_call_generator: ___call_generator_spec
|
|
410
410
|
|
|
411
|
-
class __remote_spec(typing_extensions.Protocol[
|
|
411
|
+
class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
412
412
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
|
|
413
413
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result."""
|
|
414
414
|
...
|
|
@@ -417,7 +417,7 @@ class Function(
|
|
|
417
417
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result."""
|
|
418
418
|
...
|
|
419
419
|
|
|
420
|
-
remote: __remote_spec[modal._functions.
|
|
420
|
+
remote: __remote_spec[modal._functions.ReturnType, modal._functions.P]
|
|
421
421
|
|
|
422
422
|
class __remote_gen_spec(typing_extensions.Protocol):
|
|
423
423
|
def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
|
|
@@ -444,7 +444,7 @@ class Function(
|
|
|
444
444
|
"""
|
|
445
445
|
...
|
|
446
446
|
|
|
447
|
-
class ___experimental_spawn_spec(typing_extensions.Protocol[
|
|
447
|
+
class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
448
448
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
449
449
|
"""[Experimental] Calls the function with the given arguments, without waiting for the results.
|
|
450
450
|
|
|
@@ -467,7 +467,7 @@ class Function(
|
|
|
467
467
|
"""
|
|
468
468
|
...
|
|
469
469
|
|
|
470
|
-
_experimental_spawn: ___experimental_spawn_spec[modal._functions.
|
|
470
|
+
_experimental_spawn: ___experimental_spawn_spec[modal._functions.ReturnType, modal._functions.P]
|
|
471
471
|
|
|
472
472
|
class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER]):
|
|
473
473
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
|
|
@@ -475,7 +475,7 @@ class Function(
|
|
|
475
475
|
|
|
476
476
|
_spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P]
|
|
477
477
|
|
|
478
|
-
class __spawn_spec(typing_extensions.Protocol[
|
|
478
|
+
class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
479
479
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
480
480
|
"""Calls the function with the given arguments, without waiting for the results.
|
|
481
481
|
|
|
@@ -496,7 +496,7 @@ class Function(
|
|
|
496
496
|
"""
|
|
497
497
|
...
|
|
498
498
|
|
|
499
|
-
spawn: __spawn_spec[modal._functions.
|
|
499
|
+
spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P]
|
|
500
500
|
|
|
501
501
|
def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
|
|
502
502
|
"""Return the inner Python object wrapped by this Modal Function."""
|
|
@@ -740,7 +740,7 @@ class _Volume(_Object, type_prefix="vo"):
|
|
|
740
740
|
except modal.exception.NotFoundError as exc:
|
|
741
741
|
raise FileNotFoundError(exc.args[0])
|
|
742
742
|
|
|
743
|
-
@retry(n_attempts=5, base_delay=0.1,
|
|
743
|
+
@retry(n_attempts=5, base_delay=0.1, attempt_timeout=None)
|
|
744
744
|
async def read_block(block_url: str) -> bytes:
|
|
745
745
|
async with ClientSessionRegistry.get_session().get(block_url) as get_response:
|
|
746
746
|
get_response.raise_for_status()
|
|
@@ -806,7 +806,7 @@ class _Volume(_Object, type_prefix="vo"):
|
|
|
806
806
|
write_lock = asyncio.Lock()
|
|
807
807
|
start_pos = fileobj.tell()
|
|
808
808
|
|
|
809
|
-
@retry(n_attempts=5, base_delay=0.1,
|
|
809
|
+
@retry(n_attempts=5, base_delay=0.1, attempt_timeout=None)
|
|
810
810
|
async def download_block(idx, url) -> int:
|
|
811
811
|
block_start_pos = start_pos + idx * BLOCK_SIZE
|
|
812
812
|
num_bytes_written = 0
|
|
@@ -1369,7 +1369,7 @@ async def _put_missing_blocks(
|
|
|
1369
1369
|
file_progress.pending_blocks.add(missing_block.block_index)
|
|
1370
1370
|
task_progress_cb = functools.partial(progress_cb, task_id=file_progress.task_id)
|
|
1371
1371
|
|
|
1372
|
-
@retry(n_attempts=11, base_delay=0.5,
|
|
1372
|
+
@retry(n_attempts=11, base_delay=0.5, attempt_timeout=None)
|
|
1373
1373
|
async def put_missing_block_attempt(payload: BytesIOSegmentPayload) -> bytes:
|
|
1374
1374
|
with payload.reset_on_error(subtract_progress=True):
|
|
1375
1375
|
async with ClientSessionRegistry.get_session().put(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modal
|
|
3
|
-
Version: 1.3.6.
|
|
3
|
+
Version: 1.3.6.dev9
|
|
4
4
|
Summary: Python client library for Modal
|
|
5
5
|
Author-email: Modal Labs <support@modal.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -36,7 +36,6 @@ Dynamic: license-file
|
|
|
36
36
|
|
|
37
37
|
[](https://pypi.org/project/modal/)
|
|
38
38
|
[](https://github.com/modal-labs/modal-client/blob/master/LICENSE)
|
|
39
|
-
[](https://github.com/modal-labs/modal-client/actions/workflows/ci-cd.yml)
|
|
40
39
|
[](https://modal.com/slack)
|
|
41
40
|
|
|
42
41
|
The [Modal](https://modal.com/) Python SDK provides convenient, on-demand
|
|
@@ -28,7 +28,7 @@ dependencies = [
|
|
|
28
28
|
"types-certifi",
|
|
29
29
|
"types-toml",
|
|
30
30
|
"watchfiles",
|
|
31
|
-
"typing_extensions~=4.6"
|
|
31
|
+
"typing_extensions~=4.6",
|
|
32
32
|
]
|
|
33
33
|
keywords = ["modal", "client", "cloud", "serverless", "infrastructure"]
|
|
34
34
|
classifiers = [
|
|
@@ -37,6 +37,51 @@ classifiers = [
|
|
|
37
37
|
"Programming Language :: Python :: 3"
|
|
38
38
|
]
|
|
39
39
|
|
|
40
|
+
[dependency-groups]
|
|
41
|
+
dev = [
|
|
42
|
+
"cbor2==5.7.0",
|
|
43
|
+
"fastapi~=0.125",
|
|
44
|
+
"flaky~=3.8",
|
|
45
|
+
"grpclib==0.4.9",
|
|
46
|
+
"invoke~=2.2",
|
|
47
|
+
"httpx~=0.27.2",
|
|
48
|
+
"pyjwt~=2.10.1",
|
|
49
|
+
"pre-commit>=2.21,<4",
|
|
50
|
+
"mypy~=1.18.2",
|
|
51
|
+
"packaging>=23.1",
|
|
52
|
+
"pytest~=8.4.0",
|
|
53
|
+
"pytest-asyncio @ git+https://github.com/modal-labs/pytest-asyncio.git@af3f2d721b842309749cd26e5bbdd210e17d80c8",
|
|
54
|
+
"pytest-env~=1.1.5",
|
|
55
|
+
"pytest-markdown-docs==0.9.1",
|
|
56
|
+
"pytest-timeout~=2.4.0",
|
|
57
|
+
"python-dotenv~=1.0.0",
|
|
58
|
+
"requests~=2.32.4",
|
|
59
|
+
"ruff~=0.9.6",
|
|
60
|
+
"setuptools<82", # Required by grpcio-tools for pkg_resources (v82+ removed pkg_resources)"
|
|
61
|
+
"types-croniter~=1.0.8",
|
|
62
|
+
"types-python-dateutil~=2.8.10",
|
|
63
|
+
"types-requests~=2.31.0",
|
|
64
|
+
"types-setuptools~=57.4.11",
|
|
65
|
+
"types-six~=1.16.21",
|
|
66
|
+
"types-toml~=0.10.4",
|
|
67
|
+
"wheel~=0.38.1",
|
|
68
|
+
"nbclient~=0.10.2",
|
|
69
|
+
"notebook~=7.5.4",
|
|
70
|
+
"jupytext~=1.19.1",
|
|
71
|
+
"pyright~=1.1.351",
|
|
72
|
+
"console-ctrl~=0.1.0",
|
|
73
|
+
"zstandard~=0.25.0",
|
|
74
|
+
"synchronicity[compile]==0.11.1",
|
|
75
|
+
"python-json-logger==2.0.7",
|
|
76
|
+
"build~=1.3.0",
|
|
77
|
+
|
|
78
|
+
"mypy-protobuf",
|
|
79
|
+
"grpcio-tools",
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
[tool.uv.extra-build-dependencies]
|
|
83
|
+
grpcio-tools = ["setuptools<82"]
|
|
84
|
+
|
|
40
85
|
[project.urls]
|
|
41
86
|
Homepage = "https://modal.com"
|
|
42
87
|
Source = "https://github.com/modal-labs/modal-client"
|
|
@@ -122,6 +167,7 @@ extend-select = ['PLR1702']
|
|
|
122
167
|
"modal_docs/**" = ['T201']
|
|
123
168
|
"modal_global_objects/**" = ['T201']
|
|
124
169
|
"tasks.py" = ['T201']
|
|
170
|
+
"compile_protos.py" = ['T201']
|
|
125
171
|
"modal/__init__.py" = ['T201']
|
|
126
172
|
"modal/experimental/ipython.py" = ['T201']
|
|
127
173
|
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|