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
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from truss.base.truss_config import TrussConfig
|
|
6
|
+
from truss.templates.control.control.helpers.custom_types import (
|
|
7
|
+
Action,
|
|
8
|
+
ConfigPatch,
|
|
9
|
+
EnvVarPatch,
|
|
10
|
+
ExternalDataPatch,
|
|
11
|
+
ModelCodePatch,
|
|
12
|
+
PackagePatch,
|
|
13
|
+
Patch,
|
|
14
|
+
PythonRequirementPatch,
|
|
15
|
+
SystemPackagePatch,
|
|
16
|
+
)
|
|
17
|
+
from truss.templates.control.control.helpers.errors import UnsupportedPatch
|
|
18
|
+
from truss.templates.control.control.helpers.truss_patch.model_code_patch_applier import (
|
|
19
|
+
apply_code_patch,
|
|
20
|
+
)
|
|
21
|
+
from truss.templates.control.control.helpers.truss_patch.requirement_name_identifier import (
|
|
22
|
+
identify_requirement_name,
|
|
23
|
+
reqs_by_name,
|
|
24
|
+
)
|
|
25
|
+
from truss.templates.control.control.helpers.truss_patch.system_packages import (
|
|
26
|
+
system_packages_set,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class TrussDirPatchApplier:
|
|
31
|
+
"""Applies patches to a truss directory.
|
|
32
|
+
This should be compatible with ModelContainerPatchApplier.
|
|
33
|
+
|
|
34
|
+
Note: This class imported via old_build_setup.sh.jinja in the baseten
|
|
35
|
+
repository
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def __init__(self, truss_dir: Path, logger: logging.Logger) -> None:
|
|
39
|
+
self._truss_dir = truss_dir
|
|
40
|
+
self._truss_config_path = self._truss_dir / "config.yaml"
|
|
41
|
+
self._truss_config = TrussConfig.from_yaml(self._truss_config_path)
|
|
42
|
+
self._logger = logger
|
|
43
|
+
|
|
44
|
+
def __call__(self, patches: List[Patch]):
|
|
45
|
+
# Apply model code patches immediately
|
|
46
|
+
# Aggregate config patches and apply at end
|
|
47
|
+
reqs = reqs_by_name(self._truss_config.requirements)
|
|
48
|
+
pkgs = system_packages_set(self._truss_config.system_packages)
|
|
49
|
+
new_config = self._truss_config
|
|
50
|
+
for patch in patches:
|
|
51
|
+
self._logger.debug(f"Applying patch {patch.to_dict()}")
|
|
52
|
+
action = patch.body.action
|
|
53
|
+
if isinstance(patch.body, ModelCodePatch):
|
|
54
|
+
model_code_patch: ModelCodePatch = patch.body
|
|
55
|
+
model_module_dir = self._truss_dir / self._truss_config.model_module_dir
|
|
56
|
+
apply_code_patch(model_module_dir, model_code_patch, self._logger)
|
|
57
|
+
elif isinstance(patch.body, PythonRequirementPatch):
|
|
58
|
+
py_req_patch: PythonRequirementPatch = patch.body
|
|
59
|
+
req = py_req_patch.requirement
|
|
60
|
+
req_name = identify_requirement_name(req)
|
|
61
|
+
if action == Action.REMOVE:
|
|
62
|
+
del reqs[req_name]
|
|
63
|
+
elif action == Action.ADD or Action.UPDATE:
|
|
64
|
+
reqs[req_name] = req
|
|
65
|
+
elif isinstance(patch.body, SystemPackagePatch):
|
|
66
|
+
sys_pkg_patch: SystemPackagePatch = patch.body
|
|
67
|
+
pkg = sys_pkg_patch.package
|
|
68
|
+
if action == Action.REMOVE:
|
|
69
|
+
pkgs.remove(pkg)
|
|
70
|
+
elif action == Action.ADD or Action.UPDATE:
|
|
71
|
+
pkgs.add(pkg)
|
|
72
|
+
elif isinstance(patch.body, ConfigPatch):
|
|
73
|
+
new_config = TrussConfig.from_dict(patch.body.config)
|
|
74
|
+
# Each of EnvVarPatch and ExternalDataPatch can be expressed through an
|
|
75
|
+
# overwrite of the config, handled below.
|
|
76
|
+
elif isinstance(patch.body, (EnvVarPatch, ExternalDataPatch)):
|
|
77
|
+
pass
|
|
78
|
+
elif isinstance(patch.body, PackagePatch):
|
|
79
|
+
package_patch: PackagePatch = patch.body
|
|
80
|
+
package_module_dir = (
|
|
81
|
+
self._truss_dir / self._truss_config.bundled_packages_dir
|
|
82
|
+
)
|
|
83
|
+
apply_code_patch(package_module_dir, package_patch, self._logger)
|
|
84
|
+
else:
|
|
85
|
+
raise UnsupportedPatch(f"Unknown patch type {patch.type}")
|
|
86
|
+
|
|
87
|
+
new_config.write_to_yaml_file(self._truss_config_path)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from jinja2 import Template
|
|
2
|
-
|
|
3
|
-
from truss.
|
|
2
|
+
|
|
3
|
+
from truss.base.constants import README_TEMPLATE_NAME, TEMPLATES_DIR
|
|
4
|
+
from truss.base.truss_spec import TrussSpec
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
def generate_readme(_spec: TrussSpec) -> str:
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
3
|
import yaml
|
|
4
|
+
|
|
4
5
|
from truss.local.local_config_handler import LocalConfigHandler
|
|
5
|
-
from truss.patch.hash import str_hash_str
|
|
6
|
-
from truss.truss_handle import TrussHandle
|
|
6
|
+
from truss.truss_handle.patch.hash import str_hash_str
|
|
7
|
+
from truss.truss_handle.truss_handle import TrussHandle
|
|
7
8
|
from truss.util.path import copy_file_path, copy_tree_path, remove_tree_path
|
|
8
9
|
|
|
9
10
|
|
|
@@ -6,7 +6,7 @@ import sys
|
|
|
6
6
|
import uuid
|
|
7
7
|
from dataclasses import replace
|
|
8
8
|
from pathlib import Path
|
|
9
|
-
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
|
9
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union
|
|
10
10
|
from urllib.error import HTTPError
|
|
11
11
|
|
|
12
12
|
import requests
|
|
@@ -24,19 +24,46 @@ from tenacity import (
|
|
|
24
24
|
stop_after_delay,
|
|
25
25
|
wait_fixed,
|
|
26
26
|
)
|
|
27
|
-
|
|
27
|
+
|
|
28
|
+
from truss.base.constants import (
|
|
28
29
|
INFERENCE_SERVER_PORT,
|
|
29
30
|
TRUSS,
|
|
30
31
|
TRUSS_DIR,
|
|
31
32
|
TRUSS_HASH,
|
|
32
33
|
TRUSS_MODIFIED_TIME,
|
|
33
34
|
)
|
|
35
|
+
from truss.base.custom_types import Example
|
|
36
|
+
from truss.base.errors import ContainerIsDownError, ContainerNotFoundError
|
|
37
|
+
from truss.base.truss_config import (
|
|
38
|
+
BaseImage,
|
|
39
|
+
ExternalData,
|
|
40
|
+
ExternalDataItem,
|
|
41
|
+
TrussConfig,
|
|
42
|
+
)
|
|
43
|
+
from truss.base.truss_spec import TrussSpec
|
|
44
|
+
from truss.base.validation import validate_secret_name
|
|
34
45
|
from truss.contexts.image_builder.serving_image_builder import (
|
|
35
46
|
ServingImageBuilderContext,
|
|
36
47
|
)
|
|
37
48
|
from truss.contexts.local_loader.load_model_local import LoadModelLocal
|
|
38
|
-
from truss.
|
|
39
|
-
from truss.
|
|
49
|
+
from truss.contexts.truss_context import TrussContext
|
|
50
|
+
from truss.local.local_config_handler import LocalConfigHandler
|
|
51
|
+
from truss.templates.shared.serialization import (
|
|
52
|
+
truss_msgpack_deserialize,
|
|
53
|
+
truss_msgpack_serialize,
|
|
54
|
+
)
|
|
55
|
+
from truss.trt_llm.validation import validate
|
|
56
|
+
from truss.truss_handle.decorators import proxy_to_shadow_if_scattered
|
|
57
|
+
from truss.truss_handle.patch.calc_patch import calc_truss_patch
|
|
58
|
+
from truss.truss_handle.patch.custom_types import (
|
|
59
|
+
PatchDetails,
|
|
60
|
+
PatchRequest,
|
|
61
|
+
TrussSignature,
|
|
62
|
+
)
|
|
63
|
+
from truss.truss_handle.patch.hash import directory_content_hash
|
|
64
|
+
from truss.truss_handle.patch.signature import calc_truss_signature
|
|
65
|
+
from truss.truss_handle.readme_generator import generate_readme
|
|
66
|
+
from truss.util.docker import (
|
|
40
67
|
Docker,
|
|
41
68
|
DockerStates,
|
|
42
69
|
get_container_logs,
|
|
@@ -46,28 +73,13 @@ from truss.docker import (
|
|
|
46
73
|
get_urls_from_container,
|
|
47
74
|
kill_containers,
|
|
48
75
|
)
|
|
49
|
-
from truss.
|
|
50
|
-
from truss.local.local_config_handler import LocalConfigHandler
|
|
51
|
-
from truss.notebook import is_notebook_or_ipython
|
|
52
|
-
from truss.patch.calc_patch import calc_truss_patch
|
|
53
|
-
from truss.patch.hash import directory_content_hash
|
|
54
|
-
from truss.patch.signature import calc_truss_signature
|
|
55
|
-
from truss.patch.types import TrussSignature
|
|
56
|
-
from truss.readme_generator import generate_readme
|
|
57
|
-
from truss.server.shared.serialization import (
|
|
58
|
-
truss_msgpack_deserialize,
|
|
59
|
-
truss_msgpack_serialize,
|
|
60
|
-
)
|
|
61
|
-
from truss.truss_config import BaseImage, ExternalData, ExternalDataItem, TrussConfig
|
|
62
|
-
from truss.truss_spec import TrussSpec
|
|
63
|
-
from truss.types import Example, PatchDetails, PatchRequest
|
|
76
|
+
from truss.util.notebook import is_notebook_or_ipython
|
|
64
77
|
from truss.util.path import (
|
|
65
78
|
copy_file_path,
|
|
66
79
|
copy_tree_path,
|
|
67
80
|
get_max_modified_time_of_dir,
|
|
68
81
|
load_trussignore_patterns,
|
|
69
82
|
)
|
|
70
|
-
from truss.validation import validate_secret_name
|
|
71
83
|
|
|
72
84
|
logger: logging.Logger = logging.getLogger(__name__)
|
|
73
85
|
|
|
@@ -76,16 +88,32 @@ if is_notebook_or_ipython():
|
|
|
76
88
|
logger.addHandler(logging.StreamHandler(sys.stdout))
|
|
77
89
|
|
|
78
90
|
|
|
91
|
+
class RunningContainer:
|
|
92
|
+
def __init__(self, container):
|
|
93
|
+
self.container = container
|
|
94
|
+
|
|
95
|
+
def logs(self):
|
|
96
|
+
from python_on_whales import docker
|
|
97
|
+
|
|
98
|
+
return docker.logs(self.container, follow=True, stream=True)
|
|
99
|
+
|
|
100
|
+
def wait(self):
|
|
101
|
+
from python_on_whales import docker
|
|
102
|
+
|
|
103
|
+
return docker.wait(self.container)
|
|
104
|
+
|
|
105
|
+
|
|
79
106
|
class TrussHandle:
|
|
80
107
|
def __init__(self, truss_dir: Path, validate: bool = True) -> None:
|
|
81
108
|
self._truss_dir = truss_dir
|
|
82
|
-
self._spec = TrussSpec(
|
|
109
|
+
self._spec = TrussSpec(self._truss_dir)
|
|
83
110
|
self._hash_for_mod_time: Optional[Tuple[float, str]] = None
|
|
84
111
|
if validate:
|
|
85
112
|
self.validate()
|
|
86
113
|
|
|
87
114
|
def validate(self):
|
|
88
115
|
self._validate_external_packages()
|
|
116
|
+
self._validate_extensions()
|
|
89
117
|
|
|
90
118
|
@property
|
|
91
119
|
def spec(self) -> TrussSpec:
|
|
@@ -149,6 +177,57 @@ class TrussHandle:
|
|
|
149
177
|
"""[Deprecated] Do not use."""
|
|
150
178
|
return _docker_image_from_labels(labels)
|
|
151
179
|
|
|
180
|
+
@proxy_to_shadow_if_scattered
|
|
181
|
+
def run_python_script(self, script_path: Path, build_dir: Optional[Path] = None):
|
|
182
|
+
from python_on_whales.exceptions import DockerException
|
|
183
|
+
|
|
184
|
+
image = self.build_serving_docker_image(build_dir=build_dir)
|
|
185
|
+
secrets_mount_dir_path = _prepare_secrets_mount_dir()
|
|
186
|
+
|
|
187
|
+
envs: Dict[str, str] = {}
|
|
188
|
+
# Add bundled packages to the PYTHONPATH. Note
|
|
189
|
+
# that this is necessary to achieve the same environment as Truss Server
|
|
190
|
+
# -- this is setup that is done by Truss Server, that won't be available
|
|
191
|
+
# to the standalone script.
|
|
192
|
+
bundled_packages_path = Path("/packages")
|
|
193
|
+
envs["PYTHONPATH"] = bundled_packages_path.as_posix()
|
|
194
|
+
|
|
195
|
+
# Note that the entrypoint command should match
|
|
196
|
+
# what we use when executing Truss Server.
|
|
197
|
+
entrypoint_command = self.spec.python_executable_path or "python3"
|
|
198
|
+
|
|
199
|
+
def _docker_run(gpus: Optional[str] = None):
|
|
200
|
+
container = Docker.client().run(
|
|
201
|
+
image.id,
|
|
202
|
+
entrypoint=entrypoint_command,
|
|
203
|
+
command=["/app/script.py"],
|
|
204
|
+
detach=True,
|
|
205
|
+
mounts=[
|
|
206
|
+
[
|
|
207
|
+
"type=bind",
|
|
208
|
+
f"src={str(secrets_mount_dir_path)}",
|
|
209
|
+
"target=/secrets",
|
|
210
|
+
],
|
|
211
|
+
[
|
|
212
|
+
"type=bind",
|
|
213
|
+
f"src={str(script_path.absolute())}",
|
|
214
|
+
"target=/app/script.py",
|
|
215
|
+
],
|
|
216
|
+
],
|
|
217
|
+
gpus=gpus,
|
|
218
|
+
envs=envs,
|
|
219
|
+
add_hosts=[("host.docker.internal", "host-gateway")],
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
return RunningContainer(container)
|
|
223
|
+
|
|
224
|
+
try:
|
|
225
|
+
return _docker_run("all" if self._spec.config.resources.use_gpu else None)
|
|
226
|
+
except DockerException:
|
|
227
|
+
# The reason we'd wind up here is if the Truss needs
|
|
228
|
+
# a GPU, but the host does not have one that can attach.
|
|
229
|
+
return _docker_run(None)
|
|
230
|
+
|
|
152
231
|
@proxy_to_shadow_if_scattered
|
|
153
232
|
def docker_run(
|
|
154
233
|
self,
|
|
@@ -159,7 +238,9 @@ class TrussHandle:
|
|
|
159
238
|
patch_ping_url: Optional[str] = None,
|
|
160
239
|
wait_for_server_ready: bool = True,
|
|
161
240
|
network: Optional[str] = None,
|
|
162
|
-
|
|
241
|
+
container_name_prefix: Optional[str] = None,
|
|
242
|
+
model_server_stop_retry_override=None,
|
|
243
|
+
disable_json_logging: bool = False,
|
|
163
244
|
):
|
|
164
245
|
"""
|
|
165
246
|
Builds a docker image and runs it as a container. For control trusses,
|
|
@@ -173,7 +254,10 @@ class TrussHandle:
|
|
|
173
254
|
patch_ping_url: Mostly for testing, if supplied then a live
|
|
174
255
|
reload capable truss queries for truss changes
|
|
175
256
|
by hitting this url.
|
|
176
|
-
wait_for_server_ready: If true, wait for server to pass readiness
|
|
257
|
+
wait_for_server_ready: If true, wait for server to pass readiness
|
|
258
|
+
probe before returning.
|
|
259
|
+
network: docker network name.
|
|
260
|
+
container_name_prefix: optional docker container name prefix.
|
|
177
261
|
|
|
178
262
|
Returns:
|
|
179
263
|
Container, which can be used to get information about the running,
|
|
@@ -186,7 +270,7 @@ class TrussHandle:
|
|
|
186
270
|
container = container_if_patched
|
|
187
271
|
else:
|
|
188
272
|
image = self.build_serving_docker_image(
|
|
189
|
-
build_dir=build_dir, tag=tag, network=network
|
|
273
|
+
build_dir=build_dir, tag=tag, network=network
|
|
190
274
|
)
|
|
191
275
|
secrets_mount_dir_path = _prepare_secrets_mount_dir()
|
|
192
276
|
publish_ports = [[local_port, INFERENCE_SERVER_PORT]]
|
|
@@ -198,6 +282,14 @@ class TrussHandle:
|
|
|
198
282
|
envs = {}
|
|
199
283
|
if patch_ping_url is not None:
|
|
200
284
|
envs["PATCH_PING_URL_TRUSS"] = patch_ping_url
|
|
285
|
+
if disable_json_logging:
|
|
286
|
+
envs["DISABLE_JSON_LOGGING"] = "true"
|
|
287
|
+
|
|
288
|
+
if container_name_prefix:
|
|
289
|
+
suffix = str(uuid.uuid4()).split("-")[0]
|
|
290
|
+
name = f"{container_name_prefix}-{suffix}"
|
|
291
|
+
else:
|
|
292
|
+
name = None
|
|
201
293
|
|
|
202
294
|
def _run_docker(gpus: Optional[str] = None):
|
|
203
295
|
return Docker.client().run(
|
|
@@ -210,11 +302,23 @@ class TrussHandle:
|
|
|
210
302
|
"type=bind",
|
|
211
303
|
f"src={str(secrets_mount_dir_path)}",
|
|
212
304
|
"target=/secrets",
|
|
213
|
-
]
|
|
305
|
+
],
|
|
306
|
+
[
|
|
307
|
+
"type=bind",
|
|
308
|
+
f"src={str(LocalConfigHandler.bptr_data_resolution_dir_path())}",
|
|
309
|
+
"target=/bptr",
|
|
310
|
+
],
|
|
311
|
+
[
|
|
312
|
+
"type=bind",
|
|
313
|
+
f"src={str(LocalConfigHandler.dynamic_config_path())}",
|
|
314
|
+
"target=/etc/b10_dynamic_config",
|
|
315
|
+
"readonly=false",
|
|
316
|
+
],
|
|
214
317
|
],
|
|
215
318
|
gpus=gpus,
|
|
216
319
|
envs=envs,
|
|
217
320
|
add_hosts=[("host.docker.internal", "host-gateway")],
|
|
321
|
+
name=name,
|
|
218
322
|
)
|
|
219
323
|
|
|
220
324
|
try:
|
|
@@ -232,7 +336,12 @@ class TrussHandle:
|
|
|
232
336
|
)
|
|
233
337
|
model_base_url = f"http://localhost:{local_port}/v1/models/model"
|
|
234
338
|
try:
|
|
235
|
-
wait_for_truss(
|
|
339
|
+
wait_for_truss(
|
|
340
|
+
model_base_url,
|
|
341
|
+
container,
|
|
342
|
+
wait_for_server_ready,
|
|
343
|
+
model_server_stop_retry_override,
|
|
344
|
+
)
|
|
236
345
|
except ContainerNotFoundError as err:
|
|
237
346
|
raise err
|
|
238
347
|
except (ContainerIsDownError, HTTPError, ConnectionError) as err:
|
|
@@ -263,6 +372,7 @@ class TrussHandle:
|
|
|
263
372
|
else:
|
|
264
373
|
return self.server_predict(request)
|
|
265
374
|
|
|
375
|
+
# TODO(marius): can we kill this?
|
|
266
376
|
def server_predict(self, request: Dict):
|
|
267
377
|
"""Run the prediction flow locally."""
|
|
268
378
|
model = LoadModelLocal.run(self._truss_dir)
|
|
@@ -384,11 +494,7 @@ class TrussHandle:
|
|
|
384
494
|
validate_secret_name(secret_name)
|
|
385
495
|
self._update_config(
|
|
386
496
|
lambda conf: replace(
|
|
387
|
-
conf,
|
|
388
|
-
secrets={
|
|
389
|
-
**conf.secrets,
|
|
390
|
-
secret_name: default_secret_value,
|
|
391
|
-
},
|
|
497
|
+
conf, secrets={**conf.secrets, secret_name: default_secret_value}
|
|
392
498
|
)
|
|
393
499
|
)
|
|
394
500
|
|
|
@@ -410,23 +516,12 @@ class TrussHandle:
|
|
|
410
516
|
self._spec.config.external_data or ExternalData([])
|
|
411
517
|
)
|
|
412
518
|
new_external_data = replace(
|
|
413
|
-
current_external_data,
|
|
414
|
-
items=current_external_data.items + [item],
|
|
415
|
-
)
|
|
416
|
-
self._update_config(
|
|
417
|
-
lambda conf: replace(
|
|
418
|
-
conf,
|
|
419
|
-
external_data=new_external_data,
|
|
420
|
-
)
|
|
519
|
+
current_external_data, items=current_external_data.items + [item]
|
|
421
520
|
)
|
|
521
|
+
self._update_config(lambda conf: replace(conf, external_data=new_external_data))
|
|
422
522
|
|
|
423
523
|
def remove_all_external_data(self):
|
|
424
|
-
self._update_config(
|
|
425
|
-
lambda conf: replace(
|
|
426
|
-
conf,
|
|
427
|
-
external_data=None,
|
|
428
|
-
)
|
|
429
|
-
)
|
|
524
|
+
self._update_config(lambda conf: replace(conf, external_data=None))
|
|
430
525
|
|
|
431
526
|
def update_requirements(self, requirements: List[str]):
|
|
432
527
|
"""Update requirements in truss model's config.
|
|
@@ -554,9 +649,7 @@ class TrussHandle:
|
|
|
554
649
|
|
|
555
650
|
@proxy_to_shadow_if_scattered
|
|
556
651
|
def get_serving_docker_containers_from_labels(
|
|
557
|
-
self,
|
|
558
|
-
all: bool = False,
|
|
559
|
-
labels: Optional[dict] = None,
|
|
652
|
+
self, all: bool = False, labels: Optional[dict] = None
|
|
560
653
|
) -> list:
|
|
561
654
|
"""Get serving docker containers, with given labels.
|
|
562
655
|
|
|
@@ -568,10 +661,7 @@ class TrussHandle:
|
|
|
568
661
|
labels = self._get_serving_lookup_labels()
|
|
569
662
|
else:
|
|
570
663
|
# Make sure we're looking for serving container for this truss.
|
|
571
|
-
labels = {
|
|
572
|
-
TRUSS: True,
|
|
573
|
-
**labels,
|
|
574
|
-
}
|
|
664
|
+
labels = {TRUSS: True, **labels}
|
|
575
665
|
|
|
576
666
|
return sorted(get_containers(labels, all=all), key=lambda c: c.created)
|
|
577
667
|
|
|
@@ -630,10 +720,7 @@ class TrussHandle:
|
|
|
630
720
|
python_executable_path=python_executable_path,
|
|
631
721
|
)
|
|
632
722
|
return replace(conf, base_image=new_base_image)
|
|
633
|
-
new_base_image = BaseImage(
|
|
634
|
-
image,
|
|
635
|
-
python_executable_path,
|
|
636
|
-
)
|
|
723
|
+
new_base_image = BaseImage(image, python_executable_path)
|
|
637
724
|
return replace(conf, base_image=new_base_image)
|
|
638
725
|
|
|
639
726
|
self._update_config(define_base_image_fn)
|
|
@@ -691,10 +778,7 @@ class TrussHandle:
|
|
|
691
778
|
inferred_python_version = f"py{version_parts[0]}{version_parts[1]}"
|
|
692
779
|
|
|
693
780
|
self._update_config(
|
|
694
|
-
lambda conf: replace(
|
|
695
|
-
conf,
|
|
696
|
-
python_version=inferred_python_version,
|
|
697
|
-
)
|
|
781
|
+
lambda conf: replace(conf, python_version=inferred_python_version)
|
|
698
782
|
)
|
|
699
783
|
|
|
700
784
|
def _control_serving_container_has_partially_applied_patch(self) -> Optional[bool]:
|
|
@@ -758,7 +842,6 @@ class TrussHandle:
|
|
|
758
842
|
if prev_sign_str is None:
|
|
759
843
|
logger.info(f"Signature not found for truss for hash {prev_truss_hash}")
|
|
760
844
|
return None
|
|
761
|
-
|
|
762
845
|
prev_sign = TrussSignature.from_dict(json.loads(prev_sign_str))
|
|
763
846
|
ignore_patterns = truss_ignore_patterns + self._spec.hash_ignore_patterns
|
|
764
847
|
patch_ops = calc_truss_patch(self._truss_dir, prev_sign, ignore_patterns)
|
|
@@ -783,7 +866,7 @@ class TrussHandle:
|
|
|
783
866
|
gatherer and a handle to that truss is returned. These gathered trusses
|
|
784
867
|
are caches and resused.
|
|
785
868
|
"""
|
|
786
|
-
from truss.truss_gatherer import gather
|
|
869
|
+
from truss.truss_handle.truss_gatherer import gather
|
|
787
870
|
|
|
788
871
|
if not self.is_scattered():
|
|
789
872
|
return self._truss_dir
|
|
@@ -847,7 +930,7 @@ class TrussHandle:
|
|
|
847
930
|
|
|
848
931
|
def _build_image(
|
|
849
932
|
self,
|
|
850
|
-
builder_context,
|
|
933
|
+
builder_context: Type[TrussContext],
|
|
851
934
|
labels: Dict[str, str],
|
|
852
935
|
build_dir: Optional[Path] = None,
|
|
853
936
|
tag: Optional[str] = None,
|
|
@@ -855,7 +938,7 @@ class TrussHandle:
|
|
|
855
938
|
network: Optional[str] = None,
|
|
856
939
|
):
|
|
857
940
|
image = _docker_image_from_labels(labels=labels)
|
|
858
|
-
if
|
|
941
|
+
if image is not None:
|
|
859
942
|
return image
|
|
860
943
|
|
|
861
944
|
build_dir_path = Path(build_dir) if build_dir is not None else None
|
|
@@ -917,7 +1000,7 @@ class TrussHandle:
|
|
|
917
1000
|
)
|
|
918
1001
|
resp = self.patch_container(patch_request)
|
|
919
1002
|
if "error" in resp:
|
|
920
|
-
raise RuntimeError(f
|
|
1003
|
+
raise RuntimeError(f"Failed to patch control truss {resp['error']}")
|
|
921
1004
|
self._store_signature()
|
|
922
1005
|
return container
|
|
923
1006
|
|
|
@@ -951,6 +1034,11 @@ class TrussHandle:
|
|
|
951
1034
|
f"{path.resolve()} but that path does not exist."
|
|
952
1035
|
)
|
|
953
1036
|
|
|
1037
|
+
def _validate_extensions(self):
|
|
1038
|
+
# Only one extenstion right now.
|
|
1039
|
+
if self._spec.config.trt_llm is not None:
|
|
1040
|
+
validate(self._spec)
|
|
1041
|
+
|
|
954
1042
|
|
|
955
1043
|
def _prediction_flow(model, request: Dict):
|
|
956
1044
|
"""This flow attempts to mimic the request life-cycle of a server"""
|
|
@@ -974,31 +1062,39 @@ def _wait_for_docker_build(container) -> None:
|
|
|
974
1062
|
raise ContainerIsDownError(f"Container stuck in state: {state.value}.")
|
|
975
1063
|
|
|
976
1064
|
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
)
|
|
985
|
-
|
|
986
|
-
|
|
1065
|
+
def _wait_for_model_server(url: str, stop=stop_after_delay(120)) -> Response: # type: ignore[return]
|
|
1066
|
+
for attempt in Retrying(
|
|
1067
|
+
stop=stop,
|
|
1068
|
+
wait=wait_fixed(2),
|
|
1069
|
+
retry=(
|
|
1070
|
+
retry_if_result(lambda response: response.status_code in [502, 503])
|
|
1071
|
+
| retry_if_exception_type(exceptions.ConnectionError)
|
|
1072
|
+
),
|
|
1073
|
+
):
|
|
1074
|
+
with attempt:
|
|
1075
|
+
response = requests.get(url)
|
|
1076
|
+
return response
|
|
987
1077
|
|
|
988
1078
|
|
|
989
1079
|
def wait_for_truss(
|
|
990
|
-
url: str,
|
|
1080
|
+
url: str,
|
|
1081
|
+
container: str,
|
|
1082
|
+
wait_for_server_ready: bool = True,
|
|
1083
|
+
model_server_stop_retry_override=None,
|
|
991
1084
|
) -> None:
|
|
992
1085
|
from python_on_whales.exceptions import NoSuchContainer
|
|
993
1086
|
|
|
994
1087
|
try:
|
|
995
1088
|
_wait_for_docker_build(container)
|
|
1089
|
+
if wait_for_server_ready:
|
|
1090
|
+
if model_server_stop_retry_override is not None:
|
|
1091
|
+
_wait_for_model_server(url, stop=model_server_stop_retry_override)
|
|
1092
|
+
else:
|
|
1093
|
+
_wait_for_model_server(url)
|
|
996
1094
|
except NoSuchContainer:
|
|
997
1095
|
raise ContainerNotFoundError(message=f"Container {container} was not found")
|
|
998
1096
|
except RetryError as retry_err:
|
|
999
1097
|
retry_err.reraise()
|
|
1000
|
-
if wait_for_server_ready:
|
|
1001
|
-
_wait_for_model_server(url)
|
|
1002
1098
|
|
|
1003
1099
|
|
|
1004
1100
|
def _prepare_secrets_mount_dir() -> Path:
|
truss/util/.truss_ignore
CHANGED
|
@@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, Any, Dict, List
|
|
|
5
5
|
if TYPE_CHECKING:
|
|
6
6
|
from python_on_whales.components.container.cli_wrapper import Container
|
|
7
7
|
|
|
8
|
-
from truss.constants import TRUSS_DIR
|
|
8
|
+
from truss.base.constants import TRUSS, TRUSS_DIR
|
|
9
9
|
from truss.local.local_config_handler import LocalConfigHandler
|
|
10
10
|
|
|
11
11
|
|
|
@@ -57,7 +57,7 @@ def get_urls_from_container(container_details) -> Dict[int, List[str]]:
|
|
|
57
57
|
)
|
|
58
58
|
|
|
59
59
|
def urls_from_port_protocol_values(
|
|
60
|
-
port_protocol_values: List[Dict[str, str]]
|
|
60
|
+
port_protocol_values: List[Dict[str, str]],
|
|
61
61
|
) -> List[str]:
|
|
62
62
|
return [url_from_port_protocol_value(v) for v in port_protocol_values]
|
|
63
63
|
|
|
@@ -115,3 +115,7 @@ def _create_label_filters(labels: Dict) -> Dict[str, Any]:
|
|
|
115
115
|
return {
|
|
116
116
|
f"label={label_key}": label_value for label_key, label_value in labels.items()
|
|
117
117
|
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def kill_all() -> None:
|
|
121
|
+
kill_containers({TRUSS: True})
|
truss/util/download.py
CHANGED
|
@@ -5,7 +5,7 @@ from pathlib import Path
|
|
|
5
5
|
from typing import Optional
|
|
6
6
|
|
|
7
7
|
import requests
|
|
8
|
-
from truss.truss_config import ExternalData
|
|
8
|
+
from truss.base.truss_config import ExternalData
|
|
9
9
|
|
|
10
10
|
B10CP_EXECUTABLE_NAME = "b10cp"
|
|
11
11
|
BLOB_DOWNLOAD_TIMEOUT_SECS = 600 # 10 minutes
|
|
@@ -41,9 +41,7 @@ def _b10cp_path() -> Optional[str]:
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
def _download_external_data_using_b10cp(
|
|
44
|
-
b10cp_path: str,
|
|
45
|
-
data_dir: Path,
|
|
46
|
-
external_data: ExternalData,
|
|
44
|
+
b10cp_path: str, data_dir: Path, external_data: ExternalData
|
|
47
45
|
):
|
|
48
46
|
procs = []
|
|
49
47
|
# TODO(pankaj) Limit concurrency here
|
|
@@ -56,11 +54,7 @@ def _download_external_data_using_b10cp(
|
|
|
56
54
|
proc.wait()
|
|
57
55
|
|
|
58
56
|
|
|
59
|
-
def _download_from_url_using_b10cp(
|
|
60
|
-
b10cp_path: str,
|
|
61
|
-
url: str,
|
|
62
|
-
download_to: Path,
|
|
63
|
-
):
|
|
57
|
+
def _download_from_url_using_b10cp(b10cp_path: str, url: str, download_to: Path):
|
|
64
58
|
return subprocess.Popen(
|
|
65
59
|
[
|
|
66
60
|
b10cp_path,
|
|
@@ -74,18 +68,15 @@ def _download_from_url_using_b10cp(
|
|
|
74
68
|
|
|
75
69
|
def _download_external_data_using_requests(data_dir: Path, external_data: ExternalData):
|
|
76
70
|
for item in external_data.items:
|
|
77
|
-
|
|
71
|
+
download_from_url_using_requests(
|
|
78
72
|
item.url, (data_dir / item.local_data_path).resolve()
|
|
79
73
|
)
|
|
80
74
|
|
|
81
75
|
|
|
82
|
-
def
|
|
76
|
+
def download_from_url_using_requests(URL: str, download_to: Path):
|
|
83
77
|
# Streaming download to keep memory usage low
|
|
84
78
|
resp = requests.get(
|
|
85
|
-
URL,
|
|
86
|
-
allow_redirects=True,
|
|
87
|
-
stream=True,
|
|
88
|
-
timeout=BLOB_DOWNLOAD_TIMEOUT_SECS,
|
|
79
|
+
URL, allow_redirects=True, stream=True, timeout=BLOB_DOWNLOAD_TIMEOUT_SECS
|
|
89
80
|
)
|
|
90
81
|
resp.raise_for_status()
|
|
91
82
|
with download_to.open("wb") as file:
|