modal 1.4.1.dev5__tar.gz → 1.4.2.dev0__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.4.1.dev5 → modal-1.4.2.dev0}/PKG-INFO +2 -2
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/sandbox_fs_utils.py +35 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/time_utils.py +55 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/client.pyi +2 -2
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/exception.py +6 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/sandbox.py +19 -18
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/sandbox.pyi +19 -18
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/sandbox_fs.py +48 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/sandbox_fs.pyi +120 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal.egg-info/PKG-INFO +2 -2
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal.egg-info/requires.txt +1 -1
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_version/__init__.py +1 -1
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/pyproject.toml +2 -2
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/LICENSE +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/README.md +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/__init__.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/__main__.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_billing.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_clustered_functions.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_clustered_functions.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_container_entrypoint.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_functions.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_grpc_client.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_ipython.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_load_context.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_location.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_logs.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_object.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_output/__init__.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_output/manager.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_output/pty.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_output/rich.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_output/status.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_partial_function.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_resolver.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_resources.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_runtime/__init__.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_runtime/asgi.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_runtime/execution_context.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_runtime/telemetry.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_serialization.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_server.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_traceback.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_tunnel.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_tunnel.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_type_manager.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/__init__.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/app_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/async_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/blob_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/browser_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/deprecation.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/docker_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/function_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/git_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/hash_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/http_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/logger.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/mount_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/name_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/package_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/shell_utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_vendor/__init__.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_vendor/tblib.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_vendor/version.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/_watcher.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/app.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/app.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/billing.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/builder/2023.12.txt +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/builder/2024.04.txt +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/builder/2024.10.txt +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/builder/2025.06.txt +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/builder/README.md +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/builder/base-images.json +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/call_graph.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/__init__.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/_download.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/_traceback.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/app.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/billing.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/changelog.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/cluster.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/config.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/container.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/dashboard.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/dict.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/entry_point.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/environment.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/import_refs.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/launch.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/network_file_system.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/profile.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/programs/__init__.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/programs/vscode.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/queues.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/run.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/secret.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/selector.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/shell.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/token.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/utils.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cli/volume.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/client.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cls.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/cls.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/config.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/container_process.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/container_process.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/dict.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/dict.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/environments.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/environments.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/experimental/__init__.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/experimental/flash.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/experimental/flash.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/experimental/ipython.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/file_io.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/file_io.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/file_pattern_matcher.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/functions.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/functions.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/image.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/image.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/io_streams.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/io_streams.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/mount.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/mount.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/network_file_system.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/network_file_system.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/object.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/object.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/output.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/parallel_map.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/parallel_map.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/partial_function.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/partial_function.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/proxy.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/proxy.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/py.typed +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/queue.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/queue.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/retries.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/runner.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/runner.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/running_app.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/schedule.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/scheduler_placement.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/secret.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/secret.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/server.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/server.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/serving.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/serving.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/snapshot.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/snapshot.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/stream_type.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/token_flow.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/token_flow.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/volume.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal/volume.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal.egg-info/top_level.txt +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_docs/__init__.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_proto/__init__.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_proto/api_grpc.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_proto/api_pb2.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_proto/api_pb2.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_proto/py.typed +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/modal_version/__main__.py +0 -0
- {modal-1.4.1.dev5 → modal-1.4.2.dev0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modal
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.2.dev0
|
|
4
4
|
Summary: Python client library for Modal
|
|
5
5
|
Author-email: Modal Labs <support@modal.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -23,7 +23,7 @@ Requires-Dist: grpclib<0.4.10,>=0.4.7; python_version < "3.14"
|
|
|
23
23
|
Requires-Dist: grpclib<0.4.10,>=0.4.9; python_version >= "3.14"
|
|
24
24
|
Requires-Dist: protobuf!=4.24.0,<7.0,>=3.19
|
|
25
25
|
Requires-Dist: rich>=12.0.0
|
|
26
|
-
Requires-Dist: synchronicity~=0.12.
|
|
26
|
+
Requires-Dist: synchronicity~=0.12.1
|
|
27
27
|
Requires-Dist: toml
|
|
28
28
|
Requires-Dist: typer>=0.9
|
|
29
29
|
Requires-Dist: types-certifi
|
|
@@ -12,6 +12,7 @@ from ..exception import (
|
|
|
12
12
|
Error as ModalError,
|
|
13
13
|
InvalidError,
|
|
14
14
|
NotFoundError,
|
|
15
|
+
SandboxFilesystemDirectoryNotEmptyError,
|
|
15
16
|
SandboxFilesystemError,
|
|
16
17
|
SandboxFilesystemFileTooLargeError,
|
|
17
18
|
SandboxFilesystemIsADirectoryError,
|
|
@@ -153,6 +154,40 @@ def make_read_file_command(remote_path: str) -> str:
|
|
|
153
154
|
return json.dumps({"ReadFile": {"path": remote_path}})
|
|
154
155
|
|
|
155
156
|
|
|
157
|
+
def make_remove_command(remote_path: str, recursive: bool) -> str:
|
|
158
|
+
"""Build the JSON command string for a Remove operation.
|
|
159
|
+
|
|
160
|
+
The returned JSON must match the `Command` enum in the modal-sandbox-fs-tools
|
|
161
|
+
Rust crate (crates/modal-sandbox-fs-tools/src/lib.rs). Treat changes to
|
|
162
|
+
this schema like protobuf changes: fields must not be removed or renamed,
|
|
163
|
+
only added with backwards-compatible defaults.
|
|
164
|
+
"""
|
|
165
|
+
return json.dumps({"Remove": {"path": remote_path, "recursive": recursive}})
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def raise_remove_error(returncode: int, stderr: Union[str, bytes], remote_path: str) -> NoReturn:
|
|
169
|
+
if payload := try_parse_error_payload(stderr):
|
|
170
|
+
logger.debug(
|
|
171
|
+
f"sandbox-fs-tools remove error: path={remote_path}, "
|
|
172
|
+
f"error_kind={payload.error_kind}, message={payload.message}, detail={payload.detail}"
|
|
173
|
+
)
|
|
174
|
+
if payload.error_kind == "NotFound":
|
|
175
|
+
raise SandboxFilesystemNotFoundError(f"{payload.message}: {remote_path}")
|
|
176
|
+
if payload.error_kind == "DirectoryNotEmpty":
|
|
177
|
+
raise SandboxFilesystemDirectoryNotEmptyError(f"{payload.message}: {remote_path}")
|
|
178
|
+
if payload.error_kind == "NotSupported":
|
|
179
|
+
raise InvalidError(
|
|
180
|
+
f"{payload.message}: {remote_path} - this operation is not supported for CloudBucketMounts"
|
|
181
|
+
)
|
|
182
|
+
if payload.error_kind == "PermissionDenied":
|
|
183
|
+
raise SandboxFilesystemPermissionError(f"{payload.message}: {remote_path}")
|
|
184
|
+
raise SandboxFilesystemError(payload.message)
|
|
185
|
+
|
|
186
|
+
if stderr_text := _stderr_to_text(stderr):
|
|
187
|
+
logger.debug(f"Unstructured modal-sandbox-fs-tools stderr: {stderr_text}")
|
|
188
|
+
raise SandboxFilesystemError(f"Operation on '{remote_path}' failed with exit code {returncode}")
|
|
189
|
+
|
|
190
|
+
|
|
156
191
|
def validate_absolute_remote_path(remote_path: str, operation: str) -> None:
|
|
157
192
|
if not PurePosixPath(remote_path).is_absolute():
|
|
158
193
|
raise InvalidError(f"Sandbox.filesystem.{operation}() currently only supports absolute remote_path values")
|
|
@@ -164,6 +164,61 @@ def parse_date_range(s: str, tz: Optional[tzinfo] = None) -> tuple[datetime, dat
|
|
|
164
164
|
raise ValueError(f"Unrecognized range: '{s}'. Accepted values: {accepted}")
|
|
165
165
|
|
|
166
166
|
|
|
167
|
+
def relative_timestamp(dt: datetime) -> str:
|
|
168
|
+
"""Convert a tz-aware datetime to a human-readable relative time string.
|
|
169
|
+
|
|
170
|
+
Examples: "just now", "30 seconds ago", "5 minutes ago", "2 hours ago",
|
|
171
|
+
"yesterday", "3 days ago", "2 weeks ago", "3 months ago", "1 year ago".
|
|
172
|
+
|
|
173
|
+
Raises ValueError if the datetime is naive (no tzinfo).
|
|
174
|
+
"""
|
|
175
|
+
if dt.tzinfo is None:
|
|
176
|
+
raise ValueError("datetime must be timezone-aware")
|
|
177
|
+
|
|
178
|
+
now = datetime.now(timezone.utc)
|
|
179
|
+
delta = now - dt
|
|
180
|
+
total_seconds = int(delta.total_seconds())
|
|
181
|
+
|
|
182
|
+
if total_seconds < 0:
|
|
183
|
+
return "just now"
|
|
184
|
+
|
|
185
|
+
if total_seconds < 10:
|
|
186
|
+
return "just now"
|
|
187
|
+
if total_seconds < 60:
|
|
188
|
+
return f"{total_seconds} seconds ago"
|
|
189
|
+
if total_seconds < 120:
|
|
190
|
+
return "1 minute ago"
|
|
191
|
+
|
|
192
|
+
minutes = total_seconds // 60
|
|
193
|
+
if minutes < 60:
|
|
194
|
+
return f"{minutes} minutes ago"
|
|
195
|
+
if minutes < 120:
|
|
196
|
+
return "1 hour ago"
|
|
197
|
+
|
|
198
|
+
hours = minutes // 60
|
|
199
|
+
if hours < 24:
|
|
200
|
+
return f"{hours} hours ago"
|
|
201
|
+
if hours < 48:
|
|
202
|
+
return "yesterday"
|
|
203
|
+
|
|
204
|
+
days = hours // 24
|
|
205
|
+
if days < 14:
|
|
206
|
+
return f"{days} days ago"
|
|
207
|
+
|
|
208
|
+
weeks = days // 7
|
|
209
|
+
if days < 60:
|
|
210
|
+
return f"{weeks} weeks ago"
|
|
211
|
+
|
|
212
|
+
months = days // 30
|
|
213
|
+
if days < 365:
|
|
214
|
+
return f"{months} months ago"
|
|
215
|
+
|
|
216
|
+
years = days // 365
|
|
217
|
+
if years == 1:
|
|
218
|
+
return "1 year ago"
|
|
219
|
+
return f"{years} years ago"
|
|
220
|
+
|
|
221
|
+
|
|
167
222
|
def locale_tz() -> tzinfo:
|
|
168
223
|
return datetime.now().astimezone().tzinfo
|
|
169
224
|
|
|
@@ -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.4.
|
|
38
|
+
version: str = "1.4.2.dev0",
|
|
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.4.
|
|
174
|
+
version: str = "1.4.2.dev0",
|
|
175
175
|
):
|
|
176
176
|
"""mdmd:hidden
|
|
177
177
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -351,6 +351,12 @@ class SandboxFilesystemNotFoundError(SandboxFilesystemError):
|
|
|
351
351
|
pass
|
|
352
352
|
|
|
353
353
|
|
|
354
|
+
class SandboxFilesystemDirectoryNotEmptyError(SandboxFilesystemError):
|
|
355
|
+
"""Raised when a directory is not empty."""
|
|
356
|
+
|
|
357
|
+
pass
|
|
358
|
+
|
|
359
|
+
|
|
354
360
|
class SandboxFilesystemIsADirectoryError(SandboxFilesystemError):
|
|
355
361
|
"""Raised when a file operation in the sandbox targets a directory when it should target a non-directory file."""
|
|
356
362
|
|
|
@@ -123,24 +123,25 @@ class SandboxConnectCredentials:
|
|
|
123
123
|
class Probe:
|
|
124
124
|
"""Probe configuration for the Sandbox Readiness Probe.
|
|
125
125
|
|
|
126
|
-
Usage
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
126
|
+
**Usage**
|
|
127
|
+
|
|
128
|
+
```python notest
|
|
129
|
+
# Wait until a file exists.
|
|
130
|
+
readiness_probe = modal.Probe.with_exec(
|
|
131
|
+
"sh", "-c", "test -f /tmp/ready",
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
# Wait until a TCP port is accepting connections.
|
|
135
|
+
readiness_probe = modal.Probe.with_tcp(8080)
|
|
136
|
+
|
|
137
|
+
app = modal.App.lookup('sandbox-readiness-probe', create_if_missing=True)
|
|
138
|
+
sandbox = modal.Sandbox.create(
|
|
139
|
+
"python3", "-m", "http.server", "8080",
|
|
140
|
+
readiness_probe=readiness_probe,
|
|
141
|
+
app=app,
|
|
142
|
+
)
|
|
143
|
+
sandbox.wait_until_ready()
|
|
144
|
+
```
|
|
144
145
|
"""
|
|
145
146
|
|
|
146
147
|
tcp_port: Optional[int] = None
|
|
@@ -74,24 +74,25 @@ class SandboxConnectCredentials:
|
|
|
74
74
|
class Probe:
|
|
75
75
|
"""Probe configuration for the Sandbox Readiness Probe.
|
|
76
76
|
|
|
77
|
-
Usage
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
77
|
+
**Usage**
|
|
78
|
+
|
|
79
|
+
```python notest
|
|
80
|
+
# Wait until a file exists.
|
|
81
|
+
readiness_probe = modal.Probe.with_exec(
|
|
82
|
+
"sh", "-c", "test -f /tmp/ready",
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
# Wait until a TCP port is accepting connections.
|
|
86
|
+
readiness_probe = modal.Probe.with_tcp(8080)
|
|
87
|
+
|
|
88
|
+
app = modal.App.lookup('sandbox-readiness-probe', create_if_missing=True)
|
|
89
|
+
sandbox = modal.Sandbox.create(
|
|
90
|
+
"python3", "-m", "http.server", "8080",
|
|
91
|
+
readiness_probe=readiness_probe,
|
|
92
|
+
app=app,
|
|
93
|
+
)
|
|
94
|
+
sandbox.wait_until_ready()
|
|
95
|
+
```
|
|
95
96
|
"""
|
|
96
97
|
|
|
97
98
|
tcp_port: typing.Optional[int]
|
|
@@ -12,8 +12,10 @@ from ._utils.async_utils import synchronize_api
|
|
|
12
12
|
from ._utils.logger import logger
|
|
13
13
|
from ._utils.sandbox_fs_utils import (
|
|
14
14
|
make_read_file_command,
|
|
15
|
+
make_remove_command,
|
|
15
16
|
make_write_file_command,
|
|
16
17
|
raise_read_file_error,
|
|
18
|
+
raise_remove_error,
|
|
17
19
|
raise_write_file_error,
|
|
18
20
|
translate_exec_errors,
|
|
19
21
|
validate_absolute_remote_path,
|
|
@@ -303,5 +305,51 @@ class _SandboxFilesystem:
|
|
|
303
305
|
dur_s = max(time.monotonic() - t0, 0.001)
|
|
304
306
|
_log_throughput(f"copy_from_local {local_path} -> {remote_path}", total_bytes, dur_s)
|
|
305
307
|
|
|
308
|
+
async def remove(self, remote_path: str, *, recursive: bool = False) -> None:
|
|
309
|
+
"""Remove a file or directory in the Sandbox.
|
|
310
|
+
|
|
311
|
+
`remote_path` must be an absolute path in the Sandbox.
|
|
312
|
+
|
|
313
|
+
When `remote_path` is a directory and `recursive` is `False` (the
|
|
314
|
+
default), removes it only if it is empty. When `recursive` is `True`,
|
|
315
|
+
removes the directory and all its contents.
|
|
316
|
+
|
|
317
|
+
Recursive directory removal is not supported on all mounts.
|
|
318
|
+
In particular, `CloudBucketMount` does not support it. An
|
|
319
|
+
`InvalidError` is raised in that case.
|
|
320
|
+
|
|
321
|
+
**Raises**
|
|
322
|
+
|
|
323
|
+
- `SandboxFilesystemNotFoundError`: the path does not exist.
|
|
324
|
+
- `SandboxFilesystemDirectoryNotEmptyError`: `recursive` is `False` and the directory is not empty.
|
|
325
|
+
- `SandboxFilesystemPermissionError`: removal is not permitted.
|
|
326
|
+
- `InvalidError`: the operation is not supported by the mount.
|
|
327
|
+
- `SandboxFilesystemError`: the command fails for any other reason.
|
|
328
|
+
|
|
329
|
+
**Usage**
|
|
330
|
+
|
|
331
|
+
To remove a file:
|
|
332
|
+
|
|
333
|
+
```python fixture:sandbox
|
|
334
|
+
sandbox.filesystem.write_bytes(b"Hello, world!\\n", "/tmp/hello.bin")
|
|
335
|
+
sandbox.filesystem.remove("/tmp/hello.bin")
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
To remove a directory and all its contents:
|
|
339
|
+
|
|
340
|
+
```python fixture:sandbox
|
|
341
|
+
sandbox.exec("mkdir", "-p", "/tmp/mydir/subdir").wait()
|
|
342
|
+
sandbox.filesystem.remove("/tmp/mydir", recursive=True)
|
|
343
|
+
```
|
|
344
|
+
"""
|
|
345
|
+
validate_absolute_remote_path(remote_path, "remove")
|
|
346
|
+
|
|
347
|
+
with translate_exec_errors("remove", remote_path):
|
|
348
|
+
process = await self._sandbox.exec(_SANDBOX_FS_TOOLS_PATH, make_remove_command(remote_path, recursive))
|
|
349
|
+
stderr, returncode = await asyncio.gather(process.stderr.read(), process.wait())
|
|
350
|
+
|
|
351
|
+
if returncode != 0:
|
|
352
|
+
raise_remove_error(returncode, stderr, remote_path)
|
|
353
|
+
|
|
306
354
|
|
|
307
355
|
SandboxFilesystem = synchronize_api(_SandboxFilesystem)
|
|
@@ -168,6 +168,45 @@ class _SandboxFilesystem:
|
|
|
168
168
|
"""
|
|
169
169
|
...
|
|
170
170
|
|
|
171
|
+
async def remove(self, remote_path: str, *, recursive: bool = False) -> None:
|
|
172
|
+
"""Remove a file or directory in the Sandbox.
|
|
173
|
+
|
|
174
|
+
`remote_path` must be an absolute path in the Sandbox.
|
|
175
|
+
|
|
176
|
+
When `remote_path` is a directory and `recursive` is `False` (the
|
|
177
|
+
default), removes it only if it is empty. When `recursive` is `True`,
|
|
178
|
+
removes the directory and all its contents.
|
|
179
|
+
|
|
180
|
+
Recursive directory removal is not supported on all mounts.
|
|
181
|
+
In particular, `CloudBucketMount` does not support it. An
|
|
182
|
+
`InvalidError` is raised in that case.
|
|
183
|
+
|
|
184
|
+
**Raises**
|
|
185
|
+
|
|
186
|
+
- `SandboxFilesystemNotFoundError`: the path does not exist.
|
|
187
|
+
- `SandboxFilesystemDirectoryNotEmptyError`: `recursive` is `False` and the directory is not empty.
|
|
188
|
+
- `SandboxFilesystemPermissionError`: removal is not permitted.
|
|
189
|
+
- `InvalidError`: the operation is not supported by the mount.
|
|
190
|
+
- `SandboxFilesystemError`: the command fails for any other reason.
|
|
191
|
+
|
|
192
|
+
**Usage**
|
|
193
|
+
|
|
194
|
+
To remove a file:
|
|
195
|
+
|
|
196
|
+
```python fixture:sandbox
|
|
197
|
+
sandbox.filesystem.write_bytes(b"Hello, world!\n", "/tmp/hello.bin")
|
|
198
|
+
sandbox.filesystem.remove("/tmp/hello.bin")
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
To remove a directory and all its contents:
|
|
202
|
+
|
|
203
|
+
```python fixture:sandbox
|
|
204
|
+
sandbox.exec("mkdir", "-p", "/tmp/mydir/subdir").wait()
|
|
205
|
+
sandbox.filesystem.remove("/tmp/mydir", recursive=True)
|
|
206
|
+
```
|
|
207
|
+
"""
|
|
208
|
+
...
|
|
209
|
+
|
|
171
210
|
class SandboxFilesystem:
|
|
172
211
|
"""mdmd:namespace
|
|
173
212
|
Namespace for Sandbox filesystem APIs.
|
|
@@ -505,3 +544,84 @@ class SandboxFilesystem:
|
|
|
505
544
|
...
|
|
506
545
|
|
|
507
546
|
copy_from_local: __copy_from_local_spec
|
|
547
|
+
|
|
548
|
+
class __remove_spec(typing_extensions.Protocol):
|
|
549
|
+
def __call__(self, /, remote_path: str, *, recursive: bool = False) -> None:
|
|
550
|
+
"""Remove a file or directory in the Sandbox.
|
|
551
|
+
|
|
552
|
+
`remote_path` must be an absolute path in the Sandbox.
|
|
553
|
+
|
|
554
|
+
When `remote_path` is a directory and `recursive` is `False` (the
|
|
555
|
+
default), removes it only if it is empty. When `recursive` is `True`,
|
|
556
|
+
removes the directory and all its contents.
|
|
557
|
+
|
|
558
|
+
Recursive directory removal is not supported on all mounts.
|
|
559
|
+
In particular, `CloudBucketMount` does not support it. An
|
|
560
|
+
`InvalidError` is raised in that case.
|
|
561
|
+
|
|
562
|
+
**Raises**
|
|
563
|
+
|
|
564
|
+
- `SandboxFilesystemNotFoundError`: the path does not exist.
|
|
565
|
+
- `SandboxFilesystemDirectoryNotEmptyError`: `recursive` is `False` and the directory is not empty.
|
|
566
|
+
- `SandboxFilesystemPermissionError`: removal is not permitted.
|
|
567
|
+
- `InvalidError`: the operation is not supported by the mount.
|
|
568
|
+
- `SandboxFilesystemError`: the command fails for any other reason.
|
|
569
|
+
|
|
570
|
+
**Usage**
|
|
571
|
+
|
|
572
|
+
To remove a file:
|
|
573
|
+
|
|
574
|
+
```python fixture:sandbox
|
|
575
|
+
sandbox.filesystem.write_bytes(b"Hello, world!\n", "/tmp/hello.bin")
|
|
576
|
+
sandbox.filesystem.remove("/tmp/hello.bin")
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
To remove a directory and all its contents:
|
|
580
|
+
|
|
581
|
+
```python fixture:sandbox
|
|
582
|
+
sandbox.exec("mkdir", "-p", "/tmp/mydir/subdir").wait()
|
|
583
|
+
sandbox.filesystem.remove("/tmp/mydir", recursive=True)
|
|
584
|
+
```
|
|
585
|
+
"""
|
|
586
|
+
...
|
|
587
|
+
|
|
588
|
+
async def aio(self, /, remote_path: str, *, recursive: bool = False) -> None:
|
|
589
|
+
"""Remove a file or directory in the Sandbox.
|
|
590
|
+
|
|
591
|
+
`remote_path` must be an absolute path in the Sandbox.
|
|
592
|
+
|
|
593
|
+
When `remote_path` is a directory and `recursive` is `False` (the
|
|
594
|
+
default), removes it only if it is empty. When `recursive` is `True`,
|
|
595
|
+
removes the directory and all its contents.
|
|
596
|
+
|
|
597
|
+
Recursive directory removal is not supported on all mounts.
|
|
598
|
+
In particular, `CloudBucketMount` does not support it. An
|
|
599
|
+
`InvalidError` is raised in that case.
|
|
600
|
+
|
|
601
|
+
**Raises**
|
|
602
|
+
|
|
603
|
+
- `SandboxFilesystemNotFoundError`: the path does not exist.
|
|
604
|
+
- `SandboxFilesystemDirectoryNotEmptyError`: `recursive` is `False` and the directory is not empty.
|
|
605
|
+
- `SandboxFilesystemPermissionError`: removal is not permitted.
|
|
606
|
+
- `InvalidError`: the operation is not supported by the mount.
|
|
607
|
+
- `SandboxFilesystemError`: the command fails for any other reason.
|
|
608
|
+
|
|
609
|
+
**Usage**
|
|
610
|
+
|
|
611
|
+
To remove a file:
|
|
612
|
+
|
|
613
|
+
```python fixture:sandbox
|
|
614
|
+
sandbox.filesystem.write_bytes(b"Hello, world!\n", "/tmp/hello.bin")
|
|
615
|
+
sandbox.filesystem.remove("/tmp/hello.bin")
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
To remove a directory and all its contents:
|
|
619
|
+
|
|
620
|
+
```python fixture:sandbox
|
|
621
|
+
sandbox.exec("mkdir", "-p", "/tmp/mydir/subdir").wait()
|
|
622
|
+
sandbox.filesystem.remove("/tmp/mydir", recursive=True)
|
|
623
|
+
```
|
|
624
|
+
"""
|
|
625
|
+
...
|
|
626
|
+
|
|
627
|
+
remove: __remove_spec
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modal
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.2.dev0
|
|
4
4
|
Summary: Python client library for Modal
|
|
5
5
|
Author-email: Modal Labs <support@modal.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -23,7 +23,7 @@ Requires-Dist: grpclib<0.4.10,>=0.4.7; python_version < "3.14"
|
|
|
23
23
|
Requires-Dist: grpclib<0.4.10,>=0.4.9; python_version >= "3.14"
|
|
24
24
|
Requires-Dist: protobuf!=4.24.0,<7.0,>=3.19
|
|
25
25
|
Requires-Dist: rich>=12.0.0
|
|
26
|
-
Requires-Dist: synchronicity~=0.12.
|
|
26
|
+
Requires-Dist: synchronicity~=0.12.1
|
|
27
27
|
Requires-Dist: toml
|
|
28
28
|
Requires-Dist: typer>=0.9
|
|
29
29
|
Requires-Dist: types-certifi
|
|
@@ -22,7 +22,7 @@ dependencies = [
|
|
|
22
22
|
"grpclib>=0.4.9,<0.4.10 ; python_version >= '3.14'",
|
|
23
23
|
"protobuf>=3.19,<7.0,!=4.24.0",
|
|
24
24
|
"rich>=12.0.0",
|
|
25
|
-
"synchronicity~=0.12.
|
|
25
|
+
"synchronicity~=0.12.1",
|
|
26
26
|
"toml",
|
|
27
27
|
"typer>=0.9",
|
|
28
28
|
"types-certifi",
|
|
@@ -71,7 +71,7 @@ dev = [
|
|
|
71
71
|
"pyright~=1.1.351",
|
|
72
72
|
"console-ctrl~=0.1.0",
|
|
73
73
|
"zstandard~=0.25.0",
|
|
74
|
-
"synchronicity[compile]~=0.12.
|
|
74
|
+
"synchronicity[compile]~=0.12.1",
|
|
75
75
|
"python-json-logger==2.0.7",
|
|
76
76
|
"build~=1.3.0",
|
|
77
77
|
|
|
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
|