truss 0.10.0rc1__py3-none-any.whl → 0.60.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of truss might be problematic. Click here for more details.
- truss/__init__.py +10 -3
- truss/api/__init__.py +123 -0
- truss/api/definitions.py +51 -0
- truss/base/constants.py +116 -0
- truss/base/custom_types.py +29 -0
- truss/{errors.py → base/errors.py} +4 -0
- truss/base/trt_llm_config.py +310 -0
- truss/{truss_config.py → base/truss_config.py} +344 -31
- truss/{truss_spec.py → base/truss_spec.py} +20 -6
- truss/{validation.py → base/validation.py} +60 -11
- truss/cli/cli.py +841 -88
- truss/{remote → cli}/remote_cli.py +2 -7
- truss/contexts/docker_build_setup.py +67 -0
- truss/contexts/image_builder/cache_warmer.py +2 -8
- truss/contexts/image_builder/image_builder.py +1 -1
- truss/contexts/image_builder/serving_image_builder.py +292 -46
- truss/contexts/image_builder/util.py +1 -3
- truss/contexts/local_loader/docker_build_emulator.py +58 -0
- truss/contexts/local_loader/load_model_local.py +2 -2
- truss/contexts/local_loader/truss_module_loader.py +1 -1
- truss/contexts/local_loader/utils.py +1 -1
- truss/local/local_config.py +2 -6
- truss/local/local_config_handler.py +20 -5
- truss/patch/__init__.py +1 -0
- truss/patch/hash.py +4 -70
- truss/patch/signature.py +4 -16
- truss/patch/truss_dir_patch_applier.py +3 -78
- truss/remote/baseten/api.py +308 -23
- truss/remote/baseten/auth.py +3 -3
- truss/remote/baseten/core.py +257 -50
- truss/remote/baseten/custom_types.py +44 -0
- truss/remote/baseten/error.py +4 -0
- truss/remote/baseten/remote.py +369 -118
- truss/remote/baseten/service.py +118 -11
- truss/remote/baseten/utils/status.py +29 -0
- truss/remote/baseten/utils/tar.py +34 -22
- truss/remote/baseten/utils/transfer.py +36 -23
- truss/remote/remote_factory.py +14 -5
- truss/remote/truss_remote.py +72 -45
- truss/templates/base.Dockerfile.jinja +18 -16
- truss/templates/cache.Dockerfile.jinja +3 -3
- truss/{server → templates/control}/control/application.py +14 -35
- truss/{server → templates/control}/control/endpoints.py +39 -9
- truss/{server/control/patch/types.py → templates/control/control/helpers/custom_types.py} +13 -52
- truss/{server → templates/control}/control/helpers/inference_server_controller.py +4 -8
- truss/{server → templates/control}/control/helpers/inference_server_process_controller.py +2 -4
- truss/{server → templates/control}/control/helpers/inference_server_starter.py +5 -10
- truss/{server/control → templates/control/control/helpers}/truss_patch/model_code_patch_applier.py +8 -6
- truss/{server/control/patch → templates/control/control/helpers/truss_patch}/model_container_patch_applier.py +18 -26
- truss/templates/control/control/helpers/truss_patch/requirement_name_identifier.py +66 -0
- truss/{server → templates/control}/control/server.py +11 -6
- truss/templates/control/requirements.txt +9 -0
- truss/templates/custom_python_dx/my_model.py +28 -0
- truss/templates/docker_server/proxy.conf.jinja +42 -0
- truss/templates/docker_server/supervisord.conf.jinja +27 -0
- truss/templates/docker_server_requirements.txt +1 -0
- truss/templates/server/common/errors.py +231 -0
- truss/{server → templates/server}/common/patches/whisper/patch.py +1 -0
- truss/{server/common/patches/__init__.py → templates/server/common/patches.py} +1 -3
- truss/{server → templates/server}/common/retry.py +1 -0
- truss/{server → templates/server}/common/schema.py +11 -9
- truss/templates/server/common/tracing.py +157 -0
- truss/templates/server/main.py +9 -0
- truss/templates/server/model_wrapper.py +961 -0
- truss/templates/server/requirements.txt +21 -0
- truss/templates/server/truss_server.py +447 -0
- truss/templates/server.Dockerfile.jinja +62 -14
- truss/templates/shared/dynamic_config_resolver.py +28 -0
- truss/templates/shared/lazy_data_resolver.py +164 -0
- truss/templates/shared/log_config.py +125 -0
- truss/{server → templates}/shared/secrets_resolver.py +1 -2
- truss/{server → templates}/shared/serialization.py +31 -9
- truss/{server → templates}/shared/util.py +3 -13
- truss/templates/trtllm-audio/model/model.py +49 -0
- truss/templates/trtllm-audio/packages/sigint_patch.py +14 -0
- truss/templates/trtllm-audio/packages/whisper_trt/__init__.py +215 -0
- truss/templates/trtllm-audio/packages/whisper_trt/assets.py +25 -0
- truss/templates/trtllm-audio/packages/whisper_trt/batching.py +52 -0
- truss/templates/trtllm-audio/packages/whisper_trt/custom_types.py +26 -0
- truss/templates/trtllm-audio/packages/whisper_trt/modeling.py +184 -0
- truss/templates/trtllm-audio/packages/whisper_trt/tokenizer.py +185 -0
- truss/templates/trtllm-audio/packages/whisper_trt/utils.py +245 -0
- truss/templates/trtllm-briton/src/extension.py +64 -0
- truss/tests/conftest.py +302 -94
- truss/tests/contexts/image_builder/test_serving_image_builder.py +74 -31
- truss/tests/contexts/local_loader/test_load_local.py +2 -2
- truss/tests/contexts/local_loader/test_truss_module_finder.py +1 -1
- truss/tests/patch/test_calc_patch.py +439 -127
- truss/tests/patch/test_dir_signature.py +3 -12
- truss/tests/patch/test_hash.py +1 -1
- truss/tests/patch/test_signature.py +1 -1
- truss/tests/patch/test_truss_dir_patch_applier.py +23 -11
- truss/tests/patch/test_types.py +2 -2
- truss/tests/remote/baseten/test_api.py +153 -58
- truss/tests/remote/baseten/test_auth.py +2 -1
- truss/tests/remote/baseten/test_core.py +160 -12
- truss/tests/remote/baseten/test_remote.py +489 -77
- truss/tests/remote/baseten/test_service.py +55 -0
- truss/tests/remote/test_remote_factory.py +16 -18
- truss/tests/remote/test_truss_remote.py +26 -17
- truss/tests/templates/control/control/helpers/test_context_managers.py +11 -0
- truss/tests/templates/control/control/helpers/test_model_container_patch_applier.py +184 -0
- truss/tests/templates/control/control/helpers/test_requirement_name_identifier.py +89 -0
- truss/tests/{server → templates/control}/control/test_server.py +79 -24
- truss/tests/{server → templates/control}/control/test_server_integration.py +24 -16
- truss/tests/templates/core/server/test_dynamic_config_resolver.py +108 -0
- truss/tests/templates/core/server/test_lazy_data_resolver.py +329 -0
- truss/tests/templates/core/server/test_lazy_data_resolver_v2.py +79 -0
- truss/tests/{server → templates}/core/server/test_secrets_resolver.py +1 -1
- truss/tests/{server → templates/server}/common/test_retry.py +3 -3
- truss/tests/templates/server/test_model_wrapper.py +248 -0
- truss/tests/{server → templates/server}/test_schema.py +3 -5
- truss/tests/{server/core/server/common → templates/server}/test_truss_server.py +8 -5
- truss/tests/test_build.py +9 -52
- truss/tests/test_config.py +336 -77
- truss/tests/test_context_builder_image.py +3 -11
- truss/tests/test_control_truss_patching.py +7 -12
- truss/tests/test_custom_server.py +38 -0
- truss/tests/test_data/context_builder_image_test/test.py +3 -0
- truss/tests/test_data/happy.ipynb +56 -0
- truss/tests/test_data/model_load_failure_test/config.yaml +2 -0
- truss/tests/test_data/model_load_failure_test/model/__init__.py +0 -0
- truss/tests/test_data/patch_ping_test_server/__init__.py +0 -0
- truss/{test_data → tests/test_data}/patch_ping_test_server/app.py +3 -9
- truss/{test_data → tests/test_data}/server.Dockerfile +20 -21
- truss/tests/test_data/server_conformance_test_truss/__init__.py +0 -0
- truss/tests/test_data/server_conformance_test_truss/model/__init__.py +0 -0
- truss/{test_data → tests/test_data}/server_conformance_test_truss/model/model.py +1 -3
- truss/tests/test_data/test_async_truss/__init__.py +0 -0
- truss/tests/test_data/test_async_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_basic_truss/__init__.py +0 -0
- truss/tests/test_data/test_basic_truss/config.yaml +16 -0
- truss/tests/test_data/test_basic_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_build_commands/__init__.py +0 -0
- truss/tests/test_data/test_build_commands/config.yaml +13 -0
- truss/tests/test_data/test_build_commands/model/__init__.py +0 -0
- truss/{test_data/test_streaming_async_generator_truss → tests/test_data/test_build_commands}/model/model.py +2 -3
- truss/tests/test_data/test_build_commands_failure/__init__.py +0 -0
- truss/tests/test_data/test_build_commands_failure/config.yaml +14 -0
- truss/tests/test_data/test_build_commands_failure/model/__init__.py +0 -0
- truss/tests/test_data/test_build_commands_failure/model/model.py +17 -0
- truss/tests/test_data/test_concurrency_truss/__init__.py +0 -0
- truss/tests/test_data/test_concurrency_truss/config.yaml +4 -0
- truss/tests/test_data/test_concurrency_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_custom_server_truss/__init__.py +0 -0
- truss/tests/test_data/test_custom_server_truss/config.yaml +20 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/Dockerfile +17 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/README.md +10 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/VERSION +1 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/__init__.py +0 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/app.py +19 -0
- truss/tests/test_data/test_custom_server_truss/test_docker_image/build_upload_new_image.sh +6 -0
- truss/tests/test_data/test_openai/__init__.py +0 -0
- truss/{test_data/test_basic_truss → tests/test_data/test_openai}/config.yaml +1 -2
- truss/tests/test_data/test_openai/model/__init__.py +0 -0
- truss/tests/test_data/test_openai/model/model.py +15 -0
- truss/tests/test_data/test_pyantic_v1/__init__.py +0 -0
- truss/tests/test_data/test_pyantic_v1/model/__init__.py +0 -0
- truss/tests/test_data/test_pyantic_v1/model/model.py +28 -0
- truss/tests/test_data/test_pyantic_v1/requirements.txt +1 -0
- truss/tests/test_data/test_pyantic_v2/__init__.py +0 -0
- truss/tests/test_data/test_pyantic_v2/config.yaml +13 -0
- truss/tests/test_data/test_pyantic_v2/model/__init__.py +0 -0
- truss/tests/test_data/test_pyantic_v2/model/model.py +30 -0
- truss/tests/test_data/test_pyantic_v2/requirements.txt +1 -0
- truss/tests/test_data/test_requirements_file_truss/__init__.py +0 -0
- truss/tests/test_data/test_requirements_file_truss/config.yaml +13 -0
- truss/tests/test_data/test_requirements_file_truss/model/__init__.py +0 -0
- truss/{test_data → tests/test_data}/test_requirements_file_truss/model/model.py +1 -0
- truss/tests/test_data/test_streaming_async_generator_truss/__init__.py +0 -0
- truss/tests/test_data/test_streaming_async_generator_truss/config.yaml +4 -0
- truss/tests/test_data/test_streaming_async_generator_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_streaming_async_generator_truss/model/model.py +7 -0
- truss/tests/test_data/test_streaming_read_timeout/__init__.py +0 -0
- truss/tests/test_data/test_streaming_read_timeout/model/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss/config.yaml +4 -0
- truss/tests/test_data/test_streaming_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss_with_error/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss_with_error/model/__init__.py +0 -0
- truss/{test_data → tests/test_data}/test_streaming_truss_with_error/model/model.py +3 -11
- truss/tests/test_data/test_streaming_truss_with_error/packages/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss_with_error/packages/helpers_1.py +5 -0
- truss/tests/test_data/test_streaming_truss_with_error/packages/helpers_2.py +2 -0
- truss/tests/test_data/test_streaming_truss_with_tracing/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss_with_tracing/config.yaml +43 -0
- truss/tests/test_data/test_streaming_truss_with_tracing/model/__init__.py +0 -0
- truss/tests/test_data/test_streaming_truss_with_tracing/model/model.py +65 -0
- truss/tests/test_data/test_trt_llm_truss/__init__.py +0 -0
- truss/tests/test_data/test_trt_llm_truss/config.yaml +15 -0
- truss/tests/test_data/test_trt_llm_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_trt_llm_truss/model/model.py +15 -0
- truss/tests/test_data/test_truss/__init__.py +0 -0
- truss/tests/test_data/test_truss/config.yaml +4 -0
- truss/tests/test_data/test_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_truss/model/dummy +0 -0
- truss/tests/test_data/test_truss/packages/__init__.py +0 -0
- truss/tests/test_data/test_truss/packages/test_package/__init__.py +0 -0
- truss/tests/test_data/test_truss_server_caching_truss/__init__.py +0 -0
- truss/tests/test_data/test_truss_server_caching_truss/model/__init__.py +0 -0
- truss/tests/test_data/test_truss_with_error/__init__.py +0 -0
- truss/tests/test_data/test_truss_with_error/config.yaml +4 -0
- truss/tests/test_data/test_truss_with_error/model/__init__.py +0 -0
- truss/tests/test_data/test_truss_with_error/model/model.py +8 -0
- truss/tests/test_data/test_truss_with_error/packages/__init__.py +0 -0
- truss/tests/test_data/test_truss_with_error/packages/helpers_1.py +5 -0
- truss/tests/test_data/test_truss_with_error/packages/helpers_2.py +2 -0
- truss/tests/test_docker.py +2 -1
- truss/tests/test_model_inference.py +1340 -292
- truss/tests/test_model_schema.py +33 -26
- truss/tests/test_testing_utilities_for_other_tests.py +50 -5
- truss/tests/test_truss_gatherer.py +3 -5
- truss/tests/test_truss_handle.py +62 -59
- truss/tests/test_util.py +2 -1
- truss/tests/test_validation.py +15 -13
- truss/tests/trt_llm/test_trt_llm_config.py +41 -0
- truss/tests/trt_llm/test_validation.py +91 -0
- truss/tests/util/test_config_checks.py +40 -0
- truss/tests/util/test_env_vars.py +14 -0
- truss/tests/util/test_path.py +10 -23
- truss/trt_llm/config_checks.py +43 -0
- truss/trt_llm/validation.py +42 -0
- truss/truss_handle/__init__.py +0 -0
- truss/truss_handle/build.py +122 -0
- truss/{decorators.py → truss_handle/decorators.py} +1 -1
- truss/truss_handle/patch/__init__.py +0 -0
- truss/{patch → truss_handle/patch}/calc_patch.py +146 -92
- truss/{types.py → truss_handle/patch/custom_types.py} +35 -27
- truss/{patch → truss_handle/patch}/dir_signature.py +1 -1
- truss/truss_handle/patch/hash.py +71 -0
- truss/{patch → truss_handle/patch}/local_truss_patch_applier.py +6 -4
- truss/truss_handle/patch/signature.py +22 -0
- truss/truss_handle/patch/truss_dir_patch_applier.py +87 -0
- truss/{readme_generator.py → truss_handle/readme_generator.py} +3 -2
- truss/{truss_gatherer.py → truss_handle/truss_gatherer.py} +3 -2
- truss/{truss_handle.py → truss_handle/truss_handle.py} +174 -78
- truss/util/.truss_ignore +3 -0
- truss/{docker.py → util/docker.py} +6 -2
- truss/util/download.py +6 -15
- truss/util/env_vars.py +41 -0
- truss/util/log_utils.py +52 -0
- truss/util/path.py +20 -20
- truss/util/requirements.py +11 -0
- {truss-0.10.0rc1.dist-info → truss-0.60.0.dist-info}/METADATA +18 -16
- truss-0.60.0.dist-info/RECORD +324 -0
- {truss-0.10.0rc1.dist-info → truss-0.60.0.dist-info}/WHEEL +1 -1
- truss-0.60.0.dist-info/entry_points.txt +4 -0
- truss_chains/__init__.py +71 -0
- truss_chains/definitions.py +756 -0
- truss_chains/deployment/__init__.py +0 -0
- truss_chains/deployment/code_gen.py +816 -0
- truss_chains/deployment/deployment_client.py +871 -0
- truss_chains/framework.py +1480 -0
- truss_chains/public_api.py +231 -0
- truss_chains/py.typed +0 -0
- truss_chains/pydantic_numpy.py +131 -0
- truss_chains/reference_code/reference_chainlet.py +34 -0
- truss_chains/reference_code/reference_model.py +10 -0
- truss_chains/remote_chainlet/__init__.py +0 -0
- truss_chains/remote_chainlet/model_skeleton.py +60 -0
- truss_chains/remote_chainlet/stub.py +380 -0
- truss_chains/remote_chainlet/utils.py +332 -0
- truss_chains/streaming.py +378 -0
- truss_chains/utils.py +178 -0
- CODE_OF_CONDUCT.md +0 -131
- CONTRIBUTING.md +0 -48
- README.md +0 -137
- context_builder.Dockerfile +0 -24
- truss/blob/blob_backend.py +0 -10
- truss/blob/blob_backend_registry.py +0 -23
- truss/blob/http_public_blob_backend.py +0 -23
- truss/build/__init__.py +0 -2
- truss/build/build.py +0 -143
- truss/build/configure.py +0 -63
- truss/cli/__init__.py +0 -2
- truss/cli/console.py +0 -5
- truss/cli/create.py +0 -5
- truss/config/trt_llm.py +0 -81
- truss/constants.py +0 -61
- truss/model_inference.py +0 -123
- truss/patch/types.py +0 -30
- truss/pytest.ini +0 -7
- truss/server/common/errors.py +0 -100
- truss/server/common/termination_handler_middleware.py +0 -64
- truss/server/common/truss_server.py +0 -389
- truss/server/control/patch/model_code_patch_applier.py +0 -46
- truss/server/control/patch/requirement_name_identifier.py +0 -17
- truss/server/inference_server.py +0 -29
- truss/server/model_wrapper.py +0 -434
- truss/server/shared/logging.py +0 -81
- truss/templates/trtllm/model/model.py +0 -97
- truss/templates/trtllm/packages/build_engine_utils.py +0 -34
- truss/templates/trtllm/packages/constants.py +0 -11
- truss/templates/trtllm/packages/schema.py +0 -216
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/ensemble/config.pbtxt +0 -246
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/postprocessing/1/model.py +0 -181
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/postprocessing/config.pbtxt +0 -64
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/preprocessing/1/model.py +0 -260
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/preprocessing/config.pbtxt +0 -99
- truss/templates/trtllm/packages/tensorrt_llm_model_repository/tensorrt_llm/config.pbtxt +0 -208
- truss/templates/trtllm/packages/triton_client.py +0 -150
- truss/templates/trtllm/packages/utils.py +0 -43
- truss/test_data/context_builder_image_test/test.py +0 -4
- truss/test_data/happy.ipynb +0 -54
- truss/test_data/model_load_failure_test/config.yaml +0 -2
- truss/test_data/test_concurrency_truss/config.yaml +0 -2
- truss/test_data/test_streaming_async_generator_truss/config.yaml +0 -2
- truss/test_data/test_streaming_truss/config.yaml +0 -3
- truss/test_data/test_truss/config.yaml +0 -2
- truss/tests/server/common/test_termination_handler_middleware.py +0 -93
- truss/tests/server/control/test_model_container_patch_applier.py +0 -203
- truss/tests/server/core/server/common/test_util.py +0 -19
- truss/tests/server/test_model_wrapper.py +0 -87
- truss/util/data_structures.py +0 -16
- truss-0.10.0rc1.dist-info/RECORD +0 -216
- truss-0.10.0rc1.dist-info/entry_points.txt +0 -3
- truss/{server/shared → base}/__init__.py +0 -0
- truss/{server → templates/control}/control/helpers/context_managers.py +0 -0
- truss/{server/control → templates/control/control/helpers}/errors.py +0 -0
- truss/{server/control/patch → templates/control/control/helpers/truss_patch}/__init__.py +0 -0
- truss/{server/control/patch → templates/control/control/helpers/truss_patch}/system_packages.py +0 -0
- truss/{test_data/annotated_types_truss/model → templates/server}/__init__.py +0 -0
- truss/{server → templates/server}/common/__init__.py +0 -0
- truss/{test_data/gcs_fix/model → templates/shared}/__init__.py +0 -0
- truss/templates/{trtllm → trtllm-briton}/README.md +0 -0
- truss/{test_data/server_conformance_test_truss/model → tests/test_data}/__init__.py +0 -0
- truss/{test_data/test_basic_truss/model → tests/test_data/annotated_types_truss}/__init__.py +0 -0
- truss/{test_data → tests/test_data}/annotated_types_truss/config.yaml +0 -0
- truss/{test_data/test_requirements_file_truss → tests/test_data/annotated_types_truss}/model/__init__.py +0 -0
- truss/{test_data → tests/test_data}/annotated_types_truss/model/model.py +0 -0
- truss/{test_data → tests/test_data}/auto-mpg.data +0 -0
- truss/{test_data → tests/test_data}/context_builder_image_test/Dockerfile +0 -0
- truss/{test_data/test_truss/model → tests/test_data/context_builder_image_test}/__init__.py +0 -0
- truss/{test_data/test_truss_server_caching_truss/model → tests/test_data/gcs_fix}/__init__.py +0 -0
- truss/{test_data → tests/test_data}/gcs_fix/config.yaml +0 -0
- truss/tests/{local → test_data/gcs_fix/model}/__init__.py +0 -0
- truss/{test_data → tests/test_data}/gcs_fix/model/model.py +0 -0
- truss/{test_data/test_truss/model/dummy → tests/test_data/model_load_failure_test/__init__.py} +0 -0
- truss/{test_data → tests/test_data}/model_load_failure_test/model/model.py +0 -0
- truss/{test_data → tests/test_data}/pima-indians-diabetes.csv +0 -0
- truss/{test_data → tests/test_data}/readme_int_example.md +0 -0
- truss/{test_data → tests/test_data}/readme_no_example.md +0 -0
- truss/{test_data → tests/test_data}/readme_str_example.md +0 -0
- truss/{test_data → tests/test_data}/server_conformance_test_truss/config.yaml +0 -0
- truss/{test_data → tests/test_data}/test_async_truss/config.yaml +0 -0
- truss/{test_data → tests/test_data}/test_async_truss/model/model.py +3 -3
- /truss/{test_data → tests/test_data}/test_basic_truss/model/model.py +0 -0
- /truss/{test_data → tests/test_data}/test_concurrency_truss/model/model.py +0 -0
- /truss/{test_data/test_requirements_file_truss → tests/test_data/test_pyantic_v1}/config.yaml +0 -0
- /truss/{test_data → tests/test_data}/test_requirements_file_truss/requirements.txt +0 -0
- /truss/{test_data → tests/test_data}/test_streaming_read_timeout/config.yaml +0 -0
- /truss/{test_data → tests/test_data}/test_streaming_read_timeout/model/model.py +0 -0
- /truss/{test_data → tests/test_data}/test_streaming_truss/model/model.py +0 -0
- /truss/{test_data → tests/test_data}/test_streaming_truss_with_error/config.yaml +0 -0
- /truss/{test_data → tests/test_data}/test_truss/examples.yaml +0 -0
- /truss/{test_data → tests/test_data}/test_truss/model/model.py +0 -0
- /truss/{test_data → tests/test_data}/test_truss/packages/test_package/test.py +0 -0
- /truss/{test_data → tests/test_data}/test_truss_server_caching_truss/config.yaml +0 -0
- /truss/{test_data → tests/test_data}/test_truss_server_caching_truss/model/model.py +0 -0
- /truss/{patch → truss_handle/patch}/constants.py +0 -0
- /truss/{notebook.py → util/notebook.py} +0 -0
- {truss-0.10.0rc1.dist-info → truss-0.60.0.dist-info}/LICENSE +0 -0
truss/remote/baseten/core.py
CHANGED
|
@@ -1,17 +1,34 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import json
|
|
1
3
|
import logging
|
|
2
|
-
|
|
4
|
+
import textwrap
|
|
5
|
+
from typing import IO, TYPE_CHECKING, List, NamedTuple, Optional, Tuple, Type
|
|
6
|
+
|
|
7
|
+
from truss.base.errors import ValidationError
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from rich import progress
|
|
3
11
|
|
|
4
12
|
import truss
|
|
13
|
+
from truss.base.constants import PRODUCTION_ENVIRONMENT_NAME
|
|
14
|
+
from truss.remote.baseten import custom_types as b10_types
|
|
5
15
|
from truss.remote.baseten.api import BasetenApi
|
|
6
16
|
from truss.remote.baseten.error import ApiError
|
|
7
17
|
from truss.remote.baseten.utils.tar import create_tar_with_progress_bar
|
|
8
18
|
from truss.remote.baseten.utils.transfer import multipart_upload_boto3
|
|
9
|
-
from truss.truss_handle import TrussHandle
|
|
10
|
-
from truss.util.path import
|
|
19
|
+
from truss.truss_handle.truss_handle import TrussHandle
|
|
20
|
+
from truss.util.path import load_trussignore_patterns_from_truss_dir
|
|
11
21
|
|
|
12
22
|
logger = logging.getLogger(__name__)
|
|
13
23
|
|
|
14
24
|
|
|
25
|
+
DEPLOYING_STATUSES = ["BUILDING", "DEPLOYING", "LOADING_MODEL", "UPDATING"]
|
|
26
|
+
ACTIVE_STATUS = "ACTIVE"
|
|
27
|
+
NO_ENVIRONMENTS_EXIST_ERROR_MESSAGING = (
|
|
28
|
+
"Model hasn't been deployed yet. No evironments exist."
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
15
32
|
class ModelIdentifier:
|
|
16
33
|
value: str
|
|
17
34
|
|
|
@@ -31,6 +48,126 @@ class ModelVersionId(ModelIdentifier):
|
|
|
31
48
|
self.value = model_version_id
|
|
32
49
|
|
|
33
50
|
|
|
51
|
+
class PatchState(NamedTuple):
|
|
52
|
+
current_hash: str
|
|
53
|
+
current_signature: str
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class TrussPatches(NamedTuple):
|
|
57
|
+
django_patch_state: PatchState
|
|
58
|
+
container_patch_state: PatchState
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class TrussWatchState(NamedTuple):
|
|
62
|
+
is_container_built_from_push: bool
|
|
63
|
+
patches: Optional[TrussPatches]
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class ChainDeploymentHandleAtomic(NamedTuple):
|
|
67
|
+
chain_id: str
|
|
68
|
+
chain_deployment_id: str
|
|
69
|
+
is_draft: bool
|
|
70
|
+
entrypoint_model_id: str
|
|
71
|
+
entrypoint_model_version_id: str
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def get_chain_id_by_name(api: BasetenApi, chain_name: str) -> Optional[str]:
|
|
75
|
+
"""
|
|
76
|
+
Check if a chain with the given name exists in the Baseten remote.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
api: BasetenApi instance
|
|
80
|
+
chain_name: Name of the chain to check for existence
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
chain_id if present, otherwise None
|
|
84
|
+
"""
|
|
85
|
+
chains = api.get_chains()
|
|
86
|
+
|
|
87
|
+
chain_name_id_mapping = {chain["name"]: chain["id"] for chain in chains}
|
|
88
|
+
return chain_name_id_mapping.get(chain_name)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def get_dev_chain_deployment(api: BasetenApi, chain_id: str):
|
|
92
|
+
chain_deployments = api.get_chain_deployments(chain_id)
|
|
93
|
+
dev_deployments = [
|
|
94
|
+
deployment for deployment in chain_deployments if deployment["is_draft"]
|
|
95
|
+
]
|
|
96
|
+
if not dev_deployments:
|
|
97
|
+
return None
|
|
98
|
+
newest_draft_deployment = max(
|
|
99
|
+
dev_deployments, key=lambda d: datetime.datetime.fromisoformat(d["created"])
|
|
100
|
+
)
|
|
101
|
+
return newest_draft_deployment
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def create_chain_atomic(
|
|
105
|
+
api: BasetenApi,
|
|
106
|
+
chain_name: str,
|
|
107
|
+
entrypoint: b10_types.ChainletDataAtomic,
|
|
108
|
+
dependencies: List[b10_types.ChainletDataAtomic],
|
|
109
|
+
is_draft: bool,
|
|
110
|
+
environment: Optional[str],
|
|
111
|
+
) -> ChainDeploymentHandleAtomic:
|
|
112
|
+
if environment and is_draft:
|
|
113
|
+
logging.info(
|
|
114
|
+
f"Automatically publishing Chain `{chain_name}` based on "
|
|
115
|
+
"environment setting."
|
|
116
|
+
)
|
|
117
|
+
is_draft = False
|
|
118
|
+
|
|
119
|
+
chain_id = get_chain_id_by_name(api, chain_name)
|
|
120
|
+
|
|
121
|
+
# TODO(Tyron): Refactor for better readability:
|
|
122
|
+
# 1. Prepare all arguments for `deploy_chain_atomic`.
|
|
123
|
+
# 2. Validate argument combinations.
|
|
124
|
+
# 3. Make a single invocation to `deploy_chain_atomic`.
|
|
125
|
+
if is_draft:
|
|
126
|
+
res = api.deploy_chain_atomic(
|
|
127
|
+
chain_name=chain_name,
|
|
128
|
+
is_draft=True,
|
|
129
|
+
entrypoint=entrypoint,
|
|
130
|
+
dependencies=dependencies,
|
|
131
|
+
)
|
|
132
|
+
elif chain_id:
|
|
133
|
+
# This is the only case where promote has relevance, since
|
|
134
|
+
# if there is no chain already, the first deployment will
|
|
135
|
+
# already be production, and only published deployments can
|
|
136
|
+
# be promoted.
|
|
137
|
+
try:
|
|
138
|
+
res = api.deploy_chain_atomic(
|
|
139
|
+
chain_id=chain_id,
|
|
140
|
+
environment=environment,
|
|
141
|
+
entrypoint=entrypoint,
|
|
142
|
+
dependencies=dependencies,
|
|
143
|
+
)
|
|
144
|
+
except ApiError as e:
|
|
145
|
+
if (
|
|
146
|
+
e.graphql_error_code
|
|
147
|
+
== BasetenApi.GraphQLErrorCodes.RESOURCE_NOT_FOUND.value
|
|
148
|
+
):
|
|
149
|
+
raise ValueError(
|
|
150
|
+
f"Environment `{environment}` does not exist. You can "
|
|
151
|
+
f"create environments in the Chains UI."
|
|
152
|
+
) from e
|
|
153
|
+
|
|
154
|
+
raise e
|
|
155
|
+
elif environment and environment != PRODUCTION_ENVIRONMENT_NAME:
|
|
156
|
+
raise ValueError(NO_ENVIRONMENTS_EXIST_ERROR_MESSAGING)
|
|
157
|
+
else:
|
|
158
|
+
res = api.deploy_chain_atomic(
|
|
159
|
+
chain_name=chain_name, entrypoint=entrypoint, dependencies=dependencies
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
return ChainDeploymentHandleAtomic(
|
|
163
|
+
chain_id=res["chain_id"],
|
|
164
|
+
chain_deployment_id=res["chain_deployment_id"],
|
|
165
|
+
entrypoint_model_id=res["entrypoint_model_id"],
|
|
166
|
+
entrypoint_model_version_id=res["entrypoint_model_version_id"],
|
|
167
|
+
is_draft=is_draft,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
|
|
34
171
|
def exists_model(api: BasetenApi, model_name: str) -> Optional[str]:
|
|
35
172
|
"""
|
|
36
173
|
Check if a model with the given name exists in the Baseten remote.
|
|
@@ -58,7 +195,7 @@ def exists_model(api: BasetenApi, model_name: str) -> Optional[str]:
|
|
|
58
195
|
|
|
59
196
|
def get_model_versions(api: BasetenApi, model_name: ModelName) -> Tuple[str, List]:
|
|
60
197
|
query_result = api.get_model(model_name.value)["model"]
|
|
61
|
-
return
|
|
198
|
+
return query_result["id"], query_result["versions"]
|
|
62
199
|
|
|
63
200
|
|
|
64
201
|
def get_dev_version_from_versions(versions: List[dict]) -> Optional[dict]:
|
|
@@ -93,6 +230,36 @@ def get_dev_version(api: BasetenApi, model_name: str) -> Optional[dict]:
|
|
|
93
230
|
return get_dev_version_from_versions(versions)
|
|
94
231
|
|
|
95
232
|
|
|
233
|
+
def get_truss_watch_state(api: BasetenApi, model_name: str) -> TrussWatchState:
|
|
234
|
+
response = api.get_truss_watch_state(model_name)["truss_watch_state"]
|
|
235
|
+
django_patch_state = (
|
|
236
|
+
None
|
|
237
|
+
if response["django_patch_state"] is None
|
|
238
|
+
else PatchState(
|
|
239
|
+
current_hash=response["django_patch_state"]["current_hash"],
|
|
240
|
+
current_signature=response["django_patch_state"]["current_signature"],
|
|
241
|
+
)
|
|
242
|
+
)
|
|
243
|
+
container_patch_state = (
|
|
244
|
+
None
|
|
245
|
+
if response["container_patch_state"] is None
|
|
246
|
+
else PatchState(
|
|
247
|
+
current_hash=response["container_patch_state"]["current_hash"],
|
|
248
|
+
current_signature=response["container_patch_state"]["current_signature"],
|
|
249
|
+
)
|
|
250
|
+
)
|
|
251
|
+
patches = None
|
|
252
|
+
if django_patch_state and container_patch_state:
|
|
253
|
+
patches = TrussPatches(
|
|
254
|
+
django_patch_state=django_patch_state,
|
|
255
|
+
container_patch_state=container_patch_state,
|
|
256
|
+
)
|
|
257
|
+
return TrussWatchState(
|
|
258
|
+
is_container_built_from_push=response["is_container_built_from_push"],
|
|
259
|
+
patches=patches,
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
|
|
96
263
|
def get_prod_version_from_versions(versions: List[dict]) -> Optional[dict]:
|
|
97
264
|
# Loop over versions instead of using the primary_version field because
|
|
98
265
|
# primary_version is set to the development version ID if no published
|
|
@@ -103,38 +270,37 @@ def get_prod_version_from_versions(versions: List[dict]) -> Optional[dict]:
|
|
|
103
270
|
return None
|
|
104
271
|
|
|
105
272
|
|
|
106
|
-
def archive_truss(
|
|
107
|
-
""
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
Args:
|
|
111
|
-
b10_truss: TrussHandle to archive
|
|
273
|
+
def archive_truss(
|
|
274
|
+
truss_handle: TrussHandle, progress_bar: Optional[Type["progress.Progress"]]
|
|
275
|
+
) -> IO:
|
|
276
|
+
"""Archive a TrussHandle into a tar file.
|
|
112
277
|
|
|
113
278
|
Returns:
|
|
114
279
|
A file-like object containing the tar file
|
|
115
280
|
"""
|
|
116
|
-
truss_dir = truss_handle.
|
|
117
|
-
ignore_patterns = []
|
|
281
|
+
truss_dir = truss_handle._truss_dir
|
|
118
282
|
|
|
119
283
|
# check for a truss_ignore file and read the ignore patterns if it exists
|
|
120
|
-
|
|
121
|
-
if truss_ignore_file.exists():
|
|
122
|
-
ignore_patterns = load_trussignore_patterns(truss_ignore_file=truss_ignore_file)
|
|
123
|
-
else:
|
|
124
|
-
ignore_patterns = load_trussignore_patterns()
|
|
284
|
+
ignore_patterns = load_trussignore_patterns_from_truss_dir(truss_dir)
|
|
125
285
|
|
|
126
286
|
try:
|
|
127
|
-
temp_file = create_tar_with_progress_bar(
|
|
287
|
+
temp_file = create_tar_with_progress_bar(
|
|
288
|
+
truss_dir, ignore_patterns, progress_bar=progress_bar
|
|
289
|
+
)
|
|
128
290
|
except PermissionError:
|
|
129
291
|
# workaround for Windows bug with Tempfile that causes PermissionErrors
|
|
130
292
|
temp_file = create_tar_with_progress_bar(
|
|
131
|
-
truss_dir, ignore_patterns, delete=False
|
|
293
|
+
truss_dir, ignore_patterns, delete=False, progress_bar=progress_bar
|
|
132
294
|
)
|
|
133
295
|
temp_file.file.seek(0)
|
|
134
296
|
return temp_file
|
|
135
297
|
|
|
136
298
|
|
|
137
|
-
def upload_truss(
|
|
299
|
+
def upload_truss(
|
|
300
|
+
api: BasetenApi,
|
|
301
|
+
serialize_file: IO,
|
|
302
|
+
progress_bar: Optional[Type["progress.Progress"]],
|
|
303
|
+
) -> str:
|
|
138
304
|
"""
|
|
139
305
|
Upload a TrussHandle to the Baseten remote.
|
|
140
306
|
|
|
@@ -149,7 +315,7 @@ def upload_truss(api: BasetenApi, serialize_file: IO) -> str:
|
|
|
149
315
|
s3_key = temp_credentials_s3_upload.pop("s3_key")
|
|
150
316
|
s3_bucket = temp_credentials_s3_upload.pop("s3_bucket")
|
|
151
317
|
multipart_upload_boto3(
|
|
152
|
-
serialize_file.name, s3_bucket, s3_key, temp_credentials_s3_upload
|
|
318
|
+
serialize_file.name, s3_bucket, s3_key, temp_credentials_s3_upload, progress_bar
|
|
153
319
|
)
|
|
154
320
|
return s3_key
|
|
155
321
|
|
|
@@ -161,25 +327,29 @@ def create_truss_service(
|
|
|
161
327
|
config: str,
|
|
162
328
|
semver_bump: str = "MINOR",
|
|
163
329
|
is_trusted: bool = False,
|
|
164
|
-
promote: bool = False,
|
|
165
330
|
preserve_previous_prod_deployment: bool = False,
|
|
331
|
+
allow_truss_download: bool = False,
|
|
166
332
|
is_draft: Optional[bool] = False,
|
|
167
333
|
model_id: Optional[str] = None,
|
|
168
334
|
deployment_name: Optional[str] = None,
|
|
335
|
+
origin: Optional[b10_types.ModelOrigin] = None,
|
|
336
|
+
environment: Optional[str] = None,
|
|
169
337
|
) -> Tuple[str, str]:
|
|
170
338
|
"""
|
|
171
339
|
Create a model in the Baseten remote.
|
|
172
340
|
|
|
173
341
|
Args:
|
|
174
|
-
api: BasetenApi instance
|
|
175
|
-
model_name: Name of the model to create
|
|
176
|
-
s3_key: S3 key of the uploaded TrussHandle
|
|
177
|
-
config: Base64 encoded JSON string of the Truss config
|
|
178
|
-
semver_bump: Semver bump type, defaults to "MINOR"
|
|
179
|
-
is_trusted: Whether the model is trusted, defaults to False
|
|
180
|
-
promote: Whether to promote the model after deploy, defaults to False
|
|
181
|
-
preserve_previous_prod_deployment:
|
|
182
|
-
|
|
342
|
+
api: BasetenApi instance.
|
|
343
|
+
model_name: Name of the model to create.
|
|
344
|
+
s3_key: S3 key of the uploaded TrussHandle.
|
|
345
|
+
config: Base64 encoded JSON string of the Truss config.
|
|
346
|
+
semver_bump: Semver bump type, defaults to "MINOR".
|
|
347
|
+
is_trusted: Whether the model is trusted, defaults to False.
|
|
348
|
+
promote: Whether to promote the model after deploy, defaults to False.
|
|
349
|
+
preserve_previous_prod_deployment: Whether to scale old production deployment
|
|
350
|
+
to zero.
|
|
351
|
+
deployment_name: Name to apply to the created deployment. Not applied to
|
|
352
|
+
development model.
|
|
183
353
|
|
|
184
354
|
Returns:
|
|
185
355
|
A tuple of the model ID and version ID
|
|
@@ -189,35 +359,72 @@ def create_truss_service(
|
|
|
189
359
|
model_name,
|
|
190
360
|
s3_key,
|
|
191
361
|
config,
|
|
192
|
-
|
|
193
|
-
is_trusted,
|
|
362
|
+
truss.version(),
|
|
363
|
+
is_trusted=is_trusted,
|
|
364
|
+
allow_truss_download=allow_truss_download,
|
|
365
|
+
origin=origin,
|
|
194
366
|
)
|
|
195
367
|
|
|
196
|
-
return
|
|
368
|
+
return model_version_json["id"], model_version_json["version_id"]
|
|
197
369
|
|
|
198
370
|
if model_id is None:
|
|
371
|
+
if environment and environment != PRODUCTION_ENVIRONMENT_NAME:
|
|
372
|
+
raise ValueError(NO_ENVIRONMENTS_EXIST_ERROR_MESSAGING)
|
|
199
373
|
model_version_json = api.create_model_from_truss(
|
|
200
374
|
model_name=model_name,
|
|
201
375
|
s3_key=s3_key,
|
|
202
376
|
config=config,
|
|
203
377
|
semver_bump=semver_bump,
|
|
204
|
-
client_version=
|
|
378
|
+
client_version=truss.version(),
|
|
205
379
|
is_trusted=is_trusted,
|
|
380
|
+
allow_truss_download=allow_truss_download,
|
|
206
381
|
deployment_name=deployment_name,
|
|
382
|
+
origin=origin,
|
|
207
383
|
)
|
|
208
|
-
return
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
384
|
+
return model_version_json["id"], model_version_json["version_id"]
|
|
385
|
+
|
|
386
|
+
try:
|
|
387
|
+
model_version_json = api.create_model_version_from_truss(
|
|
388
|
+
model_id=model_id,
|
|
389
|
+
s3_key=s3_key,
|
|
390
|
+
config=config,
|
|
391
|
+
semver_bump=semver_bump,
|
|
392
|
+
client_version=truss.version(),
|
|
393
|
+
is_trusted=is_trusted,
|
|
394
|
+
preserve_previous_prod_deployment=preserve_previous_prod_deployment,
|
|
395
|
+
deployment_name=deployment_name,
|
|
396
|
+
environment=environment,
|
|
397
|
+
)
|
|
398
|
+
except ApiError as e:
|
|
399
|
+
if (
|
|
400
|
+
e.graphql_error_code
|
|
401
|
+
== BasetenApi.GraphQLErrorCodes.RESOURCE_NOT_FOUND.value
|
|
402
|
+
):
|
|
403
|
+
raise ValueError(
|
|
404
|
+
f'Environment "{environment}" does not exist. You can create environments in the Baseten UI.'
|
|
405
|
+
) from e
|
|
406
|
+
raise e
|
|
222
407
|
model_version_id = model_version_json["id"]
|
|
223
|
-
return
|
|
408
|
+
return model_id, model_version_id
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def validate_truss_config(api: BasetenApi, config: str):
|
|
412
|
+
"""
|
|
413
|
+
Validate a truss config as well as the truss version.
|
|
414
|
+
|
|
415
|
+
Args:
|
|
416
|
+
api: BasetenApi instance
|
|
417
|
+
config: Base64 encoded JSON string of the Truss config
|
|
418
|
+
|
|
419
|
+
Returns:
|
|
420
|
+
None if the config is valid, otherwise raises an error message
|
|
421
|
+
"""
|
|
422
|
+
valid_config = api.validate_truss(truss.version(), config)
|
|
423
|
+
if not valid_config.get("success"):
|
|
424
|
+
details = json.loads(valid_config.get("details"))
|
|
425
|
+
errors = details.get("errors", [])
|
|
426
|
+
if errors:
|
|
427
|
+
error_messages = "\n".join(textwrap.indent(error, " ") for error in errors)
|
|
428
|
+
raise ValidationError(
|
|
429
|
+
f"Validation failed with the following errors:\n{error_messages}"
|
|
430
|
+
)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import pathlib
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
import pydantic
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DeployedChainlet(pydantic.BaseModel):
|
|
9
|
+
name: str
|
|
10
|
+
is_entrypoint: bool
|
|
11
|
+
is_draft: bool
|
|
12
|
+
status: str
|
|
13
|
+
logs_url: str
|
|
14
|
+
oracle_predict_url: str
|
|
15
|
+
oracle_name: str
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ChainletArtifact(pydantic.BaseModel):
|
|
19
|
+
truss_dir: pathlib.Path
|
|
20
|
+
display_name: str
|
|
21
|
+
name: str
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ModelOrigin(Enum):
|
|
25
|
+
BASETEN = "BASETEN"
|
|
26
|
+
CHAINS = "CHAINS"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class OracleData(pydantic.BaseModel):
|
|
30
|
+
class Config:
|
|
31
|
+
protected_namespaces = ()
|
|
32
|
+
|
|
33
|
+
model_name: str
|
|
34
|
+
s3_key: str
|
|
35
|
+
encoded_config_str: str
|
|
36
|
+
semver_bump: Optional[str] = "MINOR"
|
|
37
|
+
is_trusted: bool
|
|
38
|
+
version_name: Optional[str] = None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# This corresponds to `ChainletInputAtomicGraphene` in the backend.
|
|
42
|
+
class ChainletDataAtomic(pydantic.BaseModel):
|
|
43
|
+
name: str
|
|
44
|
+
oracle: OracleData
|