truss 0.10.0rc1__py3-none-any.whl → 0.60.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of truss might be problematic. Click here for more details.
- truss/__init__.py +10 -3
- truss/api/__init__.py +123 -0
- truss/api/definitions.py +51 -0
- truss/base/constants.py +116 -0
- truss/base/custom_types.py +29 -0
- truss/{errors.py → base/errors.py} +4 -0
- truss/base/trt_llm_config.py +310 -0
- truss/{truss_config.py → base/truss_config.py} +344 -31
- truss/{truss_spec.py → base/truss_spec.py} +20 -6
- truss/{validation.py → base/validation.py} +60 -11
- truss/cli/cli.py +841 -88
- truss/{remote → cli}/remote_cli.py +2 -7
- truss/contexts/docker_build_setup.py +67 -0
- truss/contexts/image_builder/cache_warmer.py +2 -8
- truss/contexts/image_builder/image_builder.py +1 -1
- truss/contexts/image_builder/serving_image_builder.py +292 -46
- truss/contexts/image_builder/util.py +1 -3
- truss/contexts/local_loader/docker_build_emulator.py +58 -0
- truss/contexts/local_loader/load_model_local.py +2 -2
- truss/contexts/local_loader/truss_module_loader.py +1 -1
- truss/contexts/local_loader/utils.py +1 -1
- truss/local/local_config.py +2 -6
- truss/local/local_config_handler.py +20 -5
- truss/patch/__init__.py +1 -0
- truss/patch/hash.py +4 -70
- truss/patch/signature.py +4 -16
- truss/patch/truss_dir_patch_applier.py +3 -78
- truss/remote/baseten/api.py +308 -23
- truss/remote/baseten/auth.py +3 -3
- truss/remote/baseten/core.py +257 -50
- truss/remote/baseten/custom_types.py +44 -0
- truss/remote/baseten/error.py +4 -0
- truss/remote/baseten/remote.py +369 -118
- truss/remote/baseten/service.py +118 -11
- truss/remote/baseten/utils/status.py +29 -0
- truss/remote/baseten/utils/tar.py +34 -22
- truss/remote/baseten/utils/transfer.py +36 -23
- truss/remote/remote_factory.py +14 -5
- truss/remote/truss_remote.py +72 -45
- truss/templates/base.Dockerfile.jinja +18 -16
- truss/templates/cache.Dockerfile.jinja +3 -3
- truss/{server → templates/control}/control/application.py +14 -35
- truss/{server → templates/control}/control/endpoints.py +39 -9
- truss/{server/control/patch/types.py → templates/control/control/helpers/custom_types.py} +13 -52
- truss/{server → templates/control}/control/helpers/inference_server_controller.py +4 -8
- truss/{server → templates/control}/control/helpers/inference_server_process_controller.py +2 -4
- truss/{server → templates/control}/control/helpers/inference_server_starter.py +5 -10
- truss/{server/control → templates/control/control/helpers}/truss_patch/model_code_patch_applier.py +8 -6
- truss/{server/control/patch → templates/control/control/helpers/truss_patch}/model_container_patch_applier.py +18 -26
- truss/templates/control/control/helpers/truss_patch/requirement_name_identifier.py +66 -0
- truss/{server → templates/control}/control/server.py +11 -6
- truss/templates/control/requirements.txt +9 -0
- truss/templates/custom_python_dx/my_model.py +28 -0
- truss/templates/docker_server/proxy.conf.jinja +42 -0
- truss/templates/docker_server/supervisord.conf.jinja +27 -0
- truss/templates/docker_server_requirements.txt +1 -0
- truss/templates/server/common/errors.py +231 -0
- truss/{server → templates/server}/common/patches/whisper/patch.py +1 -0
- truss/{server/common/patches/__init__.py → templates/server/common/patches.py} +1 -3
- truss/{server → templates/server}/common/retry.py +1 -0
- truss/{server → templates/server}/common/schema.py +11 -9
- truss/templates/server/common/tracing.py +157 -0
- truss/templates/server/main.py +9 -0
- truss/templates/server/model_wrapper.py +961 -0
- truss/templates/server/requirements.txt +21 -0
- truss/templates/server/truss_server.py +447 -0
- truss/templates/server.Dockerfile.jinja +62 -14
- truss/templates/shared/dynamic_config_resolver.py +28 -0
- truss/templates/shared/lazy_data_resolver.py +164 -0
- truss/templates/shared/log_config.py +125 -0
- truss/{server → templates}/shared/secrets_resolver.py +1 -2
- truss/{server → templates}/shared/serialization.py +31 -9
- truss/{server → templates}/shared/util.py +3 -13
- truss/templates/trtllm-audio/model/model.py +49 -0
- truss/templates/trtllm-audio/packages/sigint_patch.py +14 -0
- truss/templates/trtllm-audio/packages/whisper_trt/__init__.py +215 -0
- truss/templates/trtllm-audio/packages/whisper_trt/assets.py +25 -0
- truss/templates/trtllm-audio/packages/whisper_trt/batching.py +52 -0
- truss/templates/trtllm-audio/packages/whisper_trt/custom_types.py +26 -0
- truss/templates/trtllm-audio/packages/whisper_trt/modeling.py +184 -0
- truss/templates/trtllm-audio/packages/whisper_trt/tokenizer.py +185 -0
- truss/templates/trtllm-audio/packages/whisper_trt/utils.py +245 -0
- truss/templates/trtllm-briton/src/extension.py +64 -0
- truss/tests/conftest.py +302 -94
- truss/tests/contexts/image_builder/test_serving_image_builder.py +74 -31
- truss/tests/contexts/local_loader/test_load_local.py +2 -2
- truss/tests/contexts/local_loader/test_truss_module_finder.py +1 -1
- truss/tests/patch/test_calc_patch.py +439 -127
- truss/tests/patch/test_dir_signature.py +3 -12
- truss/tests/patch/test_hash.py +1 -1
- truss/tests/patch/test_signature.py +1 -1
- truss/tests/patch/test_truss_dir_patch_applier.py +23 -11
- truss/tests/patch/test_types.py +2 -2
- truss/tests/remote/baseten/test_api.py +153 -58
- truss/tests/remote/baseten/test_auth.py +2 -1
- truss/tests/remote/baseten/test_core.py +160 -12
- truss/tests/remote/baseten/test_remote.py +489 -77
- truss/tests/remote/baseten/test_service.py +55 -0
- truss/tests/remote/test_remote_factory.py +16 -18
- truss/tests/remote/test_truss_remote.py +26 -17
- truss/tests/templates/control/control/helpers/test_context_managers.py +11 -0
- truss/tests/templates/control/control/helpers/test_model_container_patch_applier.py +184 -0
- truss/tests/templates/control/control/helpers/test_requirement_name_identifier.py +89 -0
- truss/tests/{server → templates/control}/control/test_server.py +79 -24
- truss/tests/{server → templates/control}/control/test_server_integration.py +24 -16
- truss/tests/templates/core/server/test_dynamic_config_resolver.py +108 -0
- truss/tests/templates/core/server/test_lazy_data_resolver.py +329 -0
- truss/tests/templates/core/server/test_lazy_data_resolver_v2.py +79 -0
- truss/tests/{server → templates}/core/server/test_secrets_resolver.py +1 -1
- truss/tests/{server → templates/server}/common/test_retry.py +3 -3
- truss/tests/templates/server/test_model_wrapper.py +248 -0
- truss/tests/{server → templates/server}/test_schema.py +3 -5
- truss/tests/{server/core/server/common → templates/server}/test_truss_server.py +8 -5
- truss/tests/test_build.py +9 -52
- truss/tests/test_config.py +336 -77
- truss/tests/test_context_builder_image.py +3 -11
- truss/tests/test_control_truss_patching.py +7 -12
- truss/tests/test_custom_server.py +38 -0
- truss/tests/test_data/context_builder_image_test/test.py +3 -0
- truss/tests/test_data/happy.ipynb +56 -0
- truss/tests/test_data/model_load_failure_test/config.yaml +2 -0
- truss/tests/test_data/model_load_failure_test/model/__init__.py +0 -0
- truss/tests/test_data/patch_ping_test_server/__init__.py +0 -0
- truss/{test_data → tests/test_data}/patch_ping_test_server/app.py +3 -9
- truss/{test_data → tests/test_data}/server.Dockerfile +20 -21
- truss/tests/test_data/server_conformance_test_truss/__init__.py +0 -0
- truss/tests/test_data/server_conformance_test_truss/model/__init__.py +0 -0
- truss/{test_data → tests/test_data}/server_conformance_test_truss/model/model.py +1 -3
- truss/tests/test_data/test_async_truss/__init__.py +0 -0
- truss/tests/test_data/test_async_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_basic_truss/__init__.py +0 -0
- truss/tests/test_data/test_basic_truss/config.yaml +16 -0
- truss/tests/test_data/test_basic_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_build_commands/__init__.py +0 -0
- truss/tests/test_data/test_build_commands/config.yaml +13 -0
- truss/tests/test_data/test_build_commands/model/__init__.py +0 -0
- truss/{test_data/test_streaming_async_generator_truss → tests/test_data/test_build_commands}/model/model.py +2 -3
- truss/tests/test_data/test_build_commands_failure/__init__.py +0 -0
- truss/tests/test_data/test_build_commands_failure/config.yaml +14 -0
- truss/tests/test_data/test_build_commands_failure/model/__init__.py +0 -0
- truss/tests/test_data/test_build_commands_failure/model/model.py +17 -0
- truss/tests/test_data/test_concurrency_truss/__init__.py +0 -0
- truss/tests/test_data/test_concurrency_truss/config.yaml +4 -0
- truss/tests/test_data/test_concurrency_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_custom_server_truss/__init__.py +0 -0
- truss/tests/test_data/test_custom_server_truss/config.yaml +20 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/Dockerfile +17 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/README.md +10 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/VERSION +1 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/__init__.py +0 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/app.py +19 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/build_upload_new_image.sh +6 -0
- truss/tests/test_data/test_openai/__init__.py +0 -0
- truss/{test_data/test_basic_truss → tests/test_data/test_openai}/config.yaml +1 -2
- truss/tests/test_data/test_openai/model/__init__.py +0 -0
- truss/tests/test_data/test_openai/model/model.py +15 -0
- truss/tests/test_data/test_pyantic_v1/__init__.py +0 -0
- truss/tests/test_data/test_pyantic_v1/model/__init__.py +0 -0
- truss/tests/test_data/test_pyantic_v1/model/model.py +28 -0
- truss/tests/test_data/test_pyantic_v1/requirements.txt +1 -0
- truss/tests/test_data/test_pyantic_v2/__init__.py +0 -0
- truss/tests/test_data/test_pyantic_v2/config.yaml +13 -0
- truss/tests/test_data/test_pyantic_v2/model/__init__.py +0 -0
- truss/tests/test_data/test_pyantic_v2/model/model.py +30 -0
- truss/tests/test_data/test_pyantic_v2/requirements.txt +1 -0
- truss/tests/test_data/test_requirements_file_truss/__init__.py +0 -0
- truss/tests/test_data/test_requirements_file_truss/config.yaml +13 -0
- truss/tests/test_data/test_requirements_file_truss/model/__init__.py +0 -0
- truss/{test_data → tests/test_data}/test_requirements_file_truss/model/model.py +1 -0
- truss/tests/test_data/test_streaming_async_generator_truss/__init__.py +0 -0
- truss/tests/test_data/test_streaming_async_generator_truss/config.yaml +4 -0
- truss/tests/test_data/test_streaming_async_generator_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_streaming_async_generator_truss/model/model.py +7 -0
- truss/tests/test_data/test_streaming_read_timeout/__init__.py +0 -0
- truss/tests/test_data/test_streaming_read_timeout/model/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss/config.yaml +4 -0
- truss/tests/test_data/test_streaming_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss_with_error/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss_with_error/model/__init__.py +0 -0
- truss/{test_data → tests/test_data}/test_streaming_truss_with_error/model/model.py +3 -11
- truss/tests/test_data/test_streaming_truss_with_error/packages/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss_with_error/packages/helpers_1.py +5 -0
- truss/tests/test_data/test_streaming_truss_with_error/packages/helpers_2.py +2 -0
- truss/tests/test_data/test_streaming_truss_with_tracing/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss_with_tracing/config.yaml +43 -0
- truss/tests/test_data/test_streaming_truss_with_tracing/model/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss_with_tracing/model/model.py +65 -0
- truss/tests/test_data/test_trt_llm_truss/__init__.py +0 -0
- truss/tests/test_data/test_trt_llm_truss/config.yaml +15 -0
- truss/tests/test_data/test_trt_llm_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_trt_llm_truss/model/model.py +15 -0
- truss/tests/test_data/test_truss/__init__.py +0 -0
- truss/tests/test_data/test_truss/config.yaml +4 -0
- truss/tests/test_data/test_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_truss/model/dummy +0 -0
- truss/tests/test_data/test_truss/packages/__init__.py +0 -0
- truss/tests/test_data/test_truss/packages/test_package/__init__.py +0 -0
- truss/tests/test_data/test_truss_server_caching_truss/__init__.py +0 -0
- truss/tests/test_data/test_truss_server_caching_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_truss_with_error/__init__.py +0 -0
- truss/tests/test_data/test_truss_with_error/config.yaml +4 -0
- truss/tests/test_data/test_truss_with_error/model/__init__.py +0 -0
- truss/tests/test_data/test_truss_with_error/model/model.py +8 -0
- truss/tests/test_data/test_truss_with_error/packages/__init__.py +0 -0
- truss/tests/test_data/test_truss_with_error/packages/helpers_1.py +5 -0
- truss/tests/test_data/test_truss_with_error/packages/helpers_2.py +2 -0
- truss/tests/test_docker.py +2 -1
- truss/tests/test_model_inference.py +1340 -292
- truss/tests/test_model_schema.py +33 -26
- truss/tests/test_testing_utilities_for_other_tests.py +50 -5
- truss/tests/test_truss_gatherer.py +3 -5
- truss/tests/test_truss_handle.py +62 -59
- truss/tests/test_util.py +2 -1
- truss/tests/test_validation.py +15 -13
- truss/tests/trt_llm/test_trt_llm_config.py +41 -0
- truss/tests/trt_llm/test_validation.py +91 -0
- truss/tests/util/test_config_checks.py +40 -0
- truss/tests/util/test_env_vars.py +14 -0
- truss/tests/util/test_path.py +10 -23
- truss/trt_llm/config_checks.py +43 -0
- truss/trt_llm/validation.py +42 -0
- truss/truss_handle/__init__.py +0 -0
- truss/truss_handle/build.py +122 -0
- truss/{decorators.py → truss_handle/decorators.py} +1 -1
- truss/truss_handle/patch/__init__.py +0 -0
- truss/{patch → truss_handle/patch}/calc_patch.py +146 -92
- truss/{types.py → truss_handle/patch/custom_types.py} +35 -27
- truss/{patch → truss_handle/patch}/dir_signature.py +1 -1
- truss/truss_handle/patch/hash.py +71 -0
- truss/{patch → truss_handle/patch}/local_truss_patch_applier.py +6 -4
- truss/truss_handle/patch/signature.py +22 -0
- truss/truss_handle/patch/truss_dir_patch_applier.py +87 -0
- truss/{readme_generator.py → truss_handle/readme_generator.py} +3 -2
- truss/{truss_gatherer.py → truss_handle/truss_gatherer.py} +3 -2
- truss/{truss_handle.py → truss_handle/truss_handle.py} +174 -78
- truss/util/.truss_ignore +3 -0
- truss/{docker.py → util/docker.py} +6 -2
- truss/util/download.py +6 -15
- truss/util/env_vars.py +41 -0
- truss/util/log_utils.py +52 -0
- truss/util/path.py +20 -20
- truss/util/requirements.py +11 -0
- {truss-0.10.0rc1.dist-info → truss-0.60.0.dist-info}/METADATA +18 -16
- truss-0.60.0.dist-info/RECORD +324 -0
- {truss-0.10.0rc1.dist-info → truss-0.60.0.dist-info}/WHEEL +1 -1
- truss-0.60.0.dist-info/entry_points.txt +4 -0
- truss_chains/__init__.py +71 -0
- truss_chains/definitions.py +756 -0
- truss_chains/deployment/__init__.py +0 -0
- truss_chains/deployment/code_gen.py +816 -0
- truss_chains/deployment/deployment_client.py +871 -0
- truss_chains/framework.py +1480 -0
- truss_chains/public_api.py +231 -0
- truss_chains/py.typed +0 -0
- truss_chains/pydantic_numpy.py +131 -0
- truss_chains/reference_code/reference_chainlet.py +34 -0
- truss_chains/reference_code/reference_model.py +10 -0
- truss_chains/remote_chainlet/__init__.py +0 -0
- truss_chains/remote_chainlet/model_skeleton.py +60 -0
- truss_chains/remote_chainlet/stub.py +380 -0
- truss_chains/remote_chainlet/utils.py +332 -0
- truss_chains/streaming.py +378 -0
- truss_chains/utils.py +178 -0
- CODE_OF_CONDUCT.md +0 -131
- CONTRIBUTING.md +0 -48
- README.md +0 -137
- context_builder.Dockerfile +0 -24
- truss/blob/blob_backend.py +0 -10
- truss/blob/blob_backend_registry.py +0 -23
- truss/blob/http_public_blob_backend.py +0 -23
- truss/build/__init__.py +0 -2
- truss/build/build.py +0 -143
- truss/build/configure.py +0 -63
- truss/cli/__init__.py +0 -2
- truss/cli/console.py +0 -5
- truss/cli/create.py +0 -5
- truss/config/trt_llm.py +0 -81
- truss/constants.py +0 -61
- truss/model_inference.py +0 -123
- truss/patch/types.py +0 -30
- truss/pytest.ini +0 -7
- truss/server/common/errors.py +0 -100
- truss/server/common/termination_handler_middleware.py +0 -64
- truss/server/common/truss_server.py +0 -389
- truss/server/control/patch/model_code_patch_applier.py +0 -46
- truss/server/control/patch/requirement_name_identifier.py +0 -17
- truss/server/inference_server.py +0 -29
- truss/server/model_wrapper.py +0 -434
- truss/server/shared/logging.py +0 -81
- truss/templates/trtllm/model/model.py +0 -97
- truss/templates/trtllm/packages/build_engine_utils.py +0 -34
- truss/templates/trtllm/packages/constants.py +0 -11
- truss/templates/trtllm/packages/schema.py +0 -216
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/ensemble/config.pbtxt +0 -246
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/postprocessing/1/model.py +0 -181
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/postprocessing/config.pbtxt +0 -64
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/preprocessing/1/model.py +0 -260
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/preprocessing/config.pbtxt +0 -99
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/tensorrt_llm/config.pbtxt +0 -208
- truss/templates/trtllm/packages/triton_client.py +0 -150
- truss/templates/trtllm/packages/utils.py +0 -43
- truss/test_data/context_builder_image_test/test.py +0 -4
- truss/test_data/happy.ipynb +0 -54
- truss/test_data/model_load_failure_test/config.yaml +0 -2
- truss/test_data/test_concurrency_truss/config.yaml +0 -2
- truss/test_data/test_streaming_async_generator_truss/config.yaml +0 -2
- truss/test_data/test_streaming_truss/config.yaml +0 -3
- truss/test_data/test_truss/config.yaml +0 -2
- truss/tests/server/common/test_termination_handler_middleware.py +0 -93
- truss/tests/server/control/test_model_container_patch_applier.py +0 -203
- truss/tests/server/core/server/common/test_util.py +0 -19
- truss/tests/server/test_model_wrapper.py +0 -87
- truss/util/data_structures.py +0 -16
- truss-0.10.0rc1.dist-info/RECORD +0 -216
- truss-0.10.0rc1.dist-info/entry_points.txt +0 -3
- truss/{server/shared → base}/__init__.py +0 -0
- truss/{server → templates/control}/control/helpers/context_managers.py +0 -0
- truss/{server/control → templates/control/control/helpers}/errors.py +0 -0
- truss/{server/control/patch → templates/control/control/helpers/truss_patch}/__init__.py +0 -0
- truss/{server/control/patch → templates/control/control/helpers/truss_patch}/system_packages.py +0 -0
- truss/{test_data/annotated_types_truss/model → templates/server}/__init__.py +0 -0
- truss/{server → templates/server}/common/__init__.py +0 -0
- truss/{test_data/gcs_fix/model → templates/shared}/__init__.py +0 -0
- truss/templates/{trtllm → trtllm-briton}/README.md +0 -0
- truss/{test_data/server_conformance_test_truss/model → tests/test_data}/__init__.py +0 -0
- truss/{test_data/test_basic_truss/model → tests/test_data/annotated_types_truss}/__init__.py +0 -0
- truss/{test_data → tests/test_data}/annotated_types_truss/config.yaml +0 -0
- truss/{test_data/test_requirements_file_truss → tests/test_data/annotated_types_truss}/model/__init__.py +0 -0
- truss/{test_data → tests/test_data}/annotated_types_truss/model/model.py +0 -0
- truss/{test_data → tests/test_data}/auto-mpg.data +0 -0
- truss/{test_data → tests/test_data}/context_builder_image_test/Dockerfile +0 -0
- truss/{test_data/test_truss/model → tests/test_data/context_builder_image_test}/__init__.py +0 -0
- truss/{test_data/test_truss_server_caching_truss/model → tests/test_data/gcs_fix}/__init__.py +0 -0
- truss/{test_data → tests/test_data}/gcs_fix/config.yaml +0 -0
- truss/tests/{local → test_data/gcs_fix/model}/__init__.py +0 -0
- truss/{test_data → tests/test_data}/gcs_fix/model/model.py +0 -0
- truss/{test_data/test_truss/model/dummy → tests/test_data/model_load_failure_test/__init__.py} +0 -0
- truss/{test_data → tests/test_data}/model_load_failure_test/model/model.py +0 -0
- truss/{test_data → tests/test_data}/pima-indians-diabetes.csv +0 -0
- truss/{test_data → tests/test_data}/readme_int_example.md +0 -0
- truss/{test_data → tests/test_data}/readme_no_example.md +0 -0
- truss/{test_data → tests/test_data}/readme_str_example.md +0 -0
- truss/{test_data → tests/test_data}/server_conformance_test_truss/config.yaml +0 -0
- truss/{test_data → tests/test_data}/test_async_truss/config.yaml +0 -0
- truss/{test_data → tests/test_data}/test_async_truss/model/model.py +3 -3
- /truss/{test_data → tests/test_data}/test_basic_truss/model/model.py +0 -0
- /truss/{test_data → tests/test_data}/test_concurrency_truss/model/model.py +0 -0
- /truss/{test_data/test_requirements_file_truss → tests/test_data/test_pyantic_v1}/config.yaml +0 -0
- /truss/{test_data → tests/test_data}/test_requirements_file_truss/requirements.txt +0 -0
- /truss/{test_data → tests/test_data}/test_streaming_read_timeout/config.yaml +0 -0
- /truss/{test_data → tests/test_data}/test_streaming_read_timeout/model/model.py +0 -0
- /truss/{test_data → tests/test_data}/test_streaming_truss/model/model.py +0 -0
- /truss/{test_data → tests/test_data}/test_streaming_truss_with_error/config.yaml +0 -0
- /truss/{test_data → tests/test_data}/test_truss/examples.yaml +0 -0
- /truss/{test_data → tests/test_data}/test_truss/model/model.py +0 -0
- /truss/{test_data → tests/test_data}/test_truss/packages/test_package/test.py +0 -0
- /truss/{test_data → tests/test_data}/test_truss_server_caching_truss/config.yaml +0 -0
- /truss/{test_data → tests/test_data}/test_truss_server_caching_truss/model/model.py +0 -0
- /truss/{patch → truss_handle/patch}/constants.py +0 -0
- /truss/{notebook.py → util/notebook.py} +0 -0
- {truss-0.10.0rc1.dist-info → truss-0.60.0.dist-info}/LICENSE +0 -0
truss/tests/test_model_schema.py
CHANGED
|
@@ -4,9 +4,11 @@ from pathlib import Path
|
|
|
4
4
|
|
|
5
5
|
import pytest
|
|
6
6
|
import requests
|
|
7
|
+
|
|
8
|
+
from truss.templates.shared import serialization
|
|
7
9
|
from truss.tests.helpers import create_truss
|
|
8
10
|
from truss.tests.test_testing_utilities_for_other_tests import ensure_kill_all
|
|
9
|
-
from truss.truss_handle import TrussHandle
|
|
11
|
+
from truss.truss_handle.truss_handle import TrussHandle
|
|
10
12
|
|
|
11
13
|
DEFAULT_CONFIG = """model_name: test-truss"""
|
|
12
14
|
TRUSS_SERVER_ADDR = "http://localhost:8090"
|
|
@@ -15,10 +17,8 @@ SCHEMA_URL = f"{TRUSS_SERVER_ADDR}/v1/models/model/schema"
|
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
@pytest.mark.integration
|
|
18
|
-
def test_truss_with_no_annotations():
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
truss_dir = truss_root / "truss" / "test_data" / "test_basic_truss"
|
|
20
|
+
def test_truss_with_no_annotations(test_data_path):
|
|
21
|
+
truss_dir = test_data_path / "test_basic_truss"
|
|
22
22
|
|
|
23
23
|
tr = TrussHandle(truss_dir)
|
|
24
24
|
|
|
@@ -26,14 +26,14 @@ def test_truss_with_no_annotations():
|
|
|
26
26
|
_ = tr.docker_run(local_port=8090, detach=True, wait_for_server_ready=True)
|
|
27
27
|
|
|
28
28
|
response = requests.post(INFERENCE_URL, json={"prompt": "value"})
|
|
29
|
-
assert response.json() == {
|
|
30
|
-
"prompt": "value",
|
|
31
|
-
}
|
|
29
|
+
assert response.json() == {"prompt": "value"}
|
|
32
30
|
|
|
33
31
|
schema_response = requests.get(SCHEMA_URL)
|
|
34
32
|
assert schema_response.status_code == 404
|
|
35
33
|
|
|
36
34
|
assert schema_response.json()["error"] == "No schema found"
|
|
35
|
+
assert schema_response.headers["x-baseten-error-source"] == "04"
|
|
36
|
+
assert schema_response.headers["x-baseten-error-code"] == "600"
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
@pytest.mark.integration
|
|
@@ -57,8 +57,9 @@ class Model:
|
|
|
57
57
|
|
|
58
58
|
schema_response = requests.get(SCHEMA_URL)
|
|
59
59
|
assert schema_response.status_code == 404
|
|
60
|
-
|
|
61
60
|
assert schema_response.json()["error"] == "No schema found"
|
|
61
|
+
assert schema_response.headers["x-baseten-error-source"] == "04"
|
|
62
|
+
assert schema_response.headers["x-baseten-error-code"] == "600"
|
|
62
63
|
|
|
63
64
|
|
|
64
65
|
@pytest.mark.integration
|
|
@@ -92,40 +93,48 @@ class Model:
|
|
|
92
93
|
|
|
93
94
|
|
|
94
95
|
@pytest.mark.integration
|
|
95
|
-
def test_truss_with_annotated_inputs_outputs():
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
truss_dir = truss_root / "test_data" / "annotated_types_truss"
|
|
96
|
+
def test_truss_with_annotated_inputs_outputs(test_data_path):
|
|
97
|
+
truss_dir = test_data_path / "annotated_types_truss"
|
|
99
98
|
|
|
100
99
|
tr = TrussHandle(truss_dir)
|
|
101
100
|
|
|
102
101
|
with ensure_kill_all():
|
|
103
102
|
_ = tr.docker_run(local_port=8090, detach=True, wait_for_server_ready=True)
|
|
103
|
+
# Valid JSON input.
|
|
104
|
+
json_input = {"prompt": "value"}
|
|
105
|
+
response = requests.post(INFERENCE_URL, json=json_input)
|
|
106
|
+
assert response.json() == {"generated_text": "value"}
|
|
104
107
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
# Valid binary input.
|
|
109
|
+
byte_input = serialization.truss_msgpack_serialize(json_input)
|
|
110
|
+
print(byte_input)
|
|
111
|
+
response = requests.post(
|
|
112
|
+
INFERENCE_URL,
|
|
113
|
+
data=byte_input,
|
|
114
|
+
headers={"Content-Type": "application/octet-stream"},
|
|
115
|
+
)
|
|
116
|
+
assert response.content == b"\x81\xaegenerated_text\xa5value"
|
|
109
117
|
|
|
110
118
|
# An invalid input
|
|
111
|
-
|
|
112
119
|
response = requests.post(INFERENCE_URL, json={"bad_key": "value"})
|
|
113
|
-
|
|
114
120
|
assert response.status_code == 400
|
|
115
121
|
assert "error" in response.json()
|
|
116
|
-
assert
|
|
122
|
+
assert (
|
|
123
|
+
"Input Parsing Error:\n `prompt`: Field required."
|
|
124
|
+
in response.json()["error"]
|
|
125
|
+
)
|
|
126
|
+
assert response.headers["x-baseten-error-source"] == "04"
|
|
127
|
+
assert response.headers["x-baseten-error-code"] == "700"
|
|
117
128
|
|
|
129
|
+
# Schema response.
|
|
118
130
|
schema_response = requests.get(SCHEMA_URL)
|
|
119
|
-
|
|
120
131
|
schema = schema_response.json()
|
|
121
|
-
|
|
122
132
|
assert schema["input_schema"] == {
|
|
123
133
|
"properties": {"prompt": {"title": "Prompt", "type": "string"}},
|
|
124
134
|
"required": ["prompt"],
|
|
125
135
|
"title": "ModelInput",
|
|
126
136
|
"type": "object",
|
|
127
137
|
}
|
|
128
|
-
|
|
129
138
|
assert schema["output_schema"] == {
|
|
130
139
|
"properties": {
|
|
131
140
|
"generated_text": {"title": "Generated Text", "type": "string"}
|
|
@@ -442,9 +451,7 @@ class Model:
|
|
|
442
451
|
schema = schema_response.json()
|
|
443
452
|
|
|
444
453
|
assert schema["input_schema"] == {
|
|
445
|
-
"properties": {
|
|
446
|
-
"prompt": {"title": "Prompt", "type": "string"},
|
|
447
|
-
},
|
|
454
|
+
"properties": {"prompt": {"title": "Prompt", "type": "string"}},
|
|
448
455
|
"required": ["prompt"],
|
|
449
456
|
"title": "ModelInput",
|
|
450
457
|
"type": "object",
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# This file contains shared code to be used in other tests
|
|
2
2
|
# TODO(pankaj): Using a tests file for shared code is not ideal, we should
|
|
3
3
|
# move it to a regular file. This is a short term hack.
|
|
4
|
-
|
|
4
|
+
import json
|
|
5
|
+
import logging
|
|
5
6
|
import shutil
|
|
6
7
|
import subprocess
|
|
7
8
|
import time
|
|
8
9
|
from contextlib import contextmanager
|
|
9
10
|
|
|
10
|
-
from truss.
|
|
11
|
-
from truss.
|
|
12
|
-
from truss.docker import get_containers
|
|
11
|
+
from truss.base.constants import TRUSS
|
|
12
|
+
from truss.util.docker import get_containers, kill_all
|
|
13
13
|
|
|
14
14
|
DISK_SPACE_LOW_PERCENTAGE = 20
|
|
15
15
|
|
|
@@ -17,12 +17,57 @@ DISK_SPACE_LOW_PERCENTAGE = 20
|
|
|
17
17
|
@contextmanager
|
|
18
18
|
def ensure_kill_all():
|
|
19
19
|
try:
|
|
20
|
-
|
|
20
|
+
with _show_container_logs_if_raised():
|
|
21
|
+
yield
|
|
21
22
|
finally:
|
|
22
23
|
kill_all_with_retries()
|
|
23
24
|
ensure_free_disk_space()
|
|
24
25
|
|
|
25
26
|
|
|
27
|
+
def _human_readable_json_logs(raw_logs: str) -> str:
|
|
28
|
+
output = []
|
|
29
|
+
for line in raw_logs.splitlines():
|
|
30
|
+
try:
|
|
31
|
+
log_entry = json.loads(line)
|
|
32
|
+
human_readable_log = " ".join(
|
|
33
|
+
f"{key}: {value}" for key, value in log_entry.items()
|
|
34
|
+
)
|
|
35
|
+
output.append(f"\t{human_readable_log}")
|
|
36
|
+
except Exception:
|
|
37
|
+
output.append(line)
|
|
38
|
+
return "\n".join(output)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@contextmanager
|
|
42
|
+
def _show_container_logs_if_raised():
|
|
43
|
+
initial_ids = {c.id for c in get_containers({TRUSS: True})}
|
|
44
|
+
exception_raised = False
|
|
45
|
+
try:
|
|
46
|
+
yield
|
|
47
|
+
except Exception:
|
|
48
|
+
exception_raised = True
|
|
49
|
+
raise
|
|
50
|
+
finally:
|
|
51
|
+
if exception_raised:
|
|
52
|
+
print("An exception was raised, showing logs of all containers.")
|
|
53
|
+
containers = get_containers({TRUSS: True})
|
|
54
|
+
new_containers = [c for c in containers if c.id not in initial_ids]
|
|
55
|
+
parts = ["\n"]
|
|
56
|
+
for container in new_containers:
|
|
57
|
+
parts.append(f"Logs for container {container.name} ({container.id}):")
|
|
58
|
+
parts.append(_human_readable_json_logs(container.logs()))
|
|
59
|
+
parts.append("\n")
|
|
60
|
+
logging.warning("\n".join(parts))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def get_container_logs_from_prefix(prefix: str) -> str:
|
|
64
|
+
containers = get_containers({TRUSS: True})
|
|
65
|
+
for container in containers:
|
|
66
|
+
if container.name.startswith(prefix):
|
|
67
|
+
return _human_readable_json_logs(container.logs())
|
|
68
|
+
return ""
|
|
69
|
+
|
|
70
|
+
|
|
26
71
|
def kill_all_with_retries(num_retries: int = 10):
|
|
27
72
|
kill_all()
|
|
28
73
|
attempts = 0
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
from typing import List
|
|
3
3
|
|
|
4
|
-
from truss.patch.dir_signature import directory_content_signature
|
|
5
|
-
from truss.truss_gatherer import gather
|
|
4
|
+
from truss.truss_handle.patch.dir_signature import directory_content_signature
|
|
5
|
+
from truss.truss_handle.truss_gatherer import gather
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def test_gather(custom_model_with_external_package):
|
|
@@ -21,9 +21,7 @@ def test_gather(custom_model_with_external_package):
|
|
|
21
21
|
ext_pkg_top_module2.unlink()
|
|
22
22
|
|
|
23
23
|
assert _same_dir_content(
|
|
24
|
-
custom_model_with_external_package,
|
|
25
|
-
gathered_truss_path,
|
|
26
|
-
["config.yaml"],
|
|
24
|
+
custom_model_with_external_package, gathered_truss_path, ["config.yaml"]
|
|
27
25
|
)
|
|
28
26
|
|
|
29
27
|
|
truss/tests/test_truss_handle.py
CHANGED
|
@@ -7,16 +7,24 @@ import pytest
|
|
|
7
7
|
import requests
|
|
8
8
|
from python_on_whales.exceptions import DockerException
|
|
9
9
|
from tenacity import RetryError
|
|
10
|
-
|
|
11
|
-
from truss.
|
|
10
|
+
|
|
11
|
+
from truss.base.custom_types import Example
|
|
12
|
+
from truss.base.errors import ContainerIsDownError, ContainerNotFoundError
|
|
13
|
+
from truss.base.truss_config import map_local_to_supported_python_version
|
|
12
14
|
from truss.local.local_config_handler import LocalConfigHandler
|
|
13
|
-
from truss.
|
|
15
|
+
from truss.templates.control.control.helpers.custom_types import (
|
|
16
|
+
Action,
|
|
17
|
+
ModelCodePatch,
|
|
18
|
+
Patch,
|
|
19
|
+
PatchType,
|
|
20
|
+
)
|
|
14
21
|
from truss.tests.test_testing_utilities_for_other_tests import (
|
|
15
22
|
ensure_kill_all,
|
|
16
23
|
kill_all_with_retries,
|
|
17
24
|
)
|
|
18
|
-
from truss.truss_handle import
|
|
19
|
-
from truss.
|
|
25
|
+
from truss.truss_handle.patch.custom_types import PatchRequest
|
|
26
|
+
from truss.truss_handle.truss_handle import TrussHandle, wait_for_truss
|
|
27
|
+
from truss.util.docker import Docker, DockerStates
|
|
20
28
|
|
|
21
29
|
|
|
22
30
|
def test_spec(custom_model_truss_dir_with_pre_and_post):
|
|
@@ -51,16 +59,18 @@ def test_server_predict(custom_model_truss_dir_with_pre_and_post):
|
|
|
51
59
|
assert resp == {"predictions": [4, 5, 6, 7]}
|
|
52
60
|
|
|
53
61
|
|
|
54
|
-
def test_readme_generation_int_example(
|
|
62
|
+
def test_readme_generation_int_example(
|
|
63
|
+
test_data_path, custom_model_truss_dir_with_pre_and_post
|
|
64
|
+
):
|
|
55
65
|
th = TrussHandle(custom_model_truss_dir_with_pre_and_post)
|
|
56
66
|
readme_contents = th.generate_readme()
|
|
57
67
|
readme_contents = readme_contents.replace("\n", "")
|
|
58
|
-
correct_readme_contents = _read_readme("readme_int_example.md")
|
|
68
|
+
correct_readme_contents = _read_readme(test_data_path / "readme_int_example.md")
|
|
59
69
|
assert readme_contents == correct_readme_contents
|
|
60
70
|
|
|
61
71
|
|
|
62
72
|
def test_readme_generation_no_example(
|
|
63
|
-
custom_model_truss_dir_with_pre_and_post_no_example
|
|
73
|
+
test_data_path, custom_model_truss_dir_with_pre_and_post_no_example
|
|
64
74
|
):
|
|
65
75
|
th = TrussHandle(custom_model_truss_dir_with_pre_and_post_no_example)
|
|
66
76
|
if os.path.exists(th._spec.examples_path):
|
|
@@ -68,17 +78,17 @@ def test_readme_generation_no_example(
|
|
|
68
78
|
os.remove(th._spec.examples_path)
|
|
69
79
|
readme_contents = th.generate_readme()
|
|
70
80
|
readme_contents = readme_contents.replace("\n", "")
|
|
71
|
-
correct_readme_contents = _read_readme("readme_no_example.md")
|
|
81
|
+
correct_readme_contents = _read_readme(test_data_path / "readme_no_example.md")
|
|
72
82
|
assert readme_contents == correct_readme_contents
|
|
73
83
|
|
|
74
84
|
|
|
75
85
|
def test_readme_generation_str_example(
|
|
76
|
-
custom_model_truss_dir_with_pre_and_post_str_example
|
|
86
|
+
test_data_path, custom_model_truss_dir_with_pre_and_post_str_example
|
|
77
87
|
):
|
|
78
88
|
th = TrussHandle(custom_model_truss_dir_with_pre_and_post_str_example)
|
|
79
89
|
readme_contents = th.generate_readme()
|
|
80
90
|
readme_contents = readme_contents.replace("\n", "")
|
|
81
|
-
correct_readme_contents = _read_readme("readme_str_example.md")
|
|
91
|
+
correct_readme_contents = _read_readme(test_data_path / "readme_str_example.md")
|
|
82
92
|
assert readme_contents == correct_readme_contents
|
|
83
93
|
|
|
84
94
|
|
|
@@ -96,6 +106,7 @@ def test_build_docker_image(custom_model_truss_dir_with_pre_and_post):
|
|
|
96
106
|
[
|
|
97
107
|
("baseten/truss-server-base:3.9-v0.4.8rc4", "/usr/local/bin/python3", False),
|
|
98
108
|
("python:3.8", "/usr/local/bin/python3", False),
|
|
109
|
+
("python:3.10", "/usr/local/bin/python3", False),
|
|
99
110
|
("python:3.11", "/usr/local/bin/python3", False),
|
|
100
111
|
("python:alpine", "/usr/local/bin/python3", True),
|
|
101
112
|
("python:2.7-slim", "/usr/local/bin/python", True),
|
|
@@ -389,15 +400,10 @@ def test_enable_gpu(custom_model_truss_dir_with_pre_and_post):
|
|
|
389
400
|
|
|
390
401
|
@pytest.mark.parametrize(
|
|
391
402
|
"python_version, expected_python_version",
|
|
392
|
-
[
|
|
393
|
-
("3.8", "py38"),
|
|
394
|
-
("py38", "py38"),
|
|
395
|
-
],
|
|
403
|
+
[("3.8", "py38"), ("py38", "py38"), ("3.9", "py39"), ("py39", "py39")],
|
|
396
404
|
)
|
|
397
405
|
def test_update_python_version(
|
|
398
|
-
python_version,
|
|
399
|
-
expected_python_version,
|
|
400
|
-
custom_model_truss_dir_with_pre_and_post,
|
|
406
|
+
python_version, expected_python_version, custom_model_truss_dir_with_pre_and_post
|
|
401
407
|
):
|
|
402
408
|
th = TrussHandle(custom_model_truss_dir_with_pre_and_post)
|
|
403
409
|
th.update_python_version(python_version)
|
|
@@ -406,10 +412,7 @@ def test_update_python_version(
|
|
|
406
412
|
|
|
407
413
|
def test_update_requirements(custom_model_truss_dir_with_pre_and_post):
|
|
408
414
|
th = TrussHandle(custom_model_truss_dir_with_pre_and_post)
|
|
409
|
-
requirements = [
|
|
410
|
-
"tensorflow==2.3.1",
|
|
411
|
-
"uvicorn==0.12.2",
|
|
412
|
-
]
|
|
415
|
+
requirements = ["tensorflow==2.3.1", "uvicorn==0.12.2"]
|
|
413
416
|
th.update_requirements(requirements)
|
|
414
417
|
sc_requirements = th.spec.requirements
|
|
415
418
|
assert sc_requirements == requirements
|
|
@@ -425,10 +428,7 @@ def test_update_requirements_from_file(
|
|
|
425
428
|
" # this is comment with a big space. Please don't add.",
|
|
426
429
|
"uvicorn==0.12.2",
|
|
427
430
|
]
|
|
428
|
-
allowed_requirements = [
|
|
429
|
-
"tensorflow==2.3.1",
|
|
430
|
-
"uvicorn==0.12.2",
|
|
431
|
-
]
|
|
431
|
+
allowed_requirements = ["tensorflow==2.3.1", "uvicorn==0.12.2"]
|
|
432
432
|
req_file_path = tmp_path / "requirements.txt"
|
|
433
433
|
with req_file_path.open("w") as req_file:
|
|
434
434
|
for req in file_requirements:
|
|
@@ -450,6 +450,25 @@ def test_add_environment_variable(custom_model_truss_dir_with_pre_and_post):
|
|
|
450
450
|
Docker.client().kill(container)
|
|
451
451
|
|
|
452
452
|
|
|
453
|
+
@pytest.mark.integration
|
|
454
|
+
def test_build_commands(test_data_path):
|
|
455
|
+
truss_dir = test_data_path / "test_build_commands"
|
|
456
|
+
tr = TrussHandle(truss_dir)
|
|
457
|
+
with ensure_kill_all():
|
|
458
|
+
r1 = tr.docker_predict([1, 2])
|
|
459
|
+
assert r1 == {"predictions": [1, 2]}
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
@pytest.mark.integration
|
|
463
|
+
def test_build_commands_failure(test_data_path):
|
|
464
|
+
truss_dir = test_data_path / "test_build_commands_failure"
|
|
465
|
+
tr = TrussHandle(truss_dir)
|
|
466
|
+
try:
|
|
467
|
+
tr.docker_run(local_port=8090, detach=True, wait_for_server_ready=True)
|
|
468
|
+
except DockerException as exc:
|
|
469
|
+
assert "It returned with code 1" in str(exc)
|
|
470
|
+
|
|
471
|
+
|
|
453
472
|
def test_add_data_file(custom_model_truss_dir_with_pre_and_post, tmp_path):
|
|
454
473
|
th = TrussHandle(custom_model_truss_dir_with_pre_and_post)
|
|
455
474
|
data_filepath = tmp_path / "test_data.txt"
|
|
@@ -513,18 +532,13 @@ def test_add_example_new(custom_model_truss_dir_with_pre_and_post):
|
|
|
513
532
|
th = TrussHandle(custom_model_truss_dir_with_pre_and_post)
|
|
514
533
|
orig_examples = th.examples()
|
|
515
534
|
th.add_example("example2", [[1]])
|
|
516
|
-
assert th.examples() == [
|
|
517
|
-
*orig_examples,
|
|
518
|
-
Example("example2", [[1]]),
|
|
519
|
-
]
|
|
535
|
+
assert th.examples() == [*orig_examples, Example("example2", [[1]])]
|
|
520
536
|
|
|
521
537
|
|
|
522
538
|
def test_add_example_update(custom_model_truss_dir_with_pre_and_post):
|
|
523
539
|
th = TrussHandle(custom_model_truss_dir_with_pre_and_post)
|
|
524
540
|
th.add_example("example1", [[1]])
|
|
525
|
-
assert th.examples() == [
|
|
526
|
-
Example("example1", [[1]]),
|
|
527
|
-
]
|
|
541
|
+
assert th.examples() == [Example("example1", [[1]])]
|
|
528
542
|
|
|
529
543
|
|
|
530
544
|
def test_model_without_pre_post(custom_model_truss_dir):
|
|
@@ -562,11 +576,9 @@ class Model:
|
|
|
562
576
|
Patch(
|
|
563
577
|
type=PatchType.MODEL_CODE,
|
|
564
578
|
body=ModelCodePatch(
|
|
565
|
-
action=Action.UPDATE,
|
|
566
|
-
path="model.py",
|
|
567
|
-
content=new_model_code,
|
|
579
|
+
action=Action.UPDATE, path="model.py", content=new_model_code
|
|
568
580
|
),
|
|
569
|
-
)
|
|
581
|
+
)
|
|
570
582
|
],
|
|
571
583
|
)
|
|
572
584
|
|
|
@@ -604,10 +616,9 @@ class Model:
|
|
|
604
616
|
assert len(th.get_all_docker_images()) == orig_num_truss_images + 1
|
|
605
617
|
|
|
606
618
|
|
|
607
|
-
@patch("truss.truss_handle.directory_content_hash")
|
|
619
|
+
@patch("truss.truss_handle.truss_handle.directory_content_hash")
|
|
608
620
|
def test_truss_hash_caching_based_on_max_mod_time(
|
|
609
|
-
directory_content_patcher,
|
|
610
|
-
custom_model_truss_dir,
|
|
621
|
+
directory_content_patcher, custom_model_truss_dir
|
|
611
622
|
):
|
|
612
623
|
directory_content_patcher.return_value = "mock_hash"
|
|
613
624
|
th = TrussHandle(custom_model_truss_dir)
|
|
@@ -623,14 +634,14 @@ def test_truss_hash_caching_based_on_max_mod_time(
|
|
|
623
634
|
directory_content_patcher.call_count == 2
|
|
624
635
|
|
|
625
636
|
|
|
626
|
-
@patch("truss.truss_handle.get_container_state")
|
|
637
|
+
@patch("truss.truss_handle.truss_handle.get_container_state")
|
|
627
638
|
def test_container_oom_caught_during_waiting(container_state_mock):
|
|
628
639
|
container_state_mock.return_value = DockerStates.OOMKILLED
|
|
629
640
|
with pytest.raises(ContainerIsDownError):
|
|
630
641
|
wait_for_truss(url="localhost:8000", container=MagicMock())
|
|
631
642
|
|
|
632
643
|
|
|
633
|
-
@patch("truss.truss_handle.get_container_state")
|
|
644
|
+
@patch("truss.truss_handle.truss_handle.get_container_state")
|
|
634
645
|
@pytest.mark.integration
|
|
635
646
|
def test_container_stuck_in_created(container_state_mock):
|
|
636
647
|
container_state_mock.return_value = DockerStates.CREATED
|
|
@@ -674,10 +685,7 @@ class Model:
|
|
|
674
685
|
@pytest.mark.integration
|
|
675
686
|
@pytest.mark.parametrize(
|
|
676
687
|
"patch_path, expected_call_count",
|
|
677
|
-
[
|
|
678
|
-
("hash_is_current", 1),
|
|
679
|
-
("hash_is_current_but_only_every_third_call_succeeds", 3),
|
|
680
|
-
],
|
|
688
|
+
[("hash_is_current", 1), ("hash_is_current_but_only_every_third_call_succeeds", 3)],
|
|
681
689
|
)
|
|
682
690
|
def test_patch_ping_flow(
|
|
683
691
|
patch_path, expected_call_count, custom_model_control, patch_ping_test_server
|
|
@@ -687,11 +695,7 @@ def test_patch_ping_flow(
|
|
|
687
695
|
th = TrussHandle(custom_model_control)
|
|
688
696
|
tag = "test-docker-custom-model-control-tag:0.0.1"
|
|
689
697
|
with ensure_kill_all():
|
|
690
|
-
result = th.docker_predict(
|
|
691
|
-
[1],
|
|
692
|
-
tag=tag,
|
|
693
|
-
patch_ping_url=patch_ping_url,
|
|
694
|
-
)
|
|
698
|
+
result = th.docker_predict([1], tag=tag, patch_ping_url=patch_ping_url)
|
|
695
699
|
assert result == [1]
|
|
696
700
|
|
|
697
701
|
# Make sure the patch ping url was actually hit
|
|
@@ -775,28 +779,27 @@ def verify_python_requirement_not_installed_on_container(container, req: str):
|
|
|
775
779
|
|
|
776
780
|
|
|
777
781
|
def verify_environment_variable_on_container(
|
|
778
|
-
container,
|
|
779
|
-
env_var_name: str,
|
|
780
|
-
env_var_value: str,
|
|
782
|
+
container, env_var_name: str, env_var_value: str
|
|
781
783
|
):
|
|
782
784
|
resp = container.execute(["env"])
|
|
783
785
|
needle = f"{env_var_name}={env_var_value}"
|
|
784
786
|
assert needle in resp.splitlines()
|
|
785
787
|
|
|
786
788
|
|
|
787
|
-
def _read_readme(
|
|
788
|
-
readme_correct_path
|
|
789
|
-
readme_contents = readme_correct_path.open().read().replace("\n", "")
|
|
790
|
-
return readme_contents
|
|
789
|
+
def _read_readme(readme_correct_path: Path) -> str:
|
|
790
|
+
return readme_correct_path.open().read().replace("\n", "")
|
|
791
791
|
|
|
792
792
|
|
|
793
793
|
def generate_default_config():
|
|
794
|
+
# The test fixture varies with host version.
|
|
795
|
+
python_version = map_local_to_supported_python_version()
|
|
794
796
|
config = {
|
|
797
|
+
"build_commands": [],
|
|
795
798
|
"environment_variables": {},
|
|
796
799
|
"external_package_dirs": [],
|
|
797
800
|
"model_metadata": {},
|
|
798
801
|
"model_name": None,
|
|
799
|
-
"python_version":
|
|
802
|
+
"python_version": python_version,
|
|
800
803
|
"requirements": [],
|
|
801
804
|
"resources": {
|
|
802
805
|
"accelerator": None,
|
truss/tests/test_util.py
CHANGED
|
@@ -2,7 +2,8 @@ import os
|
|
|
2
2
|
from unittest.mock import patch
|
|
3
3
|
|
|
4
4
|
import requests_mock
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
from truss.base.truss_config import ExternalData
|
|
6
7
|
from truss.util.download import download_external_data
|
|
7
8
|
|
|
8
9
|
TEST_DOWNLOAD_URL = "http://example.com/some-download-url"
|
truss/tests/test_validation.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import pytest
|
|
2
|
-
|
|
3
|
-
from truss.
|
|
2
|
+
|
|
3
|
+
from truss.base.errors import ValidationError
|
|
4
|
+
from truss.base.validation import (
|
|
4
5
|
validate_cpu_spec,
|
|
5
6
|
validate_memory_spec,
|
|
6
7
|
validate_secret_name,
|
|
@@ -64,21 +65,22 @@ def test_validate_cpu_spec(cpu_spec, expected_valid):
|
|
|
64
65
|
|
|
65
66
|
|
|
66
67
|
@pytest.mark.parametrize(
|
|
67
|
-
"mem_spec, expected_valid",
|
|
68
|
+
"mem_spec, expected_valid, memory_in_bytes",
|
|
68
69
|
[
|
|
69
|
-
(None, False),
|
|
70
|
-
(1, False),
|
|
71
|
-
("1m", False),
|
|
72
|
-
("1k", True),
|
|
73
|
-
("512k", True),
|
|
74
|
-
("512M", True),
|
|
75
|
-
("1.5Gi", True),
|
|
76
|
-
("abc", False),
|
|
70
|
+
(None, False, None),
|
|
71
|
+
(1, False, None),
|
|
72
|
+
("1m", False, None),
|
|
73
|
+
("1k", True, 10**3),
|
|
74
|
+
("512k", True, 512 * 10**3),
|
|
75
|
+
("512M", True, 512 * 10**6),
|
|
76
|
+
("1.5Gi", True, 1.5 * 1024**3),
|
|
77
|
+
("abc", False, None),
|
|
78
|
+
("1024", True, 1024),
|
|
77
79
|
],
|
|
78
80
|
)
|
|
79
|
-
def test_validate_mem_spec(mem_spec, expected_valid):
|
|
81
|
+
def test_validate_mem_spec(mem_spec, expected_valid, memory_in_bytes):
|
|
80
82
|
if not expected_valid:
|
|
81
83
|
with pytest.raises(ValidationError):
|
|
82
84
|
validate_memory_spec(mem_spec)
|
|
83
85
|
else:
|
|
84
|
-
validate_memory_spec(mem_spec)
|
|
86
|
+
assert memory_in_bytes == validate_memory_spec(mem_spec)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from truss.base.trt_llm_config import (
|
|
2
|
+
TRTLLMConfiguration,
|
|
3
|
+
TrussTRTLLMBatchSchedulerPolicy,
|
|
4
|
+
TrussTRTLLMBuildConfiguration,
|
|
5
|
+
TrussTRTLLMRuntimeConfiguration,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_trt_llm_config_init_from_pydantic_models(trtllm_config):
|
|
10
|
+
build_config = TrussTRTLLMBuildConfiguration(**trtllm_config["trt_llm"]["build"])
|
|
11
|
+
TRTLLMConfiguration(build=build_config, runtime=TrussTRTLLMRuntimeConfiguration())
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_trt_llm_configuration_init_and_migrate_deprecated_runtime_fields(
|
|
15
|
+
deprecated_trtllm_config,
|
|
16
|
+
):
|
|
17
|
+
trt_llm_config = TRTLLMConfiguration(**deprecated_trtllm_config["trt_llm"])
|
|
18
|
+
assert trt_llm_config.runtime.model_dump() == {
|
|
19
|
+
"kv_cache_free_gpu_mem_fraction": 0.1,
|
|
20
|
+
"kv_cache_host_memory_bytes": None,
|
|
21
|
+
"enable_chunked_context": True,
|
|
22
|
+
"batch_scheduler_policy": TrussTRTLLMBatchSchedulerPolicy.MAX_UTILIZATION.value,
|
|
23
|
+
"request_default_max_tokens": 10,
|
|
24
|
+
"total_token_limit": 50,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_trt_llm_configuration_init_and_migrate_deprecated_runtime_fields_existing_runtime(
|
|
29
|
+
deprecated_trtllm_config_with_runtime_existing,
|
|
30
|
+
):
|
|
31
|
+
trt_llm_config = TRTLLMConfiguration(
|
|
32
|
+
**deprecated_trtllm_config_with_runtime_existing["trt_llm"]
|
|
33
|
+
)
|
|
34
|
+
assert trt_llm_config.runtime.model_dump() == {
|
|
35
|
+
"kv_cache_free_gpu_mem_fraction": 0.1,
|
|
36
|
+
"kv_cache_host_memory_bytes": None,
|
|
37
|
+
"enable_chunked_context": True,
|
|
38
|
+
"batch_scheduler_policy": TrussTRTLLMBatchSchedulerPolicy.MAX_UTILIZATION.value,
|
|
39
|
+
"request_default_max_tokens": 10,
|
|
40
|
+
"total_token_limit": 100,
|
|
41
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from truss.base.errors import ValidationError
|
|
3
|
+
from truss.base.truss_spec import TrussSpec
|
|
4
|
+
from truss.trt_llm.validation import _verify_has_class_init_arg, validate
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@pytest.mark.parametrize(
|
|
8
|
+
"src, class_name, expected_arg, expected_to_raise",
|
|
9
|
+
[
|
|
10
|
+
(
|
|
11
|
+
"""
|
|
12
|
+
class Model:
|
|
13
|
+
def __init__(self, foo):
|
|
14
|
+
pass
|
|
15
|
+
""",
|
|
16
|
+
"Model",
|
|
17
|
+
"foo",
|
|
18
|
+
False,
|
|
19
|
+
),
|
|
20
|
+
# Missing arg
|
|
21
|
+
(
|
|
22
|
+
"""
|
|
23
|
+
class Model:
|
|
24
|
+
def __init__(self, foo):
|
|
25
|
+
pass
|
|
26
|
+
""",
|
|
27
|
+
"Model",
|
|
28
|
+
"bar",
|
|
29
|
+
True,
|
|
30
|
+
),
|
|
31
|
+
# Missing class
|
|
32
|
+
(
|
|
33
|
+
"""
|
|
34
|
+
class Model:
|
|
35
|
+
def __init__(self, foo):
|
|
36
|
+
pass
|
|
37
|
+
""",
|
|
38
|
+
"Missing",
|
|
39
|
+
"bar",
|
|
40
|
+
True,
|
|
41
|
+
),
|
|
42
|
+
# With default value should still work
|
|
43
|
+
(
|
|
44
|
+
"""
|
|
45
|
+
class Model:
|
|
46
|
+
def __init__(self, foo=None):
|
|
47
|
+
pass
|
|
48
|
+
""",
|
|
49
|
+
"Model",
|
|
50
|
+
"foo",
|
|
51
|
+
False,
|
|
52
|
+
),
|
|
53
|
+
# not the only arg
|
|
54
|
+
(
|
|
55
|
+
"""
|
|
56
|
+
class Model:
|
|
57
|
+
def __init__(self, first, foo, third):
|
|
58
|
+
pass
|
|
59
|
+
""",
|
|
60
|
+
"Model",
|
|
61
|
+
"foo",
|
|
62
|
+
False,
|
|
63
|
+
),
|
|
64
|
+
],
|
|
65
|
+
)
|
|
66
|
+
def test_has_class_init_arg(src, expected_arg, class_name, expected_to_raise):
|
|
67
|
+
if expected_to_raise:
|
|
68
|
+
with pytest.raises(ValidationError):
|
|
69
|
+
_verify_has_class_init_arg(src, class_name, expected_arg)
|
|
70
|
+
else:
|
|
71
|
+
_verify_has_class_init_arg(src, class_name, expected_arg)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def test_validate(custom_model_trt_llm):
|
|
75
|
+
spec = TrussSpec(custom_model_trt_llm)
|
|
76
|
+
validate(spec)
|
|
77
|
+
|
|
78
|
+
# overwrite with model code that doesn't take trt_llm as input
|
|
79
|
+
override_model_code_invalid = """
|
|
80
|
+
class Model:
|
|
81
|
+
def __init__(self):
|
|
82
|
+
pass
|
|
83
|
+
"""
|
|
84
|
+
spec.model_class_filepath.write_text(override_model_code_invalid)
|
|
85
|
+
new_spec = TrussSpec(custom_model_trt_llm)
|
|
86
|
+
with pytest.raises(ValidationError):
|
|
87
|
+
validate(new_spec)
|
|
88
|
+
|
|
89
|
+
# If model class file is removed, it should be ok
|
|
90
|
+
spec.model_class_filepath.unlink()
|
|
91
|
+
validate(new_spec)
|