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
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
ARG PYVERSION={{config.python_version}}
|
|
2
|
-
FROM {{base_image_name_and_tag}}
|
|
2
|
+
FROM {{base_image_name_and_tag}} AS truss_server
|
|
3
3
|
|
|
4
|
-
ENV PYTHON_EXECUTABLE
|
|
5
|
-
ENV JSON_LOG True
|
|
4
|
+
ENV PYTHON_EXECUTABLE="{{ config.base_image.python_executable_path or 'python3' }}"
|
|
6
5
|
|
|
7
6
|
{% block fail_fast %}
|
|
8
7
|
RUN grep -w 'ID=debian\|ID_LIKE=debian' /etc/os-release || { echo "ERROR: Supplied base image is not a debian image"; exit 1; }
|
|
9
|
-
RUN $PYTHON_EXECUTABLE -c "import sys; sys.exit(0) if sys.version_info.major ==
|
|
10
|
-
|| { echo "ERROR: Supplied base image does not have
|
|
8
|
+
RUN $PYTHON_EXECUTABLE -c "import sys; sys.exit(0) if sys.version_info.major == {{supported_python_major_version_in_custom_base_image}} and sys.version_info.minor >={{min_supported_python_minor_version_in_custom_base_image}} and sys.version_info.minor <={{max_supported_python_minor_version_in_custom_base_image}} else sys.exit(1)" \
|
|
9
|
+
|| { echo "ERROR: Supplied base image does not have {{min_supported_python_version_in_custom_base_image}} <= python <= {{max_supported_python_version_in_custom_base_image}}"; exit 1; }
|
|
11
10
|
{% endblock %}
|
|
12
11
|
|
|
13
12
|
RUN pip install --upgrade pip --no-cache-dir \
|
|
14
13
|
&& rm -rf /root/.cache/pip
|
|
15
14
|
|
|
16
|
-
# Always install the truss package
|
|
17
|
-
COPY ./truss/ /lib/truss_pkg/truss
|
|
18
|
-
COPY ./pyproject.toml /lib/truss_pkg/
|
|
19
|
-
COPY ./README.md /lib/truss_pkg/
|
|
20
|
-
RUN pip install /lib/truss_pkg --no-cache-dir && rm -rf /root/.cache/pip
|
|
21
|
-
|
|
22
15
|
{% block base_image_patch %}
|
|
23
16
|
{% endblock %}
|
|
24
17
|
|
|
18
|
+
{% if config.model_framework.value == 'huggingface_transformer' %}
|
|
19
|
+
{% if config.resources.use_gpu %}
|
|
20
|
+
# HuggingFace pytorch gpu support needs mkl
|
|
21
|
+
RUN pip install mkl
|
|
22
|
+
{% endif %}
|
|
23
|
+
{% endif%}
|
|
24
|
+
|
|
25
25
|
{% block post_base %}
|
|
26
26
|
{% endblock %}
|
|
27
27
|
|
|
@@ -39,20 +39,22 @@ RUN apt-get update && apt-get install --yes --no-install-recommends $(cat {{syst
|
|
|
39
39
|
{% block install_requirements %}
|
|
40
40
|
{%- if should_install_user_requirements_file %}
|
|
41
41
|
COPY ./{{user_supplied_requirements_filename}} {{user_supplied_requirements_filename}}
|
|
42
|
+
RUN cat {{user_supplied_requirements_filename}}
|
|
42
43
|
RUN pip install -r {{user_supplied_requirements_filename}} --no-cache-dir && rm -rf /root/.cache/pip
|
|
43
44
|
{%- endif %}
|
|
44
45
|
{%- if should_install_requirements %}
|
|
45
46
|
COPY ./{{config_requirements_filename}} {{config_requirements_filename}}
|
|
47
|
+
RUN cat {{config_requirements_filename}}
|
|
46
48
|
RUN pip install -r {{config_requirements_filename}} --no-cache-dir && rm -rf /root/.cache/pip
|
|
47
49
|
{%- endif %}
|
|
48
50
|
{% endblock %}
|
|
49
51
|
|
|
50
52
|
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
ENV APP_HOME
|
|
54
|
+
{%- if not config.docker_server %}
|
|
55
|
+
ENV APP_HOME="/app"
|
|
54
56
|
WORKDIR $APP_HOME
|
|
55
|
-
|
|
57
|
+
{%- endif %}
|
|
56
58
|
|
|
57
59
|
{% block app_copy %}
|
|
58
60
|
{% endblock %}
|
|
@@ -60,13 +62,13 @@ WORKDIR $APP_HOME
|
|
|
60
62
|
|
|
61
63
|
{% block bundled_packages_copy %}
|
|
62
64
|
{%- if bundled_packages_dir_exists %}
|
|
63
|
-
COPY ./{{config.bundled_packages_dir}} /
|
|
65
|
+
COPY ./{{config.bundled_packages_dir}} /packages
|
|
64
66
|
{%- endif %}
|
|
65
67
|
{% endblock %}
|
|
66
68
|
|
|
67
69
|
|
|
68
70
|
{% for env_var_name, env_var_value in config.environment_variables.items() %}
|
|
69
|
-
ENV {{ env_var_name }}
|
|
71
|
+
ENV {{ env_var_name }}="{{ env_var_value }}"
|
|
70
72
|
{% endfor %}
|
|
71
73
|
|
|
72
74
|
{% block run %}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
FROM python:3.11-slim
|
|
1
|
+
FROM python:3.11-slim AS cache_warmer
|
|
2
2
|
|
|
3
3
|
RUN mkdir -p /app/model_cache
|
|
4
4
|
WORKDIR /app
|
|
5
5
|
|
|
6
6
|
{% if hf_access_token %}
|
|
7
|
-
ENV HUGGING_FACE_HUB_TOKEN
|
|
7
|
+
ENV HUGGING_FACE_HUB_TOKEN="{{hf_access_token}}"
|
|
8
8
|
{% endif %}
|
|
9
9
|
|
|
10
10
|
RUN apt-get -y update; apt-get -y install curl; curl -s https://baseten-public.s3.us-west-2.amazonaws.com/bin/b10cp-5fe8dc7da-linux-amd64 -o /app/b10cp; chmod +x /app/b10cp
|
|
11
|
-
ENV B10CP_PATH_TRUSS
|
|
11
|
+
ENV B10CP_PATH_TRUSS="/app/b10cp"
|
|
12
12
|
COPY ./cache_requirements.txt /app/cache_requirements.txt
|
|
13
13
|
RUN pip install -r /app/cache_requirements.txt --no-cache-dir && rm -rf /root/.cache/pip
|
|
14
14
|
COPY ./cache_warmer.py /cache_warmer.py
|
|
@@ -1,50 +1,31 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import logging
|
|
3
|
+
import logging.config
|
|
3
4
|
import re
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
from typing import Dict
|
|
6
7
|
|
|
7
8
|
import httpx
|
|
9
|
+
from endpoints import control_app
|
|
8
10
|
from fastapi import FastAPI
|
|
9
11
|
from fastapi.responses import JSONResponse
|
|
12
|
+
from helpers.errors import ModelLoadFailed, PatchApplicatonError
|
|
13
|
+
from helpers.inference_server_controller import InferenceServerController
|
|
14
|
+
from helpers.inference_server_process_controller import InferenceServerProcessController
|
|
15
|
+
from helpers.inference_server_starter import async_inference_server_startup_flow
|
|
16
|
+
from helpers.truss_patch.model_container_patch_applier import ModelContainerPatchApplier
|
|
17
|
+
from shared import log_config
|
|
10
18
|
from starlette.datastructures import State
|
|
11
|
-
from truss.server.control.endpoints import control_app
|
|
12
|
-
from truss.server.control.errors import ModelLoadFailed, PatchApplicatonError
|
|
13
|
-
from truss.server.control.helpers.inference_server_controller import (
|
|
14
|
-
InferenceServerController,
|
|
15
|
-
)
|
|
16
|
-
from truss.server.control.helpers.inference_server_process_controller import (
|
|
17
|
-
InferenceServerProcessController,
|
|
18
|
-
)
|
|
19
|
-
from truss.server.control.helpers.inference_server_starter import (
|
|
20
|
-
async_inference_server_startup_flow,
|
|
21
|
-
)
|
|
22
|
-
from truss.server.control.patch.model_container_patch_applier import (
|
|
23
|
-
ModelContainerPatchApplier,
|
|
24
|
-
)
|
|
25
|
-
from truss.server.shared.logging import setup_logging
|
|
26
19
|
|
|
27
20
|
|
|
28
21
|
async def handle_patch_error(_, exc):
|
|
29
22
|
error_type = _camel_to_snake_case(type(exc).__name__)
|
|
30
|
-
return JSONResponse(
|
|
31
|
-
content={
|
|
32
|
-
"error": {
|
|
33
|
-
"type": error_type,
|
|
34
|
-
"msg": str(exc),
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
)
|
|
23
|
+
return JSONResponse(content={"error": {"type": error_type, "msg": str(exc)}})
|
|
38
24
|
|
|
39
25
|
|
|
40
26
|
async def generic_error_handler(_, exc):
|
|
41
27
|
return JSONResponse(
|
|
42
|
-
content={
|
|
43
|
-
"error": {
|
|
44
|
-
"type": "unknown",
|
|
45
|
-
"msg": f"{type(exc)}: {exc}",
|
|
46
|
-
}
|
|
47
|
-
}
|
|
28
|
+
content={"error": {"type": "unknown", "msg": f"{type(exc)}: {exc}"}}
|
|
48
29
|
)
|
|
49
30
|
|
|
50
31
|
|
|
@@ -55,10 +36,11 @@ async def handle_model_load_failed(_, error):
|
|
|
55
36
|
|
|
56
37
|
def create_app(base_config: Dict):
|
|
57
38
|
app_state = State()
|
|
58
|
-
setup_logging()
|
|
59
39
|
app_logger = logging.getLogger(__name__)
|
|
60
40
|
app_state.logger = app_logger
|
|
61
41
|
|
|
42
|
+
logging.config.dictConfig(log_config.make_log_config("INFO"))
|
|
43
|
+
|
|
62
44
|
for k, v in base_config.items():
|
|
63
45
|
setattr(app_state, k, v)
|
|
64
46
|
|
|
@@ -77,9 +59,7 @@ def create_app(base_config: Dict):
|
|
|
77
59
|
pip_path = getattr(app_state, "pip_path", None)
|
|
78
60
|
|
|
79
61
|
patch_applier = ModelContainerPatchApplier(
|
|
80
|
-
Path(app_state.inference_server_home),
|
|
81
|
-
app_logger,
|
|
82
|
-
pip_path,
|
|
62
|
+
Path(app_state.inference_server_home), app_logger, pip_path
|
|
83
63
|
)
|
|
84
64
|
|
|
85
65
|
oversee_inference_server = getattr(app_state, "oversee_inference_server", True)
|
|
@@ -94,8 +74,7 @@ def create_app(base_config: Dict):
|
|
|
94
74
|
async def start_background_inference_startup():
|
|
95
75
|
asyncio.create_task(
|
|
96
76
|
async_inference_server_startup_flow(
|
|
97
|
-
app_state.inference_server_controller,
|
|
98
|
-
app_logger,
|
|
77
|
+
app_state.inference_server_controller, app_logger
|
|
99
78
|
)
|
|
100
79
|
)
|
|
101
80
|
|
|
@@ -4,15 +4,14 @@ from typing import Any, Dict
|
|
|
4
4
|
import httpx
|
|
5
5
|
from fastapi import APIRouter
|
|
6
6
|
from fastapi.responses import JSONResponse, StreamingResponse
|
|
7
|
+
from helpers.errors import ModelLoadFailed, ModelNotReady
|
|
7
8
|
from httpx import URL, ConnectError, RemoteProtocolError
|
|
8
9
|
from starlette.requests import ClientDisconnect, Request
|
|
9
10
|
from starlette.responses import Response
|
|
10
|
-
from tenacity import Retrying, retry_if_exception_type,
|
|
11
|
-
from truss.server.control.errors import ModelLoadFailed, ModelNotReady
|
|
11
|
+
from tenacity import RetryCallState, Retrying, retry_if_exception_type, wait_fixed
|
|
12
12
|
|
|
13
13
|
INFERENCE_SERVER_START_WAIT_SECS = 60
|
|
14
14
|
|
|
15
|
-
|
|
16
15
|
control_app = APIRouter()
|
|
17
16
|
|
|
18
17
|
|
|
@@ -26,7 +25,9 @@ async def proxy(request: Request):
|
|
|
26
25
|
request.app.state.inference_server_process_controller
|
|
27
26
|
)
|
|
28
27
|
client: httpx.AsyncClient = request.app.state.proxy_client
|
|
29
|
-
|
|
28
|
+
|
|
29
|
+
path = _reroute_if_health_check(request.url.path)
|
|
30
|
+
url = URL(path=path, query=request.url.query.encode("utf-8"))
|
|
30
31
|
|
|
31
32
|
# 2 min connect timeouts, no timeout for requests.
|
|
32
33
|
# We don't want requests to fail due to timeout on the proxy
|
|
@@ -51,15 +52,16 @@ async def proxy(request: Request):
|
|
|
51
52
|
retry_if_exception_type(ConnectError)
|
|
52
53
|
| retry_if_exception_type(ModelNotReady)
|
|
53
54
|
| retry_if_exception_type(RemoteProtocolError)
|
|
55
|
+
| retry_if_exception_type(httpx.ReadError)
|
|
56
|
+
| retry_if_exception_type(httpx.ReadTimeout)
|
|
57
|
+
| retry_if_exception_type(httpx.ConnectTimeout)
|
|
54
58
|
),
|
|
55
|
-
stop=
|
|
59
|
+
stop=_custom_stop_strategy,
|
|
56
60
|
wait=wait_fixed(1),
|
|
57
61
|
):
|
|
58
62
|
with attempt:
|
|
59
63
|
try:
|
|
60
|
-
if (
|
|
61
|
-
inference_server_process_controller.is_inference_server_intentionally_stopped()
|
|
62
|
-
):
|
|
64
|
+
if inference_server_process_controller.is_inference_server_intentionally_stopped():
|
|
63
65
|
raise ModelLoadFailed("Model load failed")
|
|
64
66
|
resp = await client.send(inf_serv_req, stream=True)
|
|
65
67
|
|
|
@@ -74,8 +76,10 @@ async def proxy(request: Request):
|
|
|
74
76
|
inference_server_process_controller.inference_server_ever_started()
|
|
75
77
|
and not inference_server_process_controller.is_inference_server_running()
|
|
76
78
|
):
|
|
77
|
-
error_msg =
|
|
79
|
+
error_msg = (
|
|
80
|
+
"It appears your model has stopped running. This often means' \
|
|
78
81
|
' it crashed and may need a fix to get it running again."
|
|
82
|
+
)
|
|
79
83
|
return JSONResponse(error_msg, 503)
|
|
80
84
|
raise exp
|
|
81
85
|
|
|
@@ -148,3 +152,29 @@ def _is_streaming_response(resp) -> bool:
|
|
|
148
152
|
if header_name.lower() == "transfer-encoding" and value.lower() == "chunked":
|
|
149
153
|
return True
|
|
150
154
|
return False
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _reroute_if_health_check(path: str) -> str:
|
|
158
|
+
"""
|
|
159
|
+
Reroutes calls from the Operator to the inference server's health check endpoint (/v1/models/model) to /v1/models/model/loaded instead.
|
|
160
|
+
This is done to avoid running custom health checks when the Operator is checking if the inference server is ready.
|
|
161
|
+
"""
|
|
162
|
+
if path == "/v1/models/model":
|
|
163
|
+
path = "/v1/models/model/loaded"
|
|
164
|
+
return path
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _custom_stop_strategy(retry_state: RetryCallState) -> bool:
|
|
168
|
+
# Stop after 10 attempts for ModelNotReady
|
|
169
|
+
if retry_state.outcome is not None and isinstance(
|
|
170
|
+
retry_state.outcome.exception(), ModelNotReady
|
|
171
|
+
):
|
|
172
|
+
# Check if the retry limit for ModelNotReady has been reached
|
|
173
|
+
return retry_state.attempt_number >= 10
|
|
174
|
+
# For all other exceptions, stop after INFERENCE_SERVER_START_WAIT_SECS
|
|
175
|
+
seconds_since_start = (
|
|
176
|
+
retry_state.seconds_since_start
|
|
177
|
+
if retry_state.seconds_since_start is not None
|
|
178
|
+
else 0.0
|
|
179
|
+
)
|
|
180
|
+
return seconds_since_start >= INFERENCE_SERVER_START_WAIT_SECS
|
|
@@ -42,11 +42,7 @@ class ModelCodePatch(PatchBody):
|
|
|
42
42
|
content: Optional[str] = None
|
|
43
43
|
|
|
44
44
|
def to_dict(self):
|
|
45
|
-
return {
|
|
46
|
-
"action": self.action.value,
|
|
47
|
-
"path": self.path,
|
|
48
|
-
"content": self.content,
|
|
49
|
-
}
|
|
45
|
+
return {"action": self.action.value, "path": self.path, "content": self.content}
|
|
50
46
|
|
|
51
47
|
@staticmethod
|
|
52
48
|
def from_dict(patch_dict: Dict):
|
|
@@ -65,17 +61,13 @@ class PythonRequirementPatch(PatchBody):
|
|
|
65
61
|
requirement: str
|
|
66
62
|
|
|
67
63
|
def to_dict(self):
|
|
68
|
-
return {
|
|
69
|
-
"action": self.action.value,
|
|
70
|
-
"requirement": self.requirement,
|
|
71
|
-
}
|
|
64
|
+
return {"action": self.action.value, "requirement": self.requirement}
|
|
72
65
|
|
|
73
66
|
@staticmethod
|
|
74
67
|
def from_dict(patch_dict: Dict):
|
|
75
68
|
action_str = patch_dict["action"]
|
|
76
69
|
return PythonRequirementPatch(
|
|
77
|
-
action=Action[action_str],
|
|
78
|
-
requirement=patch_dict["requirement"],
|
|
70
|
+
action=Action[action_str], requirement=patch_dict["requirement"]
|
|
79
71
|
)
|
|
80
72
|
|
|
81
73
|
|
|
@@ -86,17 +78,13 @@ class SystemPackagePatch(PatchBody):
|
|
|
86
78
|
package: str
|
|
87
79
|
|
|
88
80
|
def to_dict(self):
|
|
89
|
-
return {
|
|
90
|
-
"action": self.action.value,
|
|
91
|
-
"package": self.package,
|
|
92
|
-
}
|
|
81
|
+
return {"action": self.action.value, "package": self.package}
|
|
93
82
|
|
|
94
83
|
@staticmethod
|
|
95
84
|
def from_dict(patch_dict: Dict):
|
|
96
85
|
action_str = patch_dict["action"]
|
|
97
86
|
return SystemPackagePatch(
|
|
98
|
-
action=Action[action_str],
|
|
99
|
-
package=patch_dict["package"],
|
|
87
|
+
action=Action[action_str], package=patch_dict["package"]
|
|
100
88
|
)
|
|
101
89
|
|
|
102
90
|
|
|
@@ -106,11 +94,7 @@ class ConfigPatch(PatchBody):
|
|
|
106
94
|
path: str = "config.yaml"
|
|
107
95
|
|
|
108
96
|
def to_dict(self):
|
|
109
|
-
return {
|
|
110
|
-
"action": self.action.value,
|
|
111
|
-
"config": self.config,
|
|
112
|
-
"path": self.path,
|
|
113
|
-
}
|
|
97
|
+
return {"action": self.action.value, "config": self.config, "path": self.path}
|
|
114
98
|
|
|
115
99
|
@staticmethod
|
|
116
100
|
def from_dict(patch_dict: Dict):
|
|
@@ -128,11 +112,7 @@ class DataPatch(PatchBody):
|
|
|
128
112
|
content: Optional[str] = None
|
|
129
113
|
|
|
130
114
|
def to_dict(self):
|
|
131
|
-
return {
|
|
132
|
-
"action": self.action.value,
|
|
133
|
-
"content": self.content,
|
|
134
|
-
"path": self.path,
|
|
135
|
-
}
|
|
115
|
+
return {"action": self.action.value, "content": self.content, "path": self.path}
|
|
136
116
|
|
|
137
117
|
@staticmethod
|
|
138
118
|
def from_dict(patch_dict: Dict):
|
|
@@ -150,11 +130,7 @@ class PackagePatch(PatchBody):
|
|
|
150
130
|
content: Optional[str] = None
|
|
151
131
|
|
|
152
132
|
def to_dict(self):
|
|
153
|
-
return {
|
|
154
|
-
"action": self.action.value,
|
|
155
|
-
"content": self.content,
|
|
156
|
-
"path": self.path,
|
|
157
|
-
}
|
|
133
|
+
return {"action": self.action.value, "content": self.content, "path": self.path}
|
|
158
134
|
|
|
159
135
|
@staticmethod
|
|
160
136
|
def from_dict(patch_dict: Dict):
|
|
@@ -171,18 +147,12 @@ class EnvVarPatch(PatchBody):
|
|
|
171
147
|
item: dict
|
|
172
148
|
|
|
173
149
|
def to_dict(self):
|
|
174
|
-
return {
|
|
175
|
-
"action": self.action.value,
|
|
176
|
-
"item": self.item,
|
|
177
|
-
}
|
|
150
|
+
return {"action": self.action.value, "item": self.item}
|
|
178
151
|
|
|
179
152
|
@staticmethod
|
|
180
153
|
def from_dict(patch_dict: Dict):
|
|
181
154
|
action_str = patch_dict["action"]
|
|
182
|
-
return EnvVarPatch(
|
|
183
|
-
action=Action[action_str],
|
|
184
|
-
item=patch_dict["item"],
|
|
185
|
-
)
|
|
155
|
+
return EnvVarPatch(action=Action[action_str], item=patch_dict["item"])
|
|
186
156
|
|
|
187
157
|
|
|
188
158
|
@dataclass
|
|
@@ -190,18 +160,12 @@ class ExternalDataPatch(PatchBody):
|
|
|
190
160
|
item: Dict[str, str]
|
|
191
161
|
|
|
192
162
|
def to_dict(self):
|
|
193
|
-
return {
|
|
194
|
-
"action": self.action.value,
|
|
195
|
-
"item": self.item,
|
|
196
|
-
}
|
|
163
|
+
return {"action": self.action.value, "item": self.item}
|
|
197
164
|
|
|
198
165
|
@staticmethod
|
|
199
166
|
def from_dict(patch_dict: Dict):
|
|
200
167
|
action_str = patch_dict["action"]
|
|
201
|
-
return ExternalDataPatch(
|
|
202
|
-
action=Action[action_str],
|
|
203
|
-
item=patch_dict["item"],
|
|
204
|
-
)
|
|
168
|
+
return ExternalDataPatch(action=Action[action_str], item=patch_dict["item"])
|
|
205
169
|
|
|
206
170
|
|
|
207
171
|
PATCH_BODY_BY_TYPE: Dict[
|
|
@@ -238,10 +202,7 @@ class Patch:
|
|
|
238
202
|
body: PatchBody
|
|
239
203
|
|
|
240
204
|
def to_dict(self):
|
|
241
|
-
return {
|
|
242
|
-
"type": self.type.value,
|
|
243
|
-
"body": self.body.to_dict(),
|
|
244
|
-
}
|
|
205
|
+
return {"type": self.type.value, "body": self.body.to_dict()}
|
|
245
206
|
|
|
246
207
|
@staticmethod
|
|
247
208
|
def from_dict(patch_dict: Dict):
|
|
@@ -4,19 +4,15 @@ import threading
|
|
|
4
4
|
import time
|
|
5
5
|
from typing import Optional
|
|
6
6
|
|
|
7
|
-
from
|
|
7
|
+
from helpers.custom_types import Patch, PatchType
|
|
8
|
+
from helpers.errors import (
|
|
8
9
|
InadmissiblePatch,
|
|
9
10
|
PatchFailedRecoverable,
|
|
10
11
|
PatchFailedUnrecoverable,
|
|
11
12
|
UnsupportedPatch,
|
|
12
13
|
)
|
|
13
|
-
from
|
|
14
|
-
|
|
15
|
-
)
|
|
16
|
-
from truss.server.control.patch.model_container_patch_applier import (
|
|
17
|
-
ModelContainerPatchApplier,
|
|
18
|
-
)
|
|
19
|
-
from truss.server.control.patch.types import Patch, PatchType
|
|
14
|
+
from helpers.inference_server_process_controller import InferenceServerProcessController
|
|
15
|
+
from helpers.truss_patch.model_container_patch_applier import ModelContainerPatchApplier
|
|
20
16
|
|
|
21
17
|
INFERENCE_SERVER_CHECK_INTERVAL_SECS = 10
|
|
22
18
|
|
|
@@ -4,7 +4,7 @@ import time
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from typing import List, Optional
|
|
6
6
|
|
|
7
|
-
from
|
|
7
|
+
from helpers.context_managers import current_directory
|
|
8
8
|
|
|
9
9
|
INFERENCE_SERVER_FAILED_FILE = Path("~/inference_server_crashed.txt").expanduser()
|
|
10
10
|
TERMINATION_TIMEOUT_SECS = 120.0
|
|
@@ -39,8 +39,7 @@ class InferenceServerProcessController:
|
|
|
39
39
|
with current_directory(self._inference_server_home):
|
|
40
40
|
inf_env["INFERENCE_SERVER_PORT"] = str(self._inference_server_port)
|
|
41
41
|
self._inference_server_process = subprocess.Popen(
|
|
42
|
-
self._inference_server_process_args,
|
|
43
|
-
env=inf_env,
|
|
42
|
+
self._inference_server_process_args, env=inf_env
|
|
44
43
|
)
|
|
45
44
|
|
|
46
45
|
self._inference_server_started = True
|
|
@@ -49,7 +48,6 @@ class InferenceServerProcessController:
|
|
|
49
48
|
|
|
50
49
|
def stop(self):
|
|
51
50
|
if self._inference_server_process is not None:
|
|
52
|
-
|
|
53
51
|
self._inference_server_process.terminate()
|
|
54
52
|
self._inference_server_process.wait()
|
|
55
53
|
# Introduce delay to avoid failing to grab the port
|
|
@@ -3,15 +3,12 @@ from logging import Logger
|
|
|
3
3
|
|
|
4
4
|
import requests
|
|
5
5
|
from anyio import to_thread
|
|
6
|
+
from helpers.inference_server_controller import InferenceServerController
|
|
6
7
|
from tenacity import Retrying, stop_after_attempt, wait_exponential
|
|
7
|
-
from truss.server.control.helpers.inference_server_controller import (
|
|
8
|
-
InferenceServerController,
|
|
9
|
-
)
|
|
10
8
|
|
|
11
9
|
|
|
12
10
|
def inference_server_startup_flow(
|
|
13
|
-
inference_server_controller: InferenceServerController,
|
|
14
|
-
logger: Logger,
|
|
11
|
+
inference_server_controller: InferenceServerController, logger: Logger
|
|
15
12
|
) -> None:
|
|
16
13
|
"""
|
|
17
14
|
Perform the inference server startup flow
|
|
@@ -41,8 +38,7 @@ def inference_server_startup_flow(
|
|
|
41
38
|
payload = {"truss_hash": truss_hash}
|
|
42
39
|
|
|
43
40
|
for attempt in Retrying(
|
|
44
|
-
stop=stop_after_attempt(15),
|
|
45
|
-
wait=wait_exponential(multiplier=2, min=1, max=4),
|
|
41
|
+
stop=stop_after_attempt(15), wait=wait_exponential(multiplier=2, min=1, max=4)
|
|
46
42
|
):
|
|
47
43
|
with attempt:
|
|
48
44
|
try:
|
|
@@ -58,14 +54,13 @@ def inference_server_startup_flow(
|
|
|
58
54
|
if "is_current" in resp_body and resp_body["is_current"] is True:
|
|
59
55
|
logger.info("Hash is current, starting inference server")
|
|
60
56
|
inference_server_controller.start()
|
|
61
|
-
except Exception as exc:
|
|
57
|
+
except Exception as exc: # noqa
|
|
62
58
|
logger.warning(f"Patch ping attempt failed with error {exc}")
|
|
63
59
|
raise exc
|
|
64
60
|
|
|
65
61
|
|
|
66
62
|
async def async_inference_server_startup_flow(
|
|
67
|
-
inference_server_controller: InferenceServerController,
|
|
68
|
-
logger: Logger,
|
|
63
|
+
inference_server_controller: InferenceServerController, logger: Logger
|
|
69
64
|
) -> None:
|
|
70
65
|
return await to_thread.run_sync(
|
|
71
66
|
inference_server_startup_flow, inference_server_controller, logger
|
truss/{server/control → templates/control/control/helpers}/truss_patch/model_code_patch_applier.py
RENAMED
|
@@ -2,14 +2,16 @@ import logging
|
|
|
2
2
|
import os
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# TODO(marius/TaT): remove try-except after TaT.
|
|
6
|
+
# TODO(pankaj) In desparate need of refactoring into separate library
|
|
7
|
+
try:
|
|
8
|
+
from helpers.custom_types import Action, Patch
|
|
9
|
+
except ModuleNotFoundError as exc:
|
|
10
|
+
logging.debug(f"Importing helpers from truss core, caused by: {exc}")
|
|
11
|
+
from truss.templates.control.control.helpers.custom_types import Action, Patch
|
|
6
12
|
|
|
7
13
|
|
|
8
|
-
def apply_code_patch(
|
|
9
|
-
relative_dir: Path,
|
|
10
|
-
patch: ModelCodePatch,
|
|
11
|
-
logger: logging.Logger,
|
|
12
|
-
):
|
|
14
|
+
def apply_code_patch(relative_dir: Path, patch: Patch, logger: logging.Logger):
|
|
13
15
|
logger.debug(f"Applying code patch {patch.to_dict()}")
|
|
14
16
|
filepath: Path = relative_dir / patch.path
|
|
15
17
|
action = patch.action
|
|
@@ -3,9 +3,7 @@ import subprocess
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import Optional
|
|
5
5
|
|
|
6
|
-
from
|
|
7
|
-
from truss.server.control.patch.model_code_patch_applier import apply_code_patch
|
|
8
|
-
from truss.server.control.patch.types import (
|
|
6
|
+
from helpers.custom_types import (
|
|
9
7
|
Action,
|
|
10
8
|
ConfigPatch,
|
|
11
9
|
EnvVarPatch,
|
|
@@ -16,7 +14,19 @@ from truss.server.control.patch.types import (
|
|
|
16
14
|
PythonRequirementPatch,
|
|
17
15
|
SystemPackagePatch,
|
|
18
16
|
)
|
|
19
|
-
from
|
|
17
|
+
from helpers.errors import UnsupportedPatch
|
|
18
|
+
from helpers.truss_patch.model_code_patch_applier import apply_code_patch
|
|
19
|
+
|
|
20
|
+
# TODO(marius/TaT): remove try-except after TaT.
|
|
21
|
+
try:
|
|
22
|
+
from truss.base.truss_config import ExternalData, ExternalDataItem, TrussConfig
|
|
23
|
+
except ImportError:
|
|
24
|
+
from truss.truss_config import ( # type: ignore[no-redef]
|
|
25
|
+
ExternalData,
|
|
26
|
+
ExternalDataItem,
|
|
27
|
+
TrussConfig,
|
|
28
|
+
)
|
|
29
|
+
|
|
20
30
|
from truss.util.download import download_external_data
|
|
21
31
|
|
|
22
32
|
|
|
@@ -36,7 +46,7 @@ class ModelContainerPatchApplier:
|
|
|
36
46
|
self._inference_server_home / self._truss_config.model_module_dir
|
|
37
47
|
)
|
|
38
48
|
self._bundled_packages_dir = (
|
|
39
|
-
self._inference_server_home / self._truss_config.bundled_packages_dir
|
|
49
|
+
self._inference_server_home / ".." / self._truss_config.bundled_packages_dir
|
|
40
50
|
).resolve()
|
|
41
51
|
self._data_dir = self._inference_server_home / self._truss_config.data_dir
|
|
42
52
|
self._app_logger = app_logger
|
|
@@ -121,30 +131,12 @@ class ModelContainerPatchApplier:
|
|
|
121
131
|
|
|
122
132
|
if action == Action.REMOVE:
|
|
123
133
|
subprocess.run(
|
|
124
|
-
[
|
|
125
|
-
"apt",
|
|
126
|
-
"remove",
|
|
127
|
-
"-y",
|
|
128
|
-
system_package_patch.package,
|
|
129
|
-
],
|
|
130
|
-
check=True,
|
|
134
|
+
["apt", "remove", "-y", system_package_patch.package], check=True
|
|
131
135
|
)
|
|
132
136
|
elif action in [Action.ADD, Action.UPDATE]:
|
|
137
|
+
subprocess.run(["apt", "update"], check=True)
|
|
133
138
|
subprocess.run(
|
|
134
|
-
[
|
|
135
|
-
"apt",
|
|
136
|
-
"update",
|
|
137
|
-
],
|
|
138
|
-
check=True,
|
|
139
|
-
)
|
|
140
|
-
subprocess.run(
|
|
141
|
-
[
|
|
142
|
-
"apt",
|
|
143
|
-
"install",
|
|
144
|
-
"-y",
|
|
145
|
-
system_package_patch.package,
|
|
146
|
-
],
|
|
147
|
-
check=True,
|
|
139
|
+
["apt", "install", "-y", system_package_patch.package], check=True
|
|
148
140
|
)
|
|
149
141
|
else:
|
|
150
142
|
raise ValueError(f"Unknown python requirement patch action {action}")
|