truss 0.9.12__tar.gz → 0.9.12.dev2__tar.gz
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.
- {truss-0.9.12 → truss-0.9.12.dev2}/PKG-INFO +1 -1
- {truss-0.9.12 → truss-0.9.12.dev2}/pyproject.toml +2 -2
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/cli/cli.py +11 -11
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/config/trt_llm.py +1 -1
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/constants.py +1 -1
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/service.py +1 -1
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_basic_truss/config.yaml +1 -3
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_config.py +14 -42
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/truss_config.py +0 -17
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/validation.py +3 -4
- {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/__init__.py +2 -2
- {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/code_gen.py +7 -11
- {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/definitions.py +25 -48
- {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/deploy.py +1 -1
- truss-0.9.12.dev2/truss-chains/truss_chains/example_chainlet.py +37 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/framework.py +135 -209
- {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/model_skeleton.py +1 -1
- truss-0.9.12.dev2/truss-chains/truss_chains/public_api.py +73 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/stub.py +1 -1
- {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/utils.py +1 -0
- truss-0.9.12/truss-chains/truss_chains/example_chainlet.py +0 -30
- truss-0.9.12/truss-chains/truss_chains/public_api.py +0 -84
- {truss-0.9.12 → truss-0.9.12.dev2}/CODE_OF_CONDUCT.md +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/CONTRIBUTING.md +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/LICENSE +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/README.md +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/context_builder.Dockerfile +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/blob/blob_backend.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/blob/blob_backend_registry.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/blob/http_public_blob_backend.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/build.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/cli/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/cli/console.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/cli/create.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/image_builder/cache_warmer.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/image_builder/image_builder.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/image_builder/serving_image_builder.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/image_builder/util.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/local_loader/docker_build_emulator.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/local_loader/load_model_local.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/local_loader/truss_module_loader.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/local_loader/utils.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/truss_context.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/decorators.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/docker.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/errors.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/local/local_config.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/local/local_config_handler.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/model_inference.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/notebook.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/calc_patch.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/constants.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/dir_signature.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/hash.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/local_truss_patch_applier.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/signature.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/truss_dir_patch_applier.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/types.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/readme_generator.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/api.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/auth.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/core.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/error.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/remote.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/utils/tar.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/utils/transfer.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/remote_cli.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/remote_factory.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/truss_remote.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/README.md.jinja +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/base.Dockerfile.jinja +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/cache.Dockerfile.jinja +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/cache_requirements.txt +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/application.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/endpoints.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/context_managers.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/errors.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/inference_server_controller.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/inference_server_process_controller.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/inference_server_starter.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/truss_patch/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/truss_patch/model_code_patch_applier.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/truss_patch/model_container_patch_applier.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/truss_patch/requirement_name_identifier.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/truss_patch/system_packages.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/types.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/server.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/requirements.txt +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/copy_cache_files.Dockerfile.jinja +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/custom/examples.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/custom/model/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/custom/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/errors.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/patches/whisper/patch.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/patches.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/retry.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/schema.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/termination_handler_middleware.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/truss_server.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/inference_server.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/model_wrapper.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/requirements.txt +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server.Dockerfile.jinja +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/shared/README.md +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/shared/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/shared/logging.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/shared/secrets_resolver.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/shared/serialization.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/shared/util.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/README.md +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/constants.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/schema.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/tensorrt_llm_model_repository/ensemble/config.pbtxt +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/tensorrt_llm_model_repository/postprocessing/1/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/tensorrt_llm_model_repository/postprocessing/config.pbtxt +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/tensorrt_llm_model_repository/preprocessing/1/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/tensorrt_llm_model_repository/preprocessing/config.pbtxt +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/tensorrt_llm_model_repository/tensorrt_llm/config.pbtxt +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/triton_client.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/utils.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/annotated_types_truss/config.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/annotated_types_truss/model/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/annotated_types_truss/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/auto-mpg.data +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/context_builder_image_test/Dockerfile +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/context_builder_image_test/test.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/gcs_fix/config.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/gcs_fix/model/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/gcs_fix/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/happy.ipynb +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/model_load_failure_test/config.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/model_load_failure_test/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/patch_ping_test_server/app.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/pima-indians-diabetes.csv +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/readme_int_example.md +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/readme_no_example.md +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/readme_str_example.md +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/server.Dockerfile +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/server_conformance_test_truss/config.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/server_conformance_test_truss/model/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/server_conformance_test_truss/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_async_truss/config.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_async_truss/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_basic_truss/model/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_basic_truss/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_concurrency_truss/config.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_concurrency_truss/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v1/config.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v1/model/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v1/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v1/requirements.txt +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v2/config.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v2/model/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v2/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v2/requirements.txt +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_requirements_file_truss/config.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_requirements_file_truss/model/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_requirements_file_truss/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_requirements_file_truss/requirements.txt +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_async_generator_truss/config.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_async_generator_truss/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_read_timeout/config.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_read_timeout/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_truss/config.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_truss/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_truss_with_error/config.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_truss_with_error/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss/config.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss/examples.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss/model/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss/model/dummy +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss/packages/test_package/test.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss_server_caching_truss/config.yaml +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss_server_caching_truss/model/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss_server_caching_truss/model/model.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/conftest.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/contexts/image_builder/test_serving_image_builder.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/contexts/local_loader/test_load_local.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/contexts/local_loader/test_truss_module_finder.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/helpers.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/local/__init__.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/local/test_local_config_handler.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/patch/test_calc_patch.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/patch/test_dir_signature.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/patch/test_hash.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/patch/test_signature.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/patch/test_truss_dir_patch_applier.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/patch/test_types.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/remote/baseten/test_api.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/remote/baseten/test_auth.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/remote/baseten/test_core.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/remote/baseten/test_remote.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/remote/test_remote_factory.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/remote/test_truss_remote.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/control/control/helpers/test_context_managers.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/control/control/helpers/test_model_container_patch_applier.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/control/control/helpers/test_requirement_name_identifier.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/control/control/test_server.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/control/control/test_server_integration.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/core/server/common/test_truss_server.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/core/server/common/test_util.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/core/server/test_secrets_resolver.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/server/common/test_retry.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/server/common/test_termination_handler_middleware.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/server/test_model_wrapper.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/server/test_schema.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_build.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_context_builder_image.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_control_truss_patching.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_docker.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_model_inference.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_model_schema.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_testing_utilities_for_other_tests.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_truss_gatherer.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_truss_handle.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_util.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_validation.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/util/test_path.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/truss_gatherer.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/truss_handle.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/truss_spec.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/types.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/util/.truss_ignore +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/util/data_structures.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/util/download.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/util/errors.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/util/gpu.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/util/jinja.py +0 -0
- {truss-0.9.12 → truss-0.9.12.dev2}/truss/util/path.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "truss"
|
|
3
|
-
version = "0.9.
|
|
3
|
+
version = "0.9.12dev2"
|
|
4
4
|
description = "A seamless bridge from model development to model delivery"
|
|
5
5
|
license = "MIT"
|
|
6
6
|
readme = "README.md"
|
|
@@ -117,7 +117,7 @@ src_paths = ["isort", "test"]
|
|
|
117
117
|
[tool.mypy]
|
|
118
118
|
ignore_missing_imports = true
|
|
119
119
|
python_version = "3.9"
|
|
120
|
-
|
|
120
|
+
|
|
121
121
|
|
|
122
122
|
[tool.pytest.ini_options]
|
|
123
123
|
markers = [
|
|
@@ -635,7 +635,7 @@ def predict(
|
|
|
635
635
|
"specifying, the command will not complete until the deployment is complete."
|
|
636
636
|
),
|
|
637
637
|
)
|
|
638
|
-
@error_handling
|
|
638
|
+
# @error_handling
|
|
639
639
|
def push(
|
|
640
640
|
target_directory: str,
|
|
641
641
|
remote: str,
|
|
@@ -670,16 +670,6 @@ def push(
|
|
|
670
670
|
tr.spec.config.model_name = model_name
|
|
671
671
|
tr.spec.config.write_to_yaml_file(tr.spec.config_path, verbose=False)
|
|
672
672
|
|
|
673
|
-
# Log a warning if using secrets without --trusted.
|
|
674
|
-
# TODO(helen): this could be moved to a separate function that includes more
|
|
675
|
-
# config checks.
|
|
676
|
-
if tr.spec.config.secrets and not trusted:
|
|
677
|
-
not_trusted_text = (
|
|
678
|
-
"Warning: your Truss has secrets but was not pushed with --trusted. "
|
|
679
|
-
"Please push with --trusted to grant access to secrets."
|
|
680
|
-
)
|
|
681
|
-
console.print(not_trusted_text, style="red")
|
|
682
|
-
|
|
683
673
|
# TODO(Abu): This needs to be refactored to be more generic
|
|
684
674
|
service = remote_provider.push(
|
|
685
675
|
tr,
|
|
@@ -708,6 +698,16 @@ def push(
|
|
|
708
698
|
|
|
709
699
|
click.echo(draft_model_text)
|
|
710
700
|
|
|
701
|
+
# Log a warning if using secrets without --trusted.
|
|
702
|
+
# TODO(helen): this could be moved to a separate function that includes more
|
|
703
|
+
# config checks.
|
|
704
|
+
if tr.spec.config.secrets and not trusted:
|
|
705
|
+
not_trusted_text = (
|
|
706
|
+
"Warning: your Truss has secrets but was not pushed with --trusted."
|
|
707
|
+
"Please push with --trusted to grant access to secrets."
|
|
708
|
+
)
|
|
709
|
+
console.print(not_trusted_text, style="red")
|
|
710
|
+
|
|
711
711
|
if promote:
|
|
712
712
|
promotion_text = (
|
|
713
713
|
"Your Truss has been deployed as a production model. After it successfully "
|
|
@@ -29,7 +29,7 @@ class TrussTRTLLMQuantizationType(str, Enum):
|
|
|
29
29
|
class TrussTRTLLMPluginConfiguration(BaseModel):
|
|
30
30
|
multi_block_mode: bool = False
|
|
31
31
|
paged_kv_cache: bool = True
|
|
32
|
-
|
|
32
|
+
use_fused_mlp: bool = False
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
class CheckpointSource(Enum):
|
|
@@ -89,7 +89,7 @@ class BasetenService(TrussService):
|
|
|
89
89
|
# will be a json with an `error` key.
|
|
90
90
|
return parsed_response
|
|
91
91
|
|
|
92
|
-
return response.json()
|
|
92
|
+
return response.json()["model_output"]
|
|
93
93
|
|
|
94
94
|
def authenticate(self) -> dict:
|
|
95
95
|
return self._auth_service.authenticate().header()
|
|
@@ -315,57 +315,29 @@ def test_empty_config():
|
|
|
315
315
|
|
|
316
316
|
|
|
317
317
|
def test_from_yaml():
|
|
318
|
+
yaml_path = Path("test.yaml")
|
|
318
319
|
data = {"description": "this is a test"}
|
|
319
|
-
with
|
|
320
|
-
yaml_path = Path(yaml_file.name)
|
|
320
|
+
with yaml_path.open("w") as yaml_file:
|
|
321
321
|
yaml.safe_dump(data, yaml_file)
|
|
322
322
|
|
|
323
|
-
|
|
323
|
+
result = TrussConfig.from_yaml(yaml_path)
|
|
324
|
+
|
|
325
|
+
assert result.description == "this is a test"
|
|
324
326
|
|
|
325
|
-
|
|
327
|
+
yaml_path.unlink()
|
|
326
328
|
|
|
327
329
|
|
|
328
330
|
def test_from_yaml_empty():
|
|
331
|
+
yaml_path = Path("test.yaml")
|
|
329
332
|
data = {}
|
|
330
|
-
with
|
|
331
|
-
yaml_path = Path(yaml_file.name)
|
|
333
|
+
with yaml_path.open("w") as yaml_file:
|
|
332
334
|
yaml.safe_dump(data, yaml_file)
|
|
333
335
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
# test some attributes (should be default)
|
|
337
|
-
assert result.description is None
|
|
338
|
-
assert result.spec_version == "2.0"
|
|
339
|
-
assert result.bundled_packages_dir == "packages"
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
def test_from_yaml_secrets_as_list():
|
|
343
|
-
data = {"description": "this is a test", "secrets": ["foo", "bar"]}
|
|
344
|
-
with tempfile.NamedTemporaryFile(mode="w", delete=False) as yaml_file:
|
|
345
|
-
yaml_path = Path(yaml_file.name)
|
|
346
|
-
yaml.safe_dump(data, yaml_file)
|
|
347
|
-
|
|
348
|
-
with pytest.raises(ValueError):
|
|
349
|
-
TrussConfig.from_yaml(yaml_path)
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
def test_from_yaml_python_version():
|
|
353
|
-
yaml_path = Path("test.yaml")
|
|
354
|
-
invalid_py_version_data = {
|
|
355
|
-
"description": "this is a test",
|
|
356
|
-
"python_version": "py38",
|
|
357
|
-
}
|
|
358
|
-
with tempfile.NamedTemporaryFile(mode="w", delete=False) as yaml_file:
|
|
359
|
-
yaml_path = Path(yaml_file.name)
|
|
360
|
-
yaml.safe_dump(invalid_py_version_data, yaml_file)
|
|
361
|
-
|
|
362
|
-
with pytest.raises(ValueError):
|
|
363
|
-
TrussConfig.from_yaml(yaml_path)
|
|
336
|
+
result = TrussConfig.from_yaml(yaml_path)
|
|
364
337
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
338
|
+
# test some attributes (should be default)
|
|
339
|
+
assert result.description is None
|
|
340
|
+
assert result.spec_version == "2.0"
|
|
341
|
+
assert result.bundled_packages_dir == "packages"
|
|
369
342
|
|
|
370
|
-
|
|
371
|
-
result.python_version == "py39"
|
|
343
|
+
yaml_path.unlink()
|
|
@@ -39,8 +39,6 @@ DEFAULT_USE_GPU = False
|
|
|
39
39
|
|
|
40
40
|
DEFAULT_BLOB_BACKEND = HTTP_PUBLIC_BLOB_BACKEND
|
|
41
41
|
|
|
42
|
-
VALID_PYTHON_VERSIONS = ["py39", "py310", "py311"]
|
|
43
|
-
|
|
44
42
|
# Set up logging
|
|
45
43
|
logging.basicConfig(level=logging.INFO)
|
|
46
44
|
logger = logging.getLogger(__name__)
|
|
@@ -578,21 +576,6 @@ class TrussConfig:
|
|
|
578
576
|
return TrussConfig.from_dict(self.to_dict())
|
|
579
577
|
|
|
580
578
|
def validate(self):
|
|
581
|
-
if self.python_version not in VALID_PYTHON_VERSIONS:
|
|
582
|
-
|
|
583
|
-
raise ValueError(
|
|
584
|
-
f"Please ensure that `python_version` is one of {VALID_PYTHON_VERSIONS}"
|
|
585
|
-
)
|
|
586
|
-
|
|
587
|
-
if not isinstance(self.secrets, dict):
|
|
588
|
-
raise ValueError(
|
|
589
|
-
"Please ensure that `secrets` is a mapping of the form:\n"
|
|
590
|
-
"```\n"
|
|
591
|
-
"secrets:\n"
|
|
592
|
-
' secret1: "some default value"\n'
|
|
593
|
-
' secret2: "some other default value"\n'
|
|
594
|
-
"```"
|
|
595
|
-
)
|
|
596
579
|
for secret_name in self.secrets:
|
|
597
580
|
validate_secret_name(secret_name)
|
|
598
581
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import re
|
|
2
|
-
from pathlib import
|
|
2
|
+
from pathlib import Path
|
|
3
3
|
from typing import Pattern, Set
|
|
4
4
|
|
|
5
5
|
from truss.constants import REGISTRY_BUILD_SECRET_PREFIX
|
|
@@ -81,10 +81,9 @@ def _is_numeric(number_like: str) -> bool:
|
|
|
81
81
|
def validate_python_executable_path(path: str) -> None:
|
|
82
82
|
"""
|
|
83
83
|
This python executable path determines the python executable
|
|
84
|
-
used to run the inference server - check to see that it is an absolute path
|
|
85
|
-
We use PosixPath -- TrussServer always runs on a Posix machine.
|
|
84
|
+
used to run the inference server - check to see that it is an absolute path
|
|
86
85
|
"""
|
|
87
|
-
if path and not
|
|
86
|
+
if path and not Path(path).is_absolute():
|
|
88
87
|
raise ValidationError(
|
|
89
88
|
f"Invalid relative python executable path {path}. Provide an absolute path"
|
|
90
89
|
)
|
|
@@ -23,10 +23,10 @@ from truss_chains.definitions import (
|
|
|
23
23
|
)
|
|
24
24
|
from truss_chains.public_api import (
|
|
25
25
|
ChainletBase,
|
|
26
|
-
depends,
|
|
27
|
-
depends_context,
|
|
28
26
|
deploy_remotely,
|
|
29
27
|
entrypoint,
|
|
28
|
+
provide,
|
|
29
|
+
provide_context,
|
|
30
30
|
run_local,
|
|
31
31
|
)
|
|
32
32
|
from truss_chains.stub import StubBase
|
|
@@ -131,7 +131,7 @@ def _gen_chainlet_import_and_ref(
|
|
|
131
131
|
|
|
132
132
|
def _endpoint_signature_src(endpoint: definitions.EndpointAPIDescriptor) -> _Source:
|
|
133
133
|
"""
|
|
134
|
-
E.g.: `async def
|
|
134
|
+
E.g.: `async def run(self, data: str, num_partitions: int) -> tuple[list, int]:`
|
|
135
135
|
"""
|
|
136
136
|
if endpoint.is_generator:
|
|
137
137
|
# TODO: implement generator.
|
|
@@ -229,7 +229,7 @@ def _gen_stub_src(chainlet: definitions.ChainletAPIDescriptor) -> _Source:
|
|
|
229
229
|
def __init__(self, url: str, api_key: str) -> None:
|
|
230
230
|
self._remote = stub.BasetenSession(url, api_key)
|
|
231
231
|
|
|
232
|
-
async def
|
|
232
|
+
async def run(self, data: str, num_partitions: int) -> tuple[SplitTextOutput, int]:
|
|
233
233
|
json_args = {"inputs": inputs.dict(), "extra_arg": extra_arg}
|
|
234
234
|
json_result = await self._remote.predict_async(json_args)
|
|
235
235
|
return (SplitTextOutput.parse_obj(json_result[0]), json_result[1])
|
|
@@ -317,13 +317,10 @@ def _gen_load_src(chainlet_descriptor: definitions.ChainletAPIDescriptor) -> _So
|
|
|
317
317
|
# `dep.name` is the class name, while `name` is the argument name.
|
|
318
318
|
stub_args.append(f"{name}=stub.factory({dep.name}, self._context)")
|
|
319
319
|
|
|
320
|
-
if
|
|
321
|
-
|
|
322
|
-
init_args = f"{', '.join(stub_args)}, context=self._context"
|
|
323
|
-
else:
|
|
324
|
-
init_args = "context=self._context"
|
|
320
|
+
if stub_args:
|
|
321
|
+
init_args = f"context=self._context, {', '.join(stub_args)}"
|
|
325
322
|
else:
|
|
326
|
-
init_args = "
|
|
323
|
+
init_args = "context=self._context"
|
|
327
324
|
|
|
328
325
|
user_chainlet_ref = _gen_chainlet_import_and_ref(chainlet_descriptor)
|
|
329
326
|
imports.update(user_chainlet_ref.imports)
|
|
@@ -389,6 +386,7 @@ def _gen_predict_src(chainlet_descriptor: definitions.ChainletAPIDescriptor) ->
|
|
|
389
386
|
def _gen_truss_chainlet_model(
|
|
390
387
|
chainlet_descriptor: definitions.ChainletAPIDescriptor,
|
|
391
388
|
) -> _Source:
|
|
389
|
+
logging.info(f"Generating truss model for chainlet `{chainlet_descriptor.name}`.")
|
|
392
390
|
skeleton_tree = libcst.parse_module(
|
|
393
391
|
pathlib.Path(model_skeleton.__file__).read_text()
|
|
394
392
|
)
|
|
@@ -521,11 +519,10 @@ def _make_truss_config(
|
|
|
521
519
|
# Compute.
|
|
522
520
|
compute = chains_config.get_compute_spec()
|
|
523
521
|
config.resources.cpu = str(compute.cpu_count)
|
|
524
|
-
config.resources.memory = str(compute.memory)
|
|
525
522
|
config.resources.accelerator = compute.accelerator
|
|
526
523
|
config.resources.use_gpu = bool(compute.accelerator.count)
|
|
527
524
|
# TODO: expose this setting directly.
|
|
528
|
-
config.runtime.predict_concurrency = compute.
|
|
525
|
+
config.runtime.predict_concurrency = compute.cpu_count
|
|
529
526
|
# Image.
|
|
530
527
|
image = chains_config.docker_image
|
|
531
528
|
config.base_image = truss_config.BaseImage(image=image.base_image)
|
|
@@ -570,7 +567,6 @@ def gen_truss_chainlet(
|
|
|
570
567
|
gen_root: pathlib.Path,
|
|
571
568
|
) -> pathlib.Path:
|
|
572
569
|
# TODO: support file-based config (and/or merge file and python-src config values).
|
|
573
|
-
logging.info(f"Generating truss chainlet model for `{chainlet_descriptor.name}`.")
|
|
574
570
|
remote_config = chainlet_descriptor.chainlet_cls.remote_config
|
|
575
571
|
chainlet_name = remote_config.name or chainlet_descriptor.name
|
|
576
572
|
# Filter needed services and customize options.
|
|
@@ -10,15 +10,12 @@ from typing import (
|
|
|
10
10
|
ClassVar,
|
|
11
11
|
Generic,
|
|
12
12
|
Iterable,
|
|
13
|
-
Literal,
|
|
14
13
|
Mapping,
|
|
15
14
|
Optional,
|
|
16
|
-
Protocol,
|
|
17
15
|
Type,
|
|
18
16
|
TypeVar,
|
|
19
17
|
Union,
|
|
20
18
|
cast,
|
|
21
|
-
runtime_checkable,
|
|
22
19
|
)
|
|
23
20
|
|
|
24
21
|
import pydantic
|
|
@@ -27,37 +24,22 @@ from truss import truss_config
|
|
|
27
24
|
from truss.remote import baseten as baseten_remote
|
|
28
25
|
from truss.remote import remote_cli, remote_factory
|
|
29
26
|
|
|
30
|
-
UserConfigT = TypeVar("UserConfigT", bound=
|
|
27
|
+
UserConfigT = TypeVar("UserConfigT", bound=Optional[pydantic.BaseModel])
|
|
31
28
|
|
|
32
29
|
BASETEN_API_SECRET_NAME = "baseten_chain_api_key"
|
|
33
30
|
SECRET_DUMMY = "***"
|
|
34
31
|
TRUSS_CONFIG_CHAINS_KEY = "chains_metadata"
|
|
35
32
|
|
|
36
33
|
GENERATED_CODE_DIR = ".chains_generated"
|
|
34
|
+
PREDICT_ENDPOINT_NAME = "/predict"
|
|
37
35
|
|
|
38
36
|
# Below arg names must correspond to `definitions.ABCChainlet`.
|
|
39
|
-
ENDPOINT_METHOD_NAME = "
|
|
37
|
+
ENDPOINT_METHOD_NAME = "run" # Referring to Chainlet method name exposed as endpoint.
|
|
40
38
|
CONTEXT_ARG_NAME = "context" # Referring to Chainlets `__init__` signature.
|
|
41
39
|
SELF_ARG_NAME = "self"
|
|
42
40
|
REMOTE_CONFIG_NAME = "remote_config"
|
|
43
41
|
|
|
44
42
|
|
|
45
|
-
K = TypeVar("K", contravariant=True)
|
|
46
|
-
V = TypeVar("V", covariant=True)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
@runtime_checkable
|
|
50
|
-
class MappingNoIter(Protocol[K, V]):
|
|
51
|
-
def __getitem__(self, key: K) -> V:
|
|
52
|
-
...
|
|
53
|
-
|
|
54
|
-
def __len__(self) -> int:
|
|
55
|
-
...
|
|
56
|
-
|
|
57
|
-
def __contains__(self, key: K) -> bool:
|
|
58
|
-
...
|
|
59
|
-
|
|
60
|
-
|
|
61
43
|
class SafeModel(pydantic.BaseModel):
|
|
62
44
|
"""Pydantic base model with reasonable config."""
|
|
63
45
|
|
|
@@ -134,15 +116,10 @@ class DockerImage(SafeModelNonSerializable):
|
|
|
134
116
|
class ComputeSpec(pydantic.BaseModel):
|
|
135
117
|
# TODO: this is not stable yet and might change or refer back to truss.
|
|
136
118
|
cpu_count: int = 1
|
|
137
|
-
predict_concurrency: int = 1
|
|
138
119
|
memory: str = "2Gi"
|
|
139
120
|
accelerator: truss_config.AcceleratorSpec = truss_config.AcceleratorSpec()
|
|
140
121
|
|
|
141
122
|
|
|
142
|
-
CpuCountT = Literal["cpu_count"]
|
|
143
|
-
CPU_COUNT: CpuCountT = "cpu_count"
|
|
144
|
-
|
|
145
|
-
|
|
146
123
|
class Compute:
|
|
147
124
|
"""Builder to create ComputeSpec."""
|
|
148
125
|
|
|
@@ -156,7 +133,6 @@ class Compute:
|
|
|
156
133
|
memory: str = "2Gi",
|
|
157
134
|
gpu: Union[str, truss_config.Accelerator, None] = None,
|
|
158
135
|
gpu_count: int = 1,
|
|
159
|
-
predict_concurrency: Union[int, CpuCountT] = 1,
|
|
160
136
|
) -> None:
|
|
161
137
|
accelerator = truss_config.AcceleratorSpec()
|
|
162
138
|
if gpu:
|
|
@@ -165,17 +141,9 @@ class Compute:
|
|
|
165
141
|
accelerator = truss_config.AcceleratorSpec(
|
|
166
142
|
accelerator=truss_config.Accelerator(gpu), count=gpu_count
|
|
167
143
|
)
|
|
168
|
-
if predict_concurrency == CPU_COUNT:
|
|
169
|
-
predict_concurrency_int = cpu_count
|
|
170
|
-
else:
|
|
171
|
-
assert isinstance(predict_concurrency, int)
|
|
172
|
-
predict_concurrency_int = predict_concurrency
|
|
173
144
|
|
|
174
145
|
self._spec = ComputeSpec(
|
|
175
|
-
cpu_count=cpu_count,
|
|
176
|
-
memory=memory,
|
|
177
|
-
accelerator=accelerator,
|
|
178
|
-
predict_concurrency=predict_concurrency_int,
|
|
146
|
+
cpu_count=cpu_count, memory=memory, accelerator=accelerator
|
|
179
147
|
)
|
|
180
148
|
|
|
181
149
|
def get_spec(self) -> ComputeSpec:
|
|
@@ -210,7 +178,7 @@ class Assets:
|
|
|
210
178
|
class RemoteConfig(SafeModelNonSerializable):
|
|
211
179
|
"""Bundles config values needed to deploy a Chainlet."""
|
|
212
180
|
|
|
213
|
-
docker_image: DockerImage
|
|
181
|
+
docker_image: DockerImage
|
|
214
182
|
compute: Compute = Compute()
|
|
215
183
|
assets: Assets = Assets()
|
|
216
184
|
name: Optional[str] = None
|
|
@@ -243,9 +211,13 @@ class DeploymentContext(generics.GenericModel, Generic[UserConfigT]):
|
|
|
243
211
|
extra = "forbid"
|
|
244
212
|
|
|
245
213
|
data_dir: Optional[pathlib.Path] = None
|
|
246
|
-
user_config: UserConfigT
|
|
214
|
+
user_config: UserConfigT = pydantic.Field(default=None)
|
|
247
215
|
chainlet_to_service: Mapping[str, ServiceDescriptor] = {}
|
|
248
|
-
secrets:
|
|
216
|
+
# secrets: Optional[secrets_resolver.Secrets] = None
|
|
217
|
+
# TODO: above type results in `truss.server.shared.secrets_resolver.Secrets`
|
|
218
|
+
# due to the templating, at runtime the object passed will be from
|
|
219
|
+
# `shared.secrets_resolver` and give pydantic validation error.
|
|
220
|
+
secrets: Any = None
|
|
249
221
|
|
|
250
222
|
def get_service_descriptor(self, chainlet_name: str) -> ServiceDescriptor:
|
|
251
223
|
if chainlet_name not in self.chainlet_to_service:
|
|
@@ -277,24 +249,30 @@ class DeploymentContext(generics.GenericModel, Generic[UserConfigT]):
|
|
|
277
249
|
class TrussMetadata(generics.GenericModel, Generic[UserConfigT]):
|
|
278
250
|
"""Plugin for the truss config (in config["model_metadata"]["chains_metadata"])."""
|
|
279
251
|
|
|
280
|
-
user_config: UserConfigT
|
|
252
|
+
user_config: UserConfigT = pydantic.Field(default=None)
|
|
281
253
|
chainlet_to_service: Mapping[str, ServiceDescriptor] = {}
|
|
282
254
|
|
|
283
255
|
|
|
284
|
-
class ABCChainlet(abc.ABC):
|
|
285
|
-
remote_config: ClassVar[RemoteConfig]
|
|
256
|
+
class ABCChainlet(Generic[UserConfigT], abc.ABC):
|
|
257
|
+
remote_config: ClassVar[RemoteConfig]
|
|
286
258
|
default_user_config: ClassVar[Optional[pydantic.BaseModel]] = None
|
|
287
259
|
_init_is_patched: ClassVar[bool] = False
|
|
288
260
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
261
|
+
_context: DeploymentContext[UserConfigT]
|
|
262
|
+
|
|
263
|
+
@abc.abstractmethod
|
|
264
|
+
def __init__(self, context: DeploymentContext[UserConfigT]) -> None:
|
|
265
|
+
...
|
|
292
266
|
|
|
293
267
|
# Cannot add this abstract method to API, because we want to allow arbitrary
|
|
294
268
|
# arg/kwarg names and specifying any function signature here would give type errors
|
|
295
269
|
# @abc.abstractmethod
|
|
296
|
-
# def
|
|
297
|
-
|
|
270
|
+
# def run(self, *args, **kwargs) -> Any: ...
|
|
271
|
+
|
|
272
|
+
@property
|
|
273
|
+
@abc.abstractmethod
|
|
274
|
+
def user_config(self) -> UserConfigT:
|
|
275
|
+
...
|
|
298
276
|
|
|
299
277
|
|
|
300
278
|
class TypeDescriptor(SafeModelNonSerializable):
|
|
@@ -331,7 +309,6 @@ class DependencyDescriptor(SafeModelNonSerializable):
|
|
|
331
309
|
class ChainletAPIDescriptor(SafeModelNonSerializable):
|
|
332
310
|
chainlet_cls: Type[ABCChainlet]
|
|
333
311
|
src_path: str
|
|
334
|
-
has_context: bool
|
|
335
312
|
dependencies: Mapping[str, DependencyDescriptor]
|
|
336
313
|
endpoint: EndpointAPIDescriptor
|
|
337
314
|
user_config_type: TypeDescriptor
|
|
@@ -149,7 +149,7 @@ class ChainService:
|
|
|
149
149
|
def run_url(self) -> str:
|
|
150
150
|
return self.get_entrypoint.predict_url
|
|
151
151
|
|
|
152
|
-
def
|
|
152
|
+
def run(self, json: Dict) -> Any:
|
|
153
153
|
return self.get_entrypoint.predict(json)
|
|
154
154
|
|
|
155
155
|
def get_info(self) -> list[tuple[str, str, str]]:
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import truss_chains as chains
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class DummyGenerateData(chains.ChainletBase):
|
|
5
|
+
remote_config = chains.RemoteConfig(docker_image=chains.DockerImage())
|
|
6
|
+
|
|
7
|
+
def run(self) -> str:
|
|
8
|
+
return "abc"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Nesting the classes is a hack to make it *appear* like SplitText is from a different
|
|
12
|
+
# module.
|
|
13
|
+
class shared_chainlet:
|
|
14
|
+
class DummySplitText(chains.ChainletBase):
|
|
15
|
+
remote_config = chains.RemoteConfig(docker_image=chains.DockerImage())
|
|
16
|
+
|
|
17
|
+
def run(self, data: str) -> list[str]:
|
|
18
|
+
return [data[:2], data[2:]]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class DummyExample(chains.ChainletBase):
|
|
22
|
+
remote_config = chains.RemoteConfig(docker_image=chains.DockerImage())
|
|
23
|
+
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
context: chains.DeploymentContext = chains.provide_context(),
|
|
27
|
+
data_generator: DummyGenerateData = chains.provide(DummyGenerateData),
|
|
28
|
+
splitter: shared_chainlet.DummySplitText = chains.provide(
|
|
29
|
+
shared_chainlet.DummySplitText
|
|
30
|
+
),
|
|
31
|
+
) -> None:
|
|
32
|
+
super().__init__(context)
|
|
33
|
+
self._data_generator = data_generator
|
|
34
|
+
self._data_splitter = splitter
|
|
35
|
+
|
|
36
|
+
def run(self) -> list[str]:
|
|
37
|
+
return self._data_splitter.run(self._data_generator.run())
|