truss 0.10.0rc1__py3-none-any.whl → 0.60.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of truss might be problematic. Click here for more details.
- truss/__init__.py +10 -3
- truss/api/__init__.py +123 -0
- truss/api/definitions.py +51 -0
- truss/base/constants.py +116 -0
- truss/base/custom_types.py +29 -0
- truss/{errors.py → base/errors.py} +4 -0
- truss/base/trt_llm_config.py +310 -0
- truss/{truss_config.py → base/truss_config.py} +344 -31
- truss/{truss_spec.py → base/truss_spec.py} +20 -6
- truss/{validation.py → base/validation.py} +60 -11
- truss/cli/cli.py +841 -88
- truss/{remote → cli}/remote_cli.py +2 -7
- truss/contexts/docker_build_setup.py +67 -0
- truss/contexts/image_builder/cache_warmer.py +2 -8
- truss/contexts/image_builder/image_builder.py +1 -1
- truss/contexts/image_builder/serving_image_builder.py +292 -46
- truss/contexts/image_builder/util.py +1 -3
- truss/contexts/local_loader/docker_build_emulator.py +58 -0
- truss/contexts/local_loader/load_model_local.py +2 -2
- truss/contexts/local_loader/truss_module_loader.py +1 -1
- truss/contexts/local_loader/utils.py +1 -1
- truss/local/local_config.py +2 -6
- truss/local/local_config_handler.py +20 -5
- truss/patch/__init__.py +1 -0
- truss/patch/hash.py +4 -70
- truss/patch/signature.py +4 -16
- truss/patch/truss_dir_patch_applier.py +3 -78
- truss/remote/baseten/api.py +308 -23
- truss/remote/baseten/auth.py +3 -3
- truss/remote/baseten/core.py +257 -50
- truss/remote/baseten/custom_types.py +44 -0
- truss/remote/baseten/error.py +4 -0
- truss/remote/baseten/remote.py +369 -118
- truss/remote/baseten/service.py +118 -11
- truss/remote/baseten/utils/status.py +29 -0
- truss/remote/baseten/utils/tar.py +34 -22
- truss/remote/baseten/utils/transfer.py +36 -23
- truss/remote/remote_factory.py +14 -5
- truss/remote/truss_remote.py +72 -45
- truss/templates/base.Dockerfile.jinja +18 -16
- truss/templates/cache.Dockerfile.jinja +3 -3
- truss/{server → templates/control}/control/application.py +14 -35
- truss/{server → templates/control}/control/endpoints.py +39 -9
- truss/{server/control/patch/types.py → templates/control/control/helpers/custom_types.py} +13 -52
- truss/{server → templates/control}/control/helpers/inference_server_controller.py +4 -8
- truss/{server → templates/control}/control/helpers/inference_server_process_controller.py +2 -4
- truss/{server → templates/control}/control/helpers/inference_server_starter.py +5 -10
- truss/{server/control → templates/control/control/helpers}/truss_patch/model_code_patch_applier.py +8 -6
- truss/{server/control/patch → templates/control/control/helpers/truss_patch}/model_container_patch_applier.py +18 -26
- truss/templates/control/control/helpers/truss_patch/requirement_name_identifier.py +66 -0
- truss/{server → templates/control}/control/server.py +11 -6
- truss/templates/control/requirements.txt +9 -0
- truss/templates/custom_python_dx/my_model.py +28 -0
- truss/templates/docker_server/proxy.conf.jinja +42 -0
- truss/templates/docker_server/supervisord.conf.jinja +27 -0
- truss/templates/docker_server_requirements.txt +1 -0
- truss/templates/server/common/errors.py +231 -0
- truss/{server → templates/server}/common/patches/whisper/patch.py +1 -0
- truss/{server/common/patches/__init__.py → templates/server/common/patches.py} +1 -3
- truss/{server → templates/server}/common/retry.py +1 -0
- truss/{server → templates/server}/common/schema.py +11 -9
- truss/templates/server/common/tracing.py +157 -0
- truss/templates/server/main.py +9 -0
- truss/templates/server/model_wrapper.py +961 -0
- truss/templates/server/requirements.txt +21 -0
- truss/templates/server/truss_server.py +447 -0
- truss/templates/server.Dockerfile.jinja +62 -14
- truss/templates/shared/dynamic_config_resolver.py +28 -0
- truss/templates/shared/lazy_data_resolver.py +164 -0
- truss/templates/shared/log_config.py +125 -0
- truss/{server → templates}/shared/secrets_resolver.py +1 -2
- truss/{server → templates}/shared/serialization.py +31 -9
- truss/{server → templates}/shared/util.py +3 -13
- truss/templates/trtllm-audio/model/model.py +49 -0
- truss/templates/trtllm-audio/packages/sigint_patch.py +14 -0
- truss/templates/trtllm-audio/packages/whisper_trt/__init__.py +215 -0
- truss/templates/trtllm-audio/packages/whisper_trt/assets.py +25 -0
- truss/templates/trtllm-audio/packages/whisper_trt/batching.py +52 -0
- truss/templates/trtllm-audio/packages/whisper_trt/custom_types.py +26 -0
- truss/templates/trtllm-audio/packages/whisper_trt/modeling.py +184 -0
- truss/templates/trtllm-audio/packages/whisper_trt/tokenizer.py +185 -0
- truss/templates/trtllm-audio/packages/whisper_trt/utils.py +245 -0
- truss/templates/trtllm-briton/src/extension.py +64 -0
- truss/tests/conftest.py +302 -94
- truss/tests/contexts/image_builder/test_serving_image_builder.py +74 -31
- truss/tests/contexts/local_loader/test_load_local.py +2 -2
- truss/tests/contexts/local_loader/test_truss_module_finder.py +1 -1
- truss/tests/patch/test_calc_patch.py +439 -127
- truss/tests/patch/test_dir_signature.py +3 -12
- truss/tests/patch/test_hash.py +1 -1
- truss/tests/patch/test_signature.py +1 -1
- truss/tests/patch/test_truss_dir_patch_applier.py +23 -11
- truss/tests/patch/test_types.py +2 -2
- truss/tests/remote/baseten/test_api.py +153 -58
- truss/tests/remote/baseten/test_auth.py +2 -1
- truss/tests/remote/baseten/test_core.py +160 -12
- truss/tests/remote/baseten/test_remote.py +489 -77
- truss/tests/remote/baseten/test_service.py +55 -0
- truss/tests/remote/test_remote_factory.py +16 -18
- truss/tests/remote/test_truss_remote.py +26 -17
- truss/tests/templates/control/control/helpers/test_context_managers.py +11 -0
- truss/tests/templates/control/control/helpers/test_model_container_patch_applier.py +184 -0
- truss/tests/templates/control/control/helpers/test_requirement_name_identifier.py +89 -0
- truss/tests/{server → templates/control}/control/test_server.py +79 -24
- truss/tests/{server → templates/control}/control/test_server_integration.py +24 -16
- truss/tests/templates/core/server/test_dynamic_config_resolver.py +108 -0
- truss/tests/templates/core/server/test_lazy_data_resolver.py +329 -0
- truss/tests/templates/core/server/test_lazy_data_resolver_v2.py +79 -0
- truss/tests/{server → templates}/core/server/test_secrets_resolver.py +1 -1
- truss/tests/{server → templates/server}/common/test_retry.py +3 -3
- truss/tests/templates/server/test_model_wrapper.py +248 -0
- truss/tests/{server → templates/server}/test_schema.py +3 -5
- truss/tests/{server/core/server/common → templates/server}/test_truss_server.py +8 -5
- truss/tests/test_build.py +9 -52
- truss/tests/test_config.py +336 -77
- truss/tests/test_context_builder_image.py +3 -11
- truss/tests/test_control_truss_patching.py +7 -12
- truss/tests/test_custom_server.py +38 -0
- truss/tests/test_data/context_builder_image_test/test.py +3 -0
- truss/tests/test_data/happy.ipynb +56 -0
- truss/tests/test_data/model_load_failure_test/config.yaml +2 -0
- truss/tests/test_data/model_load_failure_test/model/__init__.py +0 -0
- truss/tests/test_data/patch_ping_test_server/__init__.py +0 -0
- truss/{test_data → tests/test_data}/patch_ping_test_server/app.py +3 -9
- truss/{test_data → tests/test_data}/server.Dockerfile +20 -21
- truss/tests/test_data/server_conformance_test_truss/__init__.py +0 -0
- truss/tests/test_data/server_conformance_test_truss/model/__init__.py +0 -0
- truss/{test_data → tests/test_data}/server_conformance_test_truss/model/model.py +1 -3
- truss/tests/test_data/test_async_truss/__init__.py +0 -0
- truss/tests/test_data/test_async_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_basic_truss/__init__.py +0 -0
- truss/tests/test_data/test_basic_truss/config.yaml +16 -0
- truss/tests/test_data/test_basic_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_build_commands/__init__.py +0 -0
- truss/tests/test_data/test_build_commands/config.yaml +13 -0
- truss/tests/test_data/test_build_commands/model/__init__.py +0 -0
- truss/{test_data/test_streaming_async_generator_truss → tests/test_data/test_build_commands}/model/model.py +2 -3
- truss/tests/test_data/test_build_commands_failure/__init__.py +0 -0
- truss/tests/test_data/test_build_commands_failure/config.yaml +14 -0
- truss/tests/test_data/test_build_commands_failure/model/__init__.py +0 -0
- truss/tests/test_data/test_build_commands_failure/model/model.py +17 -0
- truss/tests/test_data/test_concurrency_truss/__init__.py +0 -0
- truss/tests/test_data/test_concurrency_truss/config.yaml +4 -0
- truss/tests/test_data/test_concurrency_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_custom_server_truss/__init__.py +0 -0
- truss/tests/test_data/test_custom_server_truss/config.yaml +20 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/Dockerfile +17 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/README.md +10 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/VERSION +1 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/__init__.py +0 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/app.py +19 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/build_upload_new_image.sh +6 -0
- truss/tests/test_data/test_openai/__init__.py +0 -0
- truss/{test_data/test_basic_truss → tests/test_data/test_openai}/config.yaml +1 -2
- truss/tests/test_data/test_openai/model/__init__.py +0 -0
- truss/tests/test_data/test_openai/model/model.py +15 -0
- truss/tests/test_data/test_pyantic_v1/__init__.py +0 -0
- truss/tests/test_data/test_pyantic_v1/model/__init__.py +0 -0
- truss/tests/test_data/test_pyantic_v1/model/model.py +28 -0
- truss/tests/test_data/test_pyantic_v1/requirements.txt +1 -0
- truss/tests/test_data/test_pyantic_v2/__init__.py +0 -0
- truss/tests/test_data/test_pyantic_v2/config.yaml +13 -0
- truss/tests/test_data/test_pyantic_v2/model/__init__.py +0 -0
- truss/tests/test_data/test_pyantic_v2/model/model.py +30 -0
- truss/tests/test_data/test_pyantic_v2/requirements.txt +1 -0
- truss/tests/test_data/test_requirements_file_truss/__init__.py +0 -0
- truss/tests/test_data/test_requirements_file_truss/config.yaml +13 -0
- truss/tests/test_data/test_requirements_file_truss/model/__init__.py +0 -0
- truss/{test_data → tests/test_data}/test_requirements_file_truss/model/model.py +1 -0
- truss/tests/test_data/test_streaming_async_generator_truss/__init__.py +0 -0
- truss/tests/test_data/test_streaming_async_generator_truss/config.yaml +4 -0
- truss/tests/test_data/test_streaming_async_generator_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_streaming_async_generator_truss/model/model.py +7 -0
- truss/tests/test_data/test_streaming_read_timeout/__init__.py +0 -0
- truss/tests/test_data/test_streaming_read_timeout/model/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss/config.yaml +4 -0
- truss/tests/test_data/test_streaming_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss_with_error/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss_with_error/model/__init__.py +0 -0
- truss/{test_data → tests/test_data}/test_streaming_truss_with_error/model/model.py +3 -11
- truss/tests/test_data/test_streaming_truss_with_error/packages/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss_with_error/packages/helpers_1.py +5 -0
- truss/tests/test_data/test_streaming_truss_with_error/packages/helpers_2.py +2 -0
- truss/tests/test_data/test_streaming_truss_with_tracing/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss_with_tracing/config.yaml +43 -0
- truss/tests/test_data/test_streaming_truss_with_tracing/model/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss_with_tracing/model/model.py +65 -0
- truss/tests/test_data/test_trt_llm_truss/__init__.py +0 -0
- truss/tests/test_data/test_trt_llm_truss/config.yaml +15 -0
- truss/tests/test_data/test_trt_llm_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_trt_llm_truss/model/model.py +15 -0
- truss/tests/test_data/test_truss/__init__.py +0 -0
- truss/tests/test_data/test_truss/config.yaml +4 -0
- truss/tests/test_data/test_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_truss/model/dummy +0 -0
- truss/tests/test_data/test_truss/packages/__init__.py +0 -0
- truss/tests/test_data/test_truss/packages/test_package/__init__.py +0 -0
- truss/tests/test_data/test_truss_server_caching_truss/__init__.py +0 -0
- truss/tests/test_data/test_truss_server_caching_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_truss_with_error/__init__.py +0 -0
- truss/tests/test_data/test_truss_with_error/config.yaml +4 -0
- truss/tests/test_data/test_truss_with_error/model/__init__.py +0 -0
- truss/tests/test_data/test_truss_with_error/model/model.py +8 -0
- truss/tests/test_data/test_truss_with_error/packages/__init__.py +0 -0
- truss/tests/test_data/test_truss_with_error/packages/helpers_1.py +5 -0
- truss/tests/test_data/test_truss_with_error/packages/helpers_2.py +2 -0
- truss/tests/test_docker.py +2 -1
- truss/tests/test_model_inference.py +1340 -292
- truss/tests/test_model_schema.py +33 -26
- truss/tests/test_testing_utilities_for_other_tests.py +50 -5
- truss/tests/test_truss_gatherer.py +3 -5
- truss/tests/test_truss_handle.py +62 -59
- truss/tests/test_util.py +2 -1
- truss/tests/test_validation.py +15 -13
- truss/tests/trt_llm/test_trt_llm_config.py +41 -0
- truss/tests/trt_llm/test_validation.py +91 -0
- truss/tests/util/test_config_checks.py +40 -0
- truss/tests/util/test_env_vars.py +14 -0
- truss/tests/util/test_path.py +10 -23
- truss/trt_llm/config_checks.py +43 -0
- truss/trt_llm/validation.py +42 -0
- truss/truss_handle/__init__.py +0 -0
- truss/truss_handle/build.py +122 -0
- truss/{decorators.py → truss_handle/decorators.py} +1 -1
- truss/truss_handle/patch/__init__.py +0 -0
- truss/{patch → truss_handle/patch}/calc_patch.py +146 -92
- truss/{types.py → truss_handle/patch/custom_types.py} +35 -27
- truss/{patch → truss_handle/patch}/dir_signature.py +1 -1
- truss/truss_handle/patch/hash.py +71 -0
- truss/{patch → truss_handle/patch}/local_truss_patch_applier.py +6 -4
- truss/truss_handle/patch/signature.py +22 -0
- truss/truss_handle/patch/truss_dir_patch_applier.py +87 -0
- truss/{readme_generator.py → truss_handle/readme_generator.py} +3 -2
- truss/{truss_gatherer.py → truss_handle/truss_gatherer.py} +3 -2
- truss/{truss_handle.py → truss_handle/truss_handle.py} +174 -78
- truss/util/.truss_ignore +3 -0
- truss/{docker.py → util/docker.py} +6 -2
- truss/util/download.py +6 -15
- truss/util/env_vars.py +41 -0
- truss/util/log_utils.py +52 -0
- truss/util/path.py +20 -20
- truss/util/requirements.py +11 -0
- {truss-0.10.0rc1.dist-info → truss-0.60.0.dist-info}/METADATA +18 -16
- truss-0.60.0.dist-info/RECORD +324 -0
- {truss-0.10.0rc1.dist-info → truss-0.60.0.dist-info}/WHEEL +1 -1
- truss-0.60.0.dist-info/entry_points.txt +4 -0
- truss_chains/__init__.py +71 -0
- truss_chains/definitions.py +756 -0
- truss_chains/deployment/__init__.py +0 -0
- truss_chains/deployment/code_gen.py +816 -0
- truss_chains/deployment/deployment_client.py +871 -0
- truss_chains/framework.py +1480 -0
- truss_chains/public_api.py +231 -0
- truss_chains/py.typed +0 -0
- truss_chains/pydantic_numpy.py +131 -0
- truss_chains/reference_code/reference_chainlet.py +34 -0
- truss_chains/reference_code/reference_model.py +10 -0
- truss_chains/remote_chainlet/__init__.py +0 -0
- truss_chains/remote_chainlet/model_skeleton.py +60 -0
- truss_chains/remote_chainlet/stub.py +380 -0
- truss_chains/remote_chainlet/utils.py +332 -0
- truss_chains/streaming.py +378 -0
- truss_chains/utils.py +178 -0
- CODE_OF_CONDUCT.md +0 -131
- CONTRIBUTING.md +0 -48
- README.md +0 -137
- context_builder.Dockerfile +0 -24
- truss/blob/blob_backend.py +0 -10
- truss/blob/blob_backend_registry.py +0 -23
- truss/blob/http_public_blob_backend.py +0 -23
- truss/build/__init__.py +0 -2
- truss/build/build.py +0 -143
- truss/build/configure.py +0 -63
- truss/cli/__init__.py +0 -2
- truss/cli/console.py +0 -5
- truss/cli/create.py +0 -5
- truss/config/trt_llm.py +0 -81
- truss/constants.py +0 -61
- truss/model_inference.py +0 -123
- truss/patch/types.py +0 -30
- truss/pytest.ini +0 -7
- truss/server/common/errors.py +0 -100
- truss/server/common/termination_handler_middleware.py +0 -64
- truss/server/common/truss_server.py +0 -389
- truss/server/control/patch/model_code_patch_applier.py +0 -46
- truss/server/control/patch/requirement_name_identifier.py +0 -17
- truss/server/inference_server.py +0 -29
- truss/server/model_wrapper.py +0 -434
- truss/server/shared/logging.py +0 -81
- truss/templates/trtllm/model/model.py +0 -97
- truss/templates/trtllm/packages/build_engine_utils.py +0 -34
- truss/templates/trtllm/packages/constants.py +0 -11
- truss/templates/trtllm/packages/schema.py +0 -216
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/ensemble/config.pbtxt +0 -246
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/postprocessing/1/model.py +0 -181
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/postprocessing/config.pbtxt +0 -64
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/preprocessing/1/model.py +0 -260
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/preprocessing/config.pbtxt +0 -99
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/tensorrt_llm/config.pbtxt +0 -208
- truss/templates/trtllm/packages/triton_client.py +0 -150
- truss/templates/trtllm/packages/utils.py +0 -43
- truss/test_data/context_builder_image_test/test.py +0 -4
- truss/test_data/happy.ipynb +0 -54
- truss/test_data/model_load_failure_test/config.yaml +0 -2
- truss/test_data/test_concurrency_truss/config.yaml +0 -2
- truss/test_data/test_streaming_async_generator_truss/config.yaml +0 -2
- truss/test_data/test_streaming_truss/config.yaml +0 -3
- truss/test_data/test_truss/config.yaml +0 -2
- truss/tests/server/common/test_termination_handler_middleware.py +0 -93
- truss/tests/server/control/test_model_container_patch_applier.py +0 -203
- truss/tests/server/core/server/common/test_util.py +0 -19
- truss/tests/server/test_model_wrapper.py +0 -87
- truss/util/data_structures.py +0 -16
- truss-0.10.0rc1.dist-info/RECORD +0 -216
- truss-0.10.0rc1.dist-info/entry_points.txt +0 -3
- truss/{server/shared → base}/__init__.py +0 -0
- truss/{server → templates/control}/control/helpers/context_managers.py +0 -0
- truss/{server/control → templates/control/control/helpers}/errors.py +0 -0
- truss/{server/control/patch → templates/control/control/helpers/truss_patch}/__init__.py +0 -0
- truss/{server/control/patch → templates/control/control/helpers/truss_patch}/system_packages.py +0 -0
- truss/{test_data/annotated_types_truss/model → templates/server}/__init__.py +0 -0
- truss/{server → templates/server}/common/__init__.py +0 -0
- truss/{test_data/gcs_fix/model → templates/shared}/__init__.py +0 -0
- truss/templates/{trtllm → trtllm-briton}/README.md +0 -0
- truss/{test_data/server_conformance_test_truss/model → tests/test_data}/__init__.py +0 -0
- truss/{test_data/test_basic_truss/model → tests/test_data/annotated_types_truss}/__init__.py +0 -0
- truss/{test_data → tests/test_data}/annotated_types_truss/config.yaml +0 -0
- truss/{test_data/test_requirements_file_truss → tests/test_data/annotated_types_truss}/model/__init__.py +0 -0
- truss/{test_data → tests/test_data}/annotated_types_truss/model/model.py +0 -0
- truss/{test_data → tests/test_data}/auto-mpg.data +0 -0
- truss/{test_data → tests/test_data}/context_builder_image_test/Dockerfile +0 -0
- truss/{test_data/test_truss/model → tests/test_data/context_builder_image_test}/__init__.py +0 -0
- truss/{test_data/test_truss_server_caching_truss/model → tests/test_data/gcs_fix}/__init__.py +0 -0
- truss/{test_data → tests/test_data}/gcs_fix/config.yaml +0 -0
- truss/tests/{local → test_data/gcs_fix/model}/__init__.py +0 -0
- truss/{test_data → tests/test_data}/gcs_fix/model/model.py +0 -0
- truss/{test_data/test_truss/model/dummy → tests/test_data/model_load_failure_test/__init__.py} +0 -0
- truss/{test_data → tests/test_data}/model_load_failure_test/model/model.py +0 -0
- truss/{test_data → tests/test_data}/pima-indians-diabetes.csv +0 -0
- truss/{test_data → tests/test_data}/readme_int_example.md +0 -0
- truss/{test_data → tests/test_data}/readme_no_example.md +0 -0
- truss/{test_data → tests/test_data}/readme_str_example.md +0 -0
- truss/{test_data → tests/test_data}/server_conformance_test_truss/config.yaml +0 -0
- truss/{test_data → tests/test_data}/test_async_truss/config.yaml +0 -0
- truss/{test_data → tests/test_data}/test_async_truss/model/model.py +3 -3
- /truss/{test_data → tests/test_data}/test_basic_truss/model/model.py +0 -0
- /truss/{test_data → tests/test_data}/test_concurrency_truss/model/model.py +0 -0
- /truss/{test_data/test_requirements_file_truss → tests/test_data/test_pyantic_v1}/config.yaml +0 -0
- /truss/{test_data → tests/test_data}/test_requirements_file_truss/requirements.txt +0 -0
- /truss/{test_data → tests/test_data}/test_streaming_read_timeout/config.yaml +0 -0
- /truss/{test_data → tests/test_data}/test_streaming_read_timeout/model/model.py +0 -0
- /truss/{test_data → tests/test_data}/test_streaming_truss/model/model.py +0 -0
- /truss/{test_data → tests/test_data}/test_streaming_truss_with_error/config.yaml +0 -0
- /truss/{test_data → tests/test_data}/test_truss/examples.yaml +0 -0
- /truss/{test_data → tests/test_data}/test_truss/model/model.py +0 -0
- /truss/{test_data → tests/test_data}/test_truss/packages/test_package/test.py +0 -0
- /truss/{test_data → tests/test_data}/test_truss_server_caching_truss/config.yaml +0 -0
- /truss/{test_data → tests/test_data}/test_truss_server_caching_truss/model/model.py +0 -0
- /truss/{patch → truss_handle/patch}/constants.py +0 -0
- /truss/{notebook.py → util/notebook.py} +0 -0
- {truss-0.10.0rc1.dist-info → truss-0.60.0.dist-info}/LICENSE +0 -0
truss/remote/baseten/service.py
CHANGED
|
@@ -1,12 +1,91 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import enum
|
|
2
|
+
import time
|
|
3
|
+
import urllib.parse
|
|
4
|
+
import warnings
|
|
5
|
+
from typing import Any, Dict, Iterator, NamedTuple, Optional
|
|
6
|
+
|
|
7
|
+
import requests
|
|
8
|
+
from tenacity import retry, stop_after_delay, wait_fixed
|
|
9
|
+
from truss.base.errors import RemoteNetworkError
|
|
10
|
+
from truss.remote.baseten.api import BasetenApi
|
|
3
11
|
from truss.remote.baseten.auth import AuthService
|
|
4
12
|
from truss.remote.truss_remote import TrussService
|
|
5
|
-
from truss.truss_handle import TrussHandle
|
|
13
|
+
from truss.truss_handle.truss_handle import TrussHandle
|
|
14
|
+
|
|
15
|
+
# "classes created inside an enum will not become a member" -> intended here anyway.
|
|
16
|
+
warnings.filterwarnings("ignore", category=DeprecationWarning, message=".*enum.*")
|
|
6
17
|
|
|
7
18
|
DEFAULT_STREAM_ENCODING = "utf-8"
|
|
8
19
|
|
|
9
20
|
|
|
21
|
+
def _add_model_subdomain(rest_api_url: str, model_subdomain: str) -> str:
|
|
22
|
+
"""E.g. `https://api.baseten.co` -> `https://{model_subdomain}.api.baseten.co`"""
|
|
23
|
+
parsed_url = urllib.parse.urlparse(rest_api_url)
|
|
24
|
+
new_netloc = f"{model_subdomain}.{parsed_url.netloc}"
|
|
25
|
+
model_url = parsed_url._replace(netloc=new_netloc)
|
|
26
|
+
return str(urllib.parse.urlunparse(model_url))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class URLConfig(enum.Enum):
|
|
30
|
+
class Data(NamedTuple):
|
|
31
|
+
prefix: str
|
|
32
|
+
invoke_endpoint: str
|
|
33
|
+
app_endpoint: str
|
|
34
|
+
|
|
35
|
+
MODEL = Data("model", "predict", "models")
|
|
36
|
+
CHAIN = Data("chain", "run_remote", "chains")
|
|
37
|
+
|
|
38
|
+
@staticmethod
|
|
39
|
+
def invocation_url(
|
|
40
|
+
api_url: str, # E.g. https://api.baseten.co
|
|
41
|
+
config: "URLConfig",
|
|
42
|
+
entity_id: str,
|
|
43
|
+
entity_version_id: str,
|
|
44
|
+
is_draft,
|
|
45
|
+
) -> str:
|
|
46
|
+
"""Get the URL for the predict/run_remote endpoint."""
|
|
47
|
+
# E.g. `https://api.baseten.co` -> `https://model-{model_id}.api.baseten.co`
|
|
48
|
+
url = _add_model_subdomain(api_url, f"{config.value.prefix}-{entity_id}")
|
|
49
|
+
if is_draft:
|
|
50
|
+
# "https://model-{model_id}.api.baseten.co/development".
|
|
51
|
+
url = f"{url}/development/{config.value.invoke_endpoint}"
|
|
52
|
+
else:
|
|
53
|
+
# "https://model-{model_id}.api.baseten.co/deployment/{deployment_id}".
|
|
54
|
+
url = f"{url}/deployment/{entity_version_id}/{config.value.invoke_endpoint}"
|
|
55
|
+
return url
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def status_page_url(
|
|
59
|
+
app_url: str, # E.g. https://app.baseten.co/
|
|
60
|
+
config: "URLConfig",
|
|
61
|
+
entity_id: str,
|
|
62
|
+
) -> str:
|
|
63
|
+
return f"{app_url}/{config.value.app_endpoint}/{entity_id}/overview"
|
|
64
|
+
|
|
65
|
+
@staticmethod
|
|
66
|
+
def model_logs_url(
|
|
67
|
+
app_url: str, # E.g. https://app.baseten.co/
|
|
68
|
+
model_id: str,
|
|
69
|
+
model_version_id: str,
|
|
70
|
+
) -> str:
|
|
71
|
+
return (
|
|
72
|
+
f"{app_url}/{URLConfig.MODEL.value.app_endpoint}/{model_id}/logs/"
|
|
73
|
+
f"{model_version_id}"
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
@staticmethod
|
|
77
|
+
def chainlet_logs_url(
|
|
78
|
+
app_url: str, # E.g. https://app.baseten.co/
|
|
79
|
+
chain_id: str,
|
|
80
|
+
chain_deployment_id: str,
|
|
81
|
+
chainlet_id: str,
|
|
82
|
+
) -> str:
|
|
83
|
+
return (
|
|
84
|
+
f"{app_url}/{URLConfig.CHAIN.value.app_endpoint}/{chain_id}/logs/"
|
|
85
|
+
f"{chain_deployment_id}/{chainlet_id}"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
|
|
10
89
|
class BasetenService(TrussService):
|
|
11
90
|
def __init__(
|
|
12
91
|
self,
|
|
@@ -15,12 +94,14 @@ class BasetenService(TrussService):
|
|
|
15
94
|
is_draft: bool,
|
|
16
95
|
api_key: str,
|
|
17
96
|
service_url: str,
|
|
97
|
+
api: BasetenApi,
|
|
18
98
|
truss_handle: Optional[TrussHandle] = None,
|
|
19
99
|
):
|
|
20
100
|
super().__init__(is_draft=is_draft, service_url=service_url)
|
|
21
101
|
self._model_id = model_id
|
|
22
102
|
self._model_version_id = model_version_id
|
|
23
103
|
self._auth_service = AuthService(api_key=api_key)
|
|
104
|
+
self._api = api
|
|
24
105
|
self._truss_handle = truss_handle
|
|
25
106
|
|
|
26
107
|
def is_live(self) -> bool:
|
|
@@ -41,12 +122,9 @@ class BasetenService(TrussService):
|
|
|
41
122
|
def invocation_url(self) -> str:
|
|
42
123
|
return f"{self._service_url}/predict"
|
|
43
124
|
|
|
44
|
-
def predict(
|
|
45
|
-
self,
|
|
46
|
-
model_request_body: Dict,
|
|
47
|
-
):
|
|
125
|
+
def predict(self, model_request_body: Dict) -> Any:
|
|
48
126
|
response = self._send_request(
|
|
49
|
-
self.
|
|
127
|
+
self.predict_url, "POST", data=model_request_body, stream=True
|
|
50
128
|
)
|
|
51
129
|
|
|
52
130
|
if response.headers.get("transfer-encoding") == "chunked":
|
|
@@ -73,10 +151,39 @@ class BasetenService(TrussService):
|
|
|
73
151
|
# will be a json with an `error` key.
|
|
74
152
|
return parsed_response
|
|
75
153
|
|
|
76
|
-
return response.json()
|
|
154
|
+
return response.json()
|
|
77
155
|
|
|
78
156
|
def authenticate(self) -> dict:
|
|
79
157
|
return self._auth_service.authenticate().header()
|
|
80
158
|
|
|
81
|
-
|
|
82
|
-
|
|
159
|
+
@property
|
|
160
|
+
def logs_url(self) -> str:
|
|
161
|
+
return URLConfig.model_logs_url(
|
|
162
|
+
self._api.app_url, self.model_id, self.model_version_id
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
@property
|
|
166
|
+
def predict_url(self) -> str:
|
|
167
|
+
return URLConfig.invocation_url(
|
|
168
|
+
self._api.rest_api_url,
|
|
169
|
+
URLConfig.MODEL,
|
|
170
|
+
self.model_id,
|
|
171
|
+
self._model_version_id,
|
|
172
|
+
self.is_draft,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
@retry(stop=stop_after_delay(60), wait=wait_fixed(1), reraise=True)
|
|
176
|
+
def _fetch_deployment(self) -> Any:
|
|
177
|
+
return self._api.get_deployment(self._model_id, self._model_version_id)
|
|
178
|
+
|
|
179
|
+
def poll_deployment_status(self, sleep_secs: int = 1) -> Iterator[str]:
|
|
180
|
+
"""
|
|
181
|
+
Wait for the service to be deployed.
|
|
182
|
+
"""
|
|
183
|
+
while True:
|
|
184
|
+
time.sleep(sleep_secs)
|
|
185
|
+
try:
|
|
186
|
+
deployment = self._fetch_deployment()
|
|
187
|
+
yield deployment["status"]
|
|
188
|
+
except requests.exceptions.RequestException:
|
|
189
|
+
raise RemoteNetworkError("Could not reach backend.")
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
STATUS_TO_DISPLAYABLE = {
|
|
2
|
+
"BUILDING_MODEL": "BUILDING",
|
|
3
|
+
"DEPLOYING_MODEL": "DEPLOYING",
|
|
4
|
+
"MODEL_DEPLOY_FAILED": "DEPLOY_FAILED",
|
|
5
|
+
"MODEL_LOADING": "LOADING_MODEL",
|
|
6
|
+
"MODEL_READY": "ACTIVE",
|
|
7
|
+
"MODEL_UNHEALTHY": "UNHEALTHY",
|
|
8
|
+
"BUILDING_MODEL_FAILED": "BUILD_FAILED",
|
|
9
|
+
"BUILDING_MODEL_STOPPED": "BUILD_STOPPED",
|
|
10
|
+
"DEACTIVATING_MODEL": "DEACTIVATING",
|
|
11
|
+
"DEACTIVATED_MODEL": "INACTIVE",
|
|
12
|
+
"MODEL_DNE_ERROR": "FAILED",
|
|
13
|
+
"UPDATING": "UPDATING",
|
|
14
|
+
"MIGRATING_WORKLOAD_PLANES": "UPDATING",
|
|
15
|
+
"SCALED_TO_ZERO": "SCALED_TO_ZERO",
|
|
16
|
+
"SCALING_FROM_ZERO": "WAKING_UP",
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_displayable_status(status: str) -> str:
|
|
21
|
+
"""
|
|
22
|
+
TODO: Remove this method once Chains is supported in the REST API
|
|
23
|
+
|
|
24
|
+
This is used by the `truss chains deploy` command right now to
|
|
25
|
+
print the right status. Once Chains are supported by the REST API, the
|
|
26
|
+
Baseten REST API will return status strings matching the ones here, so we don't
|
|
27
|
+
need to do any mapping.
|
|
28
|
+
"""
|
|
29
|
+
return STATUS_TO_DISPLAYABLE.get(status, "UNKNOWN")
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import contextlib
|
|
1
2
|
import tarfile
|
|
2
3
|
import tempfile
|
|
3
4
|
from pathlib import Path
|
|
4
|
-
from typing import IO, Any, Callable, List
|
|
5
|
+
from typing import IO, TYPE_CHECKING, Any, Callable, List, Optional, Type
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from rich import progress
|
|
5
9
|
|
|
6
|
-
from rich.progress import Progress
|
|
7
10
|
from truss.util.path import is_ignored
|
|
8
11
|
|
|
9
12
|
|
|
@@ -24,37 +27,46 @@ class ReadProgressIndicatorFileHandle:
|
|
|
24
27
|
|
|
25
28
|
|
|
26
29
|
def create_tar_with_progress_bar(
|
|
27
|
-
source_dir: Path,
|
|
30
|
+
source_dir: Path,
|
|
31
|
+
ignore_patterns: Optional[List[str]] = None,
|
|
32
|
+
delete=True,
|
|
33
|
+
progress_bar: Optional[Type["progress.Progress"]] = None,
|
|
28
34
|
):
|
|
29
|
-
# Exclude files that match the ignore_patterns
|
|
30
35
|
files_to_include = [
|
|
31
36
|
f
|
|
32
37
|
for f in source_dir.rglob("*")
|
|
33
|
-
if f.is_file() and not is_ignored(f, ignore_patterns, source_dir)
|
|
38
|
+
if f.is_file() and not is_ignored(f, ignore_patterns or [], source_dir)
|
|
34
39
|
]
|
|
35
40
|
|
|
36
41
|
total_size = sum(f.stat().st_size for f in files_to_include)
|
|
37
42
|
temp_file = tempfile.NamedTemporaryFile(suffix=".tgz", delete=delete)
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
progress_context = (
|
|
45
|
+
progress_bar(transient=True) if progress_bar else contextlib.nullcontext()
|
|
46
|
+
)
|
|
47
|
+
# Trailing spaces are to align with `multipart_upload_boto3` message.
|
|
48
|
+
task_id = (
|
|
49
|
+
progress_context.add_task("[cyan]Packing Truss ", total=total_size)
|
|
50
|
+
if not isinstance(progress_context, contextlib.nullcontext)
|
|
51
|
+
else None
|
|
52
|
+
)
|
|
44
53
|
|
|
45
|
-
|
|
54
|
+
def file_read_progress_callback(bytes_read: int):
|
|
55
|
+
if not isinstance(progress_context, contextlib.nullcontext):
|
|
56
|
+
assert task_id is not None
|
|
57
|
+
progress_context.update(task_id, advance=bytes_read)
|
|
46
58
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
file_obj_with_progress = ReadProgressIndicatorFileHandle(
|
|
59
|
+
with tarfile.open(temp_file.name, "w:") as tar, progress_context:
|
|
60
|
+
for file_path in files_to_include:
|
|
61
|
+
arcname = str(file_path.relative_to(source_dir))
|
|
62
|
+
with file_path.open("rb") as file_obj:
|
|
63
|
+
file_obj_with_progress = (
|
|
64
|
+
ReadProgressIndicatorFileHandle(
|
|
54
65
|
file_obj, file_read_progress_callback
|
|
55
66
|
)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
67
|
+
if progress_bar
|
|
68
|
+
else file_obj
|
|
69
|
+
)
|
|
70
|
+
tarinfo = tar.gettarinfo(name=str(file_path), arcname=arcname)
|
|
71
|
+
tar.addfile(tarinfo=tarinfo, fileobj=file_obj_with_progress) # type: ignore[arg-type] # `ReadProgressIndicatorFileHandle` implements `IO[bytes]`.
|
|
60
72
|
return temp_file
|
|
@@ -1,37 +1,50 @@
|
|
|
1
1
|
import base64
|
|
2
|
+
import contextlib
|
|
2
3
|
import json
|
|
3
4
|
import os
|
|
5
|
+
from typing import TYPE_CHECKING, Optional, Type
|
|
4
6
|
|
|
5
7
|
import boto3
|
|
6
8
|
from boto3.s3.transfer import TransferConfig
|
|
7
|
-
from
|
|
9
|
+
from truss.util.env_vars import override_env_vars
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from rich import progress
|
|
8
13
|
|
|
9
14
|
|
|
10
15
|
def base64_encoded_json_str(obj):
|
|
11
16
|
return base64.b64encode(str.encode(json.dumps(obj))).decode("utf-8")
|
|
12
17
|
|
|
13
18
|
|
|
14
|
-
def multipart_upload_boto3(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
progress
|
|
20
|
-
|
|
21
|
-
#
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
def multipart_upload_boto3(
|
|
20
|
+
file_path,
|
|
21
|
+
bucket_name: str,
|
|
22
|
+
key: str,
|
|
23
|
+
credentials: dict,
|
|
24
|
+
progress_bar: Optional[Type["progress.Progress"]],
|
|
25
|
+
) -> None:
|
|
26
|
+
# In the CLI flow, ignore any local ~/.aws/config files,
|
|
27
|
+
# which can interfere with uploading the Truss to S3.
|
|
28
|
+
with override_env_vars({"AWS_CONFIG_FILE": ""}):
|
|
29
|
+
s3_resource = boto3.resource("s3", **credentials)
|
|
30
|
+
filesize = os.stat(file_path).st_size
|
|
31
|
+
|
|
32
|
+
progress_context = (
|
|
33
|
+
progress_bar(transient=True) if progress_bar else contextlib.nullcontext()
|
|
34
|
+
)
|
|
35
|
+
task_id = (
|
|
36
|
+
progress_context.add_task("[cyan]Uploading Truss", total=filesize)
|
|
37
|
+
if not isinstance(progress_context, contextlib.nullcontext)
|
|
38
|
+
else None
|
|
39
|
+
)
|
|
25
40
|
|
|
26
41
|
def callback(bytes_transferred):
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
max_concurrency=10,
|
|
34
|
-
|
|
35
|
-
)
|
|
36
|
-
Callback=callback,
|
|
37
|
-
)
|
|
42
|
+
if progress_bar:
|
|
43
|
+
progress_context.update(task_id, advance=bytes_transferred)
|
|
44
|
+
|
|
45
|
+
with progress_context:
|
|
46
|
+
s3_resource.Object(bucket_name, key).upload_file(
|
|
47
|
+
file_path,
|
|
48
|
+
Config=TransferConfig(max_concurrency=10, use_threads=True),
|
|
49
|
+
Callback=callback,
|
|
50
|
+
)
|
truss/remote/remote_factory.py
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import inspect
|
|
2
|
-
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
try:
|
|
5
|
+
from configparser import DEFAULTSECT, ConfigParser # type: ignore
|
|
6
|
+
except ImportError:
|
|
7
|
+
# We need to do this for old python.
|
|
8
|
+
from configparser import DEFAULTSECT
|
|
9
|
+
from configparser import SafeConfigParser as ConfigParser
|
|
10
|
+
|
|
11
|
+
|
|
3
12
|
from functools import partial
|
|
4
13
|
from operator import is_not
|
|
5
14
|
from pathlib import Path
|
|
@@ -8,16 +17,16 @@ from typing import Dict, List, Type
|
|
|
8
17
|
from truss.remote.baseten import BasetenRemote
|
|
9
18
|
from truss.remote.truss_remote import RemoteConfig, TrussRemote
|
|
10
19
|
|
|
11
|
-
USER_TRUSSRC_PATH = Path("~/.trussrc").expanduser()
|
|
20
|
+
USER_TRUSSRC_PATH = Path(os.environ.get("USER_TRUSSRC_PATH", "~/.trussrc")).expanduser()
|
|
12
21
|
|
|
13
22
|
|
|
14
|
-
def load_config() ->
|
|
15
|
-
config =
|
|
23
|
+
def load_config() -> ConfigParser:
|
|
24
|
+
config = ConfigParser()
|
|
16
25
|
config.read(USER_TRUSSRC_PATH)
|
|
17
26
|
return config
|
|
18
27
|
|
|
19
28
|
|
|
20
|
-
def update_config(config:
|
|
29
|
+
def update_config(config: ConfigParser):
|
|
21
30
|
with open(USER_TRUSSRC_PATH, "w") as configfile:
|
|
22
31
|
config.write(configfile)
|
|
23
32
|
|
truss/remote/truss_remote.py
CHANGED
|
@@ -1,16 +1,31 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
2
|
from dataclasses import dataclass, field
|
|
3
|
-
from typing import Dict, Optional
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Dict, Iterator, Optional
|
|
4
4
|
|
|
5
5
|
import requests
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from rich import console as rich_console
|
|
9
|
+
from truss.truss_handle.truss_handle import TrussHandle
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class RemoteUser:
|
|
13
|
+
"""Class to hold information about the remote user"""
|
|
14
|
+
|
|
15
|
+
workspace_name: str
|
|
16
|
+
user_email: str
|
|
17
|
+
|
|
18
|
+
def __init__(self, workspace_name: str, user_email: str):
|
|
19
|
+
self.workspace_name = workspace_name
|
|
20
|
+
self.user_email = user_email
|
|
7
21
|
|
|
8
22
|
|
|
9
23
|
class TrussService(ABC):
|
|
10
24
|
"""
|
|
11
25
|
Define the abstract base class for a TrussService.
|
|
12
26
|
|
|
13
|
-
A TrussService interacts with a service at a given URL and can either be in
|
|
27
|
+
A TrussService interacts with a service at a given URL and can either be in
|
|
28
|
+
draft or non-draft mode.
|
|
14
29
|
|
|
15
30
|
Attributes:
|
|
16
31
|
_service_url: The URL of the service.
|
|
@@ -23,7 +38,7 @@ class TrussService(ABC):
|
|
|
23
38
|
|
|
24
39
|
"""
|
|
25
40
|
|
|
26
|
-
def __init__(self, service_url: str, is_draft: bool, **kwargs):
|
|
41
|
+
def __init__(self, service_url: str, is_draft: bool, **kwargs) -> None:
|
|
27
42
|
self._service_url = service_url
|
|
28
43
|
self._is_draft = is_draft
|
|
29
44
|
|
|
@@ -34,7 +49,7 @@ class TrussService(ABC):
|
|
|
34
49
|
headers: Optional[Dict] = None,
|
|
35
50
|
data: Optional[Dict] = None,
|
|
36
51
|
stream: Optional[bool] = False,
|
|
37
|
-
):
|
|
52
|
+
) -> Any:
|
|
38
53
|
"""
|
|
39
54
|
Send a HTTP request.
|
|
40
55
|
|
|
@@ -75,7 +90,7 @@ class TrussService(ABC):
|
|
|
75
90
|
return response
|
|
76
91
|
|
|
77
92
|
@property
|
|
78
|
-
def is_draft(self):
|
|
93
|
+
def is_draft(self) -> bool:
|
|
79
94
|
"""
|
|
80
95
|
Check if the service is in draft mode.
|
|
81
96
|
|
|
@@ -89,7 +104,8 @@ class TrussService(ABC):
|
|
|
89
104
|
"""
|
|
90
105
|
Check if the service is live.
|
|
91
106
|
|
|
92
|
-
Sends a GET request to the root of the service and returns whether it
|
|
107
|
+
Sends a GET request to the root of the service and returns whether it
|
|
108
|
+
is successful.
|
|
93
109
|
|
|
94
110
|
Returns:
|
|
95
111
|
A boolean indicating if the service is live.
|
|
@@ -103,7 +119,8 @@ class TrussService(ABC):
|
|
|
103
119
|
"""
|
|
104
120
|
Check if the service is ready.
|
|
105
121
|
|
|
106
|
-
Sends a GET request to the model path of the service and returns whether it
|
|
122
|
+
Sends a GET request to the model path of the service and returns whether it
|
|
123
|
+
is successful.
|
|
107
124
|
|
|
108
125
|
Returns:
|
|
109
126
|
A boolean indicating if the service is ready.
|
|
@@ -112,21 +129,20 @@ class TrussService(ABC):
|
|
|
112
129
|
response = self._send_request(readiness_url, "GET", {})
|
|
113
130
|
return response.status_code == 200
|
|
114
131
|
|
|
115
|
-
def predict(self, model_request_body: Dict):
|
|
132
|
+
def predict(self, model_request_body: Dict) -> Any:
|
|
116
133
|
"""
|
|
117
134
|
Send a prediction request to the service.
|
|
118
135
|
|
|
119
136
|
Args:
|
|
120
|
-
model_request_body: A dictionary representing the body of the
|
|
137
|
+
model_request_body: A dictionary representing the body of the
|
|
138
|
+
prediction request.
|
|
121
139
|
|
|
122
140
|
Returns:
|
|
123
141
|
A Response object resulting from the prediction request.
|
|
124
142
|
"""
|
|
125
|
-
|
|
126
|
-
response = self._send_request(invocation_url, "POST", data=model_request_body)
|
|
127
|
-
return response
|
|
143
|
+
return self._send_request(self.predict_url, "POST", data=model_request_body)
|
|
128
144
|
|
|
129
|
-
def patch(self):
|
|
145
|
+
def patch(self) -> None:
|
|
130
146
|
"""
|
|
131
147
|
Patch the service. TrussServices in draft mode can be patched.
|
|
132
148
|
"""
|
|
@@ -137,25 +153,42 @@ class TrussService(ABC):
|
|
|
137
153
|
"""
|
|
138
154
|
Authenticate to the service.
|
|
139
155
|
|
|
140
|
-
This method should be implemented in subclasses and return a dictionary
|
|
141
|
-
to include in requests to the service with authentication
|
|
156
|
+
This method should be implemented in subclasses and return a dictionary
|
|
157
|
+
of headers to include in requests to the service with authentication
|
|
158
|
+
information.
|
|
142
159
|
"""
|
|
143
160
|
return {}
|
|
144
161
|
|
|
162
|
+
@property
|
|
145
163
|
@abstractmethod
|
|
146
|
-
def logs_url(self
|
|
164
|
+
def logs_url(self) -> str:
|
|
147
165
|
"""
|
|
148
166
|
Get the URL for the service logs.
|
|
149
167
|
"""
|
|
150
168
|
pass
|
|
151
169
|
|
|
170
|
+
@property
|
|
171
|
+
@abstractmethod
|
|
172
|
+
def predict_url(self) -> str:
|
|
173
|
+
"""
|
|
174
|
+
Get the URL for the prediction endpoint.
|
|
175
|
+
"""
|
|
176
|
+
pass
|
|
177
|
+
|
|
178
|
+
@abstractmethod
|
|
179
|
+
def poll_deployment_status(self, sleep_secs: int = 1) -> Iterator[str]:
|
|
180
|
+
"""
|
|
181
|
+
Poll for a deployment status.
|
|
182
|
+
"""
|
|
183
|
+
pass
|
|
184
|
+
|
|
152
185
|
|
|
153
186
|
class TrussRemote(ABC):
|
|
154
187
|
"""
|
|
155
188
|
Define the abstract base class for a remote Truss service.
|
|
156
189
|
|
|
157
|
-
A remote Truss service is a service that can push a TrussHandle to a remote
|
|
158
|
-
The `push` and `authenticate` methods should be implemented in subclasses.
|
|
190
|
+
A remote Truss service is a service that can push a TrussHandle to a remote
|
|
191
|
+
location. The `push` and `authenticate` methods should be implemented in subclasses.
|
|
159
192
|
|
|
160
193
|
Attributes:
|
|
161
194
|
_remote_url: The URL of the remote service.
|
|
@@ -166,11 +199,15 @@ class TrussRemote(ABC):
|
|
|
166
199
|
|
|
167
200
|
"""
|
|
168
201
|
|
|
169
|
-
def __init__(self, remote_url: str
|
|
202
|
+
def __init__(self, remote_url: str) -> None:
|
|
170
203
|
self._remote_url = remote_url
|
|
171
204
|
|
|
205
|
+
@property
|
|
206
|
+
def remote_url(self) -> str:
|
|
207
|
+
return self._remote_url
|
|
208
|
+
|
|
172
209
|
@abstractmethod
|
|
173
|
-
def push(self, truss_handle: TrussHandle, **kwargs):
|
|
210
|
+
def push(self, truss_handle: TrussHandle, **kwargs) -> TrussService:
|
|
174
211
|
"""
|
|
175
212
|
Push a TrussHandle to the remote service.
|
|
176
213
|
|
|
@@ -182,24 +219,19 @@ class TrussRemote(ABC):
|
|
|
182
219
|
**kwargs: Additional keyword arguments for the push operation.
|
|
183
220
|
|
|
184
221
|
"""
|
|
185
|
-
pass
|
|
186
222
|
|
|
187
223
|
@abstractmethod
|
|
188
|
-
def
|
|
224
|
+
def whoami(self) -> RemoteUser:
|
|
189
225
|
"""
|
|
190
|
-
|
|
226
|
+
Returns account information for the current user.
|
|
227
|
+
|
|
228
|
+
This method should be implemented in subclasses and return a RemoteUser.
|
|
191
229
|
|
|
192
|
-
This method should be implemented in subclasses. It should check whether
|
|
193
|
-
the user has valid authentication credentials to push to the remote service.
|
|
194
|
-
If not, it should raise an exception.
|
|
195
230
|
|
|
196
|
-
Args:
|
|
197
|
-
**kwargs: Additional keyword arguments for the authentication operation.
|
|
198
231
|
"""
|
|
199
|
-
pass
|
|
200
232
|
|
|
201
233
|
@abstractmethod
|
|
202
|
-
def get_service(self, **kwargs):
|
|
234
|
+
def get_service(self, **kwargs) -> TrussService:
|
|
203
235
|
"""
|
|
204
236
|
Get a TrussService object for interacting with the remote service.
|
|
205
237
|
|
|
@@ -211,20 +243,15 @@ class TrussRemote(ABC):
|
|
|
211
243
|
**kwargs: Keyword arguments for the get_service operation.
|
|
212
244
|
|
|
213
245
|
"""
|
|
214
|
-
pass
|
|
215
246
|
|
|
216
247
|
@abstractmethod
|
|
217
|
-
def
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
pass
|
|
225
|
-
|
|
226
|
-
@abstractmethod
|
|
227
|
-
def sync_truss_to_dev_version_by_name(self, model_name: str, target_directory: str):
|
|
248
|
+
def sync_truss_to_dev_version_by_name(
|
|
249
|
+
self,
|
|
250
|
+
model_name: str,
|
|
251
|
+
target_directory: str,
|
|
252
|
+
console: "rich_console.Console",
|
|
253
|
+
error_console: "rich_console.Console",
|
|
254
|
+
) -> None:
|
|
228
255
|
"""
|
|
229
256
|
This method watches for changes to files in the `target_directory`,
|
|
230
257
|
and syncs them to the development version of the model, identified
|
|
@@ -233,10 +260,10 @@ class TrussRemote(ABC):
|
|
|
233
260
|
Args:
|
|
234
261
|
model_name: The name of the model to sync to the dev version
|
|
235
262
|
target_directory: The directory to sync the model to
|
|
263
|
+
console: For printing informative output.
|
|
264
|
+
error_console: For printing errors.
|
|
236
265
|
"""
|
|
237
266
|
|
|
238
|
-
pass
|
|
239
|
-
|
|
240
267
|
|
|
241
268
|
@dataclass
|
|
242
269
|
class RemoteConfig:
|