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.
Files changed (237) hide show
  1. {truss-0.9.12 → truss-0.9.12.dev2}/PKG-INFO +1 -1
  2. {truss-0.9.12 → truss-0.9.12.dev2}/pyproject.toml +2 -2
  3. {truss-0.9.12 → truss-0.9.12.dev2}/truss/cli/cli.py +11 -11
  4. {truss-0.9.12 → truss-0.9.12.dev2}/truss/config/trt_llm.py +1 -1
  5. {truss-0.9.12 → truss-0.9.12.dev2}/truss/constants.py +1 -1
  6. {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/service.py +1 -1
  7. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_basic_truss/config.yaml +1 -3
  8. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_config.py +14 -42
  9. {truss-0.9.12 → truss-0.9.12.dev2}/truss/truss_config.py +0 -17
  10. {truss-0.9.12 → truss-0.9.12.dev2}/truss/validation.py +3 -4
  11. {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/__init__.py +2 -2
  12. {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/code_gen.py +7 -11
  13. {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/definitions.py +25 -48
  14. {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/deploy.py +1 -1
  15. truss-0.9.12.dev2/truss-chains/truss_chains/example_chainlet.py +37 -0
  16. {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/framework.py +135 -209
  17. {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/model_skeleton.py +1 -1
  18. truss-0.9.12.dev2/truss-chains/truss_chains/public_api.py +73 -0
  19. {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/stub.py +1 -1
  20. {truss-0.9.12 → truss-0.9.12.dev2}/truss-chains/truss_chains/utils.py +1 -0
  21. truss-0.9.12/truss-chains/truss_chains/example_chainlet.py +0 -30
  22. truss-0.9.12/truss-chains/truss_chains/public_api.py +0 -84
  23. {truss-0.9.12 → truss-0.9.12.dev2}/CODE_OF_CONDUCT.md +0 -0
  24. {truss-0.9.12 → truss-0.9.12.dev2}/CONTRIBUTING.md +0 -0
  25. {truss-0.9.12 → truss-0.9.12.dev2}/LICENSE +0 -0
  26. {truss-0.9.12 → truss-0.9.12.dev2}/README.md +0 -0
  27. {truss-0.9.12 → truss-0.9.12.dev2}/context_builder.Dockerfile +0 -0
  28. {truss-0.9.12 → truss-0.9.12.dev2}/truss/__init__.py +0 -0
  29. {truss-0.9.12 → truss-0.9.12.dev2}/truss/blob/blob_backend.py +0 -0
  30. {truss-0.9.12 → truss-0.9.12.dev2}/truss/blob/blob_backend_registry.py +0 -0
  31. {truss-0.9.12 → truss-0.9.12.dev2}/truss/blob/http_public_blob_backend.py +0 -0
  32. {truss-0.9.12 → truss-0.9.12.dev2}/truss/build.py +0 -0
  33. {truss-0.9.12 → truss-0.9.12.dev2}/truss/cli/__init__.py +0 -0
  34. {truss-0.9.12 → truss-0.9.12.dev2}/truss/cli/console.py +0 -0
  35. {truss-0.9.12 → truss-0.9.12.dev2}/truss/cli/create.py +0 -0
  36. {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/image_builder/cache_warmer.py +0 -0
  37. {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/image_builder/image_builder.py +0 -0
  38. {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/image_builder/serving_image_builder.py +0 -0
  39. {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/image_builder/util.py +0 -0
  40. {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/local_loader/docker_build_emulator.py +0 -0
  41. {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/local_loader/load_model_local.py +0 -0
  42. {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/local_loader/truss_module_loader.py +0 -0
  43. {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/local_loader/utils.py +0 -0
  44. {truss-0.9.12 → truss-0.9.12.dev2}/truss/contexts/truss_context.py +0 -0
  45. {truss-0.9.12 → truss-0.9.12.dev2}/truss/decorators.py +0 -0
  46. {truss-0.9.12 → truss-0.9.12.dev2}/truss/docker.py +0 -0
  47. {truss-0.9.12 → truss-0.9.12.dev2}/truss/errors.py +0 -0
  48. {truss-0.9.12 → truss-0.9.12.dev2}/truss/local/local_config.py +0 -0
  49. {truss-0.9.12 → truss-0.9.12.dev2}/truss/local/local_config_handler.py +0 -0
  50. {truss-0.9.12 → truss-0.9.12.dev2}/truss/model_inference.py +0 -0
  51. {truss-0.9.12 → truss-0.9.12.dev2}/truss/notebook.py +0 -0
  52. {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/calc_patch.py +0 -0
  53. {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/constants.py +0 -0
  54. {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/dir_signature.py +0 -0
  55. {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/hash.py +0 -0
  56. {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/local_truss_patch_applier.py +0 -0
  57. {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/signature.py +0 -0
  58. {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/truss_dir_patch_applier.py +0 -0
  59. {truss-0.9.12 → truss-0.9.12.dev2}/truss/patch/types.py +0 -0
  60. {truss-0.9.12 → truss-0.9.12.dev2}/truss/readme_generator.py +0 -0
  61. {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/__init__.py +0 -0
  62. {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/api.py +0 -0
  63. {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/auth.py +0 -0
  64. {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/core.py +0 -0
  65. {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/error.py +0 -0
  66. {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/remote.py +0 -0
  67. {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/utils/tar.py +0 -0
  68. {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/baseten/utils/transfer.py +0 -0
  69. {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/remote_cli.py +0 -0
  70. {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/remote_factory.py +0 -0
  71. {truss-0.9.12 → truss-0.9.12.dev2}/truss/remote/truss_remote.py +0 -0
  72. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/README.md.jinja +0 -0
  73. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/__init__.py +0 -0
  74. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/base.Dockerfile.jinja +0 -0
  75. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/cache.Dockerfile.jinja +0 -0
  76. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/cache_requirements.txt +0 -0
  77. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/application.py +0 -0
  78. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/endpoints.py +0 -0
  79. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/context_managers.py +0 -0
  80. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/errors.py +0 -0
  81. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/inference_server_controller.py +0 -0
  82. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/inference_server_process_controller.py +0 -0
  83. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/inference_server_starter.py +0 -0
  84. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/truss_patch/__init__.py +0 -0
  85. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/truss_patch/model_code_patch_applier.py +0 -0
  86. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/truss_patch/model_container_patch_applier.py +0 -0
  87. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/truss_patch/requirement_name_identifier.py +0 -0
  88. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/truss_patch/system_packages.py +0 -0
  89. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/helpers/types.py +0 -0
  90. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/control/server.py +0 -0
  91. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/control/requirements.txt +0 -0
  92. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/copy_cache_files.Dockerfile.jinja +0 -0
  93. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/custom/examples.yaml +0 -0
  94. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/custom/model/__init__.py +0 -0
  95. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/custom/model/model.py +0 -0
  96. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/__init__.py +0 -0
  97. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/__init__.py +0 -0
  98. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/errors.py +0 -0
  99. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/patches/whisper/patch.py +0 -0
  100. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/patches.py +0 -0
  101. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/retry.py +0 -0
  102. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/schema.py +0 -0
  103. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/termination_handler_middleware.py +0 -0
  104. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/common/truss_server.py +0 -0
  105. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/inference_server.py +0 -0
  106. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/model_wrapper.py +0 -0
  107. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server/requirements.txt +0 -0
  108. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/server.Dockerfile.jinja +0 -0
  109. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/shared/README.md +0 -0
  110. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/shared/__init__.py +0 -0
  111. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/shared/logging.py +0 -0
  112. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/shared/secrets_resolver.py +0 -0
  113. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/shared/serialization.py +0 -0
  114. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/shared/util.py +0 -0
  115. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/README.md +0 -0
  116. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/model/model.py +0 -0
  117. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/constants.py +0 -0
  118. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/schema.py +0 -0
  119. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/tensorrt_llm_model_repository/ensemble/config.pbtxt +0 -0
  120. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/tensorrt_llm_model_repository/postprocessing/1/model.py +0 -0
  121. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/tensorrt_llm_model_repository/postprocessing/config.pbtxt +0 -0
  122. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/tensorrt_llm_model_repository/preprocessing/1/model.py +0 -0
  123. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/tensorrt_llm_model_repository/preprocessing/config.pbtxt +0 -0
  124. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/tensorrt_llm_model_repository/tensorrt_llm/config.pbtxt +0 -0
  125. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/triton_client.py +0 -0
  126. {truss-0.9.12 → truss-0.9.12.dev2}/truss/templates/trtllm/packages/utils.py +0 -0
  127. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/annotated_types_truss/config.yaml +0 -0
  128. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/annotated_types_truss/model/__init__.py +0 -0
  129. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/annotated_types_truss/model/model.py +0 -0
  130. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/auto-mpg.data +0 -0
  131. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/context_builder_image_test/Dockerfile +0 -0
  132. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/context_builder_image_test/test.py +0 -0
  133. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/gcs_fix/config.yaml +0 -0
  134. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/gcs_fix/model/__init__.py +0 -0
  135. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/gcs_fix/model/model.py +0 -0
  136. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/happy.ipynb +0 -0
  137. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/model_load_failure_test/config.yaml +0 -0
  138. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/model_load_failure_test/model/model.py +0 -0
  139. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/patch_ping_test_server/app.py +0 -0
  140. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/pima-indians-diabetes.csv +0 -0
  141. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/readme_int_example.md +0 -0
  142. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/readme_no_example.md +0 -0
  143. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/readme_str_example.md +0 -0
  144. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/server.Dockerfile +0 -0
  145. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/server_conformance_test_truss/config.yaml +0 -0
  146. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/server_conformance_test_truss/model/__init__.py +0 -0
  147. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/server_conformance_test_truss/model/model.py +0 -0
  148. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_async_truss/config.yaml +0 -0
  149. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_async_truss/model/model.py +0 -0
  150. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_basic_truss/model/__init__.py +0 -0
  151. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_basic_truss/model/model.py +0 -0
  152. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_concurrency_truss/config.yaml +0 -0
  153. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_concurrency_truss/model/model.py +0 -0
  154. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v1/config.yaml +0 -0
  155. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v1/model/__init__.py +0 -0
  156. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v1/model/model.py +0 -0
  157. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v1/requirements.txt +0 -0
  158. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v2/config.yaml +0 -0
  159. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v2/model/__init__.py +0 -0
  160. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v2/model/model.py +0 -0
  161. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_pyantic_v2/requirements.txt +0 -0
  162. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_requirements_file_truss/config.yaml +0 -0
  163. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_requirements_file_truss/model/__init__.py +0 -0
  164. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_requirements_file_truss/model/model.py +0 -0
  165. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_requirements_file_truss/requirements.txt +0 -0
  166. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_async_generator_truss/config.yaml +0 -0
  167. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_async_generator_truss/model/model.py +0 -0
  168. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_read_timeout/config.yaml +0 -0
  169. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_read_timeout/model/model.py +0 -0
  170. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_truss/config.yaml +0 -0
  171. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_truss/model/model.py +0 -0
  172. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_truss_with_error/config.yaml +0 -0
  173. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_streaming_truss_with_error/model/model.py +0 -0
  174. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss/config.yaml +0 -0
  175. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss/examples.yaml +0 -0
  176. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss/model/__init__.py +0 -0
  177. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss/model/dummy +0 -0
  178. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss/model/model.py +0 -0
  179. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss/packages/test_package/test.py +0 -0
  180. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss_server_caching_truss/config.yaml +0 -0
  181. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss_server_caching_truss/model/__init__.py +0 -0
  182. {truss-0.9.12 → truss-0.9.12.dev2}/truss/test_data/test_truss_server_caching_truss/model/model.py +0 -0
  183. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/__init__.py +0 -0
  184. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/conftest.py +0 -0
  185. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/contexts/image_builder/test_serving_image_builder.py +0 -0
  186. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/contexts/local_loader/test_load_local.py +0 -0
  187. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/contexts/local_loader/test_truss_module_finder.py +0 -0
  188. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/helpers.py +0 -0
  189. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/local/__init__.py +0 -0
  190. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/local/test_local_config_handler.py +0 -0
  191. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/patch/test_calc_patch.py +0 -0
  192. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/patch/test_dir_signature.py +0 -0
  193. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/patch/test_hash.py +0 -0
  194. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/patch/test_signature.py +0 -0
  195. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/patch/test_truss_dir_patch_applier.py +0 -0
  196. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/patch/test_types.py +0 -0
  197. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/remote/baseten/test_api.py +0 -0
  198. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/remote/baseten/test_auth.py +0 -0
  199. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/remote/baseten/test_core.py +0 -0
  200. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/remote/baseten/test_remote.py +0 -0
  201. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/remote/test_remote_factory.py +0 -0
  202. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/remote/test_truss_remote.py +0 -0
  203. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/control/control/helpers/test_context_managers.py +0 -0
  204. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/control/control/helpers/test_model_container_patch_applier.py +0 -0
  205. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/control/control/helpers/test_requirement_name_identifier.py +0 -0
  206. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/control/control/test_server.py +0 -0
  207. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/control/control/test_server_integration.py +0 -0
  208. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/core/server/common/test_truss_server.py +0 -0
  209. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/core/server/common/test_util.py +0 -0
  210. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/core/server/test_secrets_resolver.py +0 -0
  211. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/server/common/test_retry.py +0 -0
  212. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/server/common/test_termination_handler_middleware.py +0 -0
  213. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/server/test_model_wrapper.py +0 -0
  214. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/templates/server/test_schema.py +0 -0
  215. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_build.py +0 -0
  216. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_context_builder_image.py +0 -0
  217. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_control_truss_patching.py +0 -0
  218. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_docker.py +0 -0
  219. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_model_inference.py +0 -0
  220. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_model_schema.py +0 -0
  221. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_testing_utilities_for_other_tests.py +0 -0
  222. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_truss_gatherer.py +0 -0
  223. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_truss_handle.py +0 -0
  224. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_util.py +0 -0
  225. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/test_validation.py +0 -0
  226. {truss-0.9.12 → truss-0.9.12.dev2}/truss/tests/util/test_path.py +0 -0
  227. {truss-0.9.12 → truss-0.9.12.dev2}/truss/truss_gatherer.py +0 -0
  228. {truss-0.9.12 → truss-0.9.12.dev2}/truss/truss_handle.py +0 -0
  229. {truss-0.9.12 → truss-0.9.12.dev2}/truss/truss_spec.py +0 -0
  230. {truss-0.9.12 → truss-0.9.12.dev2}/truss/types.py +0 -0
  231. {truss-0.9.12 → truss-0.9.12.dev2}/truss/util/.truss_ignore +0 -0
  232. {truss-0.9.12 → truss-0.9.12.dev2}/truss/util/data_structures.py +0 -0
  233. {truss-0.9.12 → truss-0.9.12.dev2}/truss/util/download.py +0 -0
  234. {truss-0.9.12 → truss-0.9.12.dev2}/truss/util/errors.py +0 -0
  235. {truss-0.9.12 → truss-0.9.12.dev2}/truss/util/gpu.py +0 -0
  236. {truss-0.9.12 → truss-0.9.12.dev2}/truss/util/jinja.py +0 -0
  237. {truss-0.9.12 → truss-0.9.12.dev2}/truss/util/path.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: truss
3
- Version: 0.9.12
3
+ Version: 0.9.12.dev2
4
4
  Summary: A seamless bridge from model development to model delivery
5
5
  Home-page: https://github.com/basetenlabs/truss
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "truss"
3
- version = "0.9.12"
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
- plugins = ["pydantic.mypy"]
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
- gemm_plugin: str = "float16"
32
+ use_fused_mlp: bool = False
33
33
 
34
34
 
35
35
  class CheckpointSource(Enum):
@@ -104,6 +104,6 @@ BASE_TRTLLM_REQUIREMENTS = [
104
104
  "tritonclient[all]==2.42.0",
105
105
  "transformers==4.40.2",
106
106
  "jinja2==3.1.3",
107
- "truss==0.9.12",
107
+ "truss==0.9.11",
108
108
  ]
109
109
  OPENAI_COMPATIBLE_TAG = "openai-compatible"
@@ -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()
@@ -9,7 +9,5 @@ resources:
9
9
  cpu: '1'
10
10
  memory: 2Gi
11
11
  use_gpu: false
12
- secrets:
13
- foo: "foo"
14
- bar: "bar"
12
+ secrets: {}
15
13
  system_packages: []
@@ -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 tempfile.NamedTemporaryFile(mode="w", delete=False) as yaml_file:
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
- result = TrussConfig.from_yaml(yaml_path)
323
+ result = TrussConfig.from_yaml(yaml_path)
324
+
325
+ assert result.description == "this is a test"
324
326
 
325
- assert result.description == "this is a test"
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 tempfile.NamedTemporaryFile(mode="w", delete=False) as yaml_file:
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
- result = TrussConfig.from_yaml(yaml_path)
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
- valid_py_version_data = {"description": "this is a test", "python_version": "py39"}
366
- with tempfile.NamedTemporaryFile(mode="w", delete=False) as yaml_file:
367
- yaml_path = Path(yaml_file.name)
368
- yaml.safe_dump(valid_py_version_data, yaml_file)
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
- result = TrussConfig.from_yaml(yaml_path)
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 PosixPath
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 PosixPath(path).is_absolute():
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 run_remote(self, data: str, num_partitions: int) -> tuple[list, int]:`
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 run_remote(self, data: str, num_partitions: int) -> tuple[SplitTextOutput, int]:
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 chainlet_descriptor.has_context:
321
- if stub_args:
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 = ", ".join(stub_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.predict_concurrency
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=Union[pydantic.BaseModel, None])
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 = "run_remote" # Chainlet method name exposed as endpoint.
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 = 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: MappingNoIter[str, str]
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] = RemoteConfig(docker_image=DockerImage())
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
- @classmethod
290
- def has_custom_init(cls) -> bool:
291
- return cls.__init__ is not object.__init__
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 run_remote(self, *args, **kwargs) -> Any:
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 run_remote(self, json: Dict) -> Any:
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())