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.

Files changed (362) hide show
  1. truss/__init__.py +10 -3
  2. truss/api/__init__.py +123 -0
  3. truss/api/definitions.py +51 -0
  4. truss/base/constants.py +116 -0
  5. truss/base/custom_types.py +29 -0
  6. truss/{errors.py → base/errors.py} +4 -0
  7. truss/base/trt_llm_config.py +310 -0
  8. truss/{truss_config.py → base/truss_config.py} +344 -31
  9. truss/{truss_spec.py → base/truss_spec.py} +20 -6
  10. truss/{validation.py → base/validation.py} +60 -11
  11. truss/cli/cli.py +841 -88
  12. truss/{remote → cli}/remote_cli.py +2 -7
  13. truss/contexts/docker_build_setup.py +67 -0
  14. truss/contexts/image_builder/cache_warmer.py +2 -8
  15. truss/contexts/image_builder/image_builder.py +1 -1
  16. truss/contexts/image_builder/serving_image_builder.py +292 -46
  17. truss/contexts/image_builder/util.py +1 -3
  18. truss/contexts/local_loader/docker_build_emulator.py +58 -0
  19. truss/contexts/local_loader/load_model_local.py +2 -2
  20. truss/contexts/local_loader/truss_module_loader.py +1 -1
  21. truss/contexts/local_loader/utils.py +1 -1
  22. truss/local/local_config.py +2 -6
  23. truss/local/local_config_handler.py +20 -5
  24. truss/patch/__init__.py +1 -0
  25. truss/patch/hash.py +4 -70
  26. truss/patch/signature.py +4 -16
  27. truss/patch/truss_dir_patch_applier.py +3 -78
  28. truss/remote/baseten/api.py +308 -23
  29. truss/remote/baseten/auth.py +3 -3
  30. truss/remote/baseten/core.py +257 -50
  31. truss/remote/baseten/custom_types.py +44 -0
  32. truss/remote/baseten/error.py +4 -0
  33. truss/remote/baseten/remote.py +369 -118
  34. truss/remote/baseten/service.py +118 -11
  35. truss/remote/baseten/utils/status.py +29 -0
  36. truss/remote/baseten/utils/tar.py +34 -22
  37. truss/remote/baseten/utils/transfer.py +36 -23
  38. truss/remote/remote_factory.py +14 -5
  39. truss/remote/truss_remote.py +72 -45
  40. truss/templates/base.Dockerfile.jinja +18 -16
  41. truss/templates/cache.Dockerfile.jinja +3 -3
  42. truss/{server → templates/control}/control/application.py +14 -35
  43. truss/{server → templates/control}/control/endpoints.py +39 -9
  44. truss/{server/control/patch/types.py → templates/control/control/helpers/custom_types.py} +13 -52
  45. truss/{server → templates/control}/control/helpers/inference_server_controller.py +4 -8
  46. truss/{server → templates/control}/control/helpers/inference_server_process_controller.py +2 -4
  47. truss/{server → templates/control}/control/helpers/inference_server_starter.py +5 -10
  48. truss/{server/control → templates/control/control/helpers}/truss_patch/model_code_patch_applier.py +8 -6
  49. truss/{server/control/patch → templates/control/control/helpers/truss_patch}/model_container_patch_applier.py +18 -26
  50. truss/templates/control/control/helpers/truss_patch/requirement_name_identifier.py +66 -0
  51. truss/{server → templates/control}/control/server.py +11 -6
  52. truss/templates/control/requirements.txt +9 -0
  53. truss/templates/custom_python_dx/my_model.py +28 -0
  54. truss/templates/docker_server/proxy.conf.jinja +42 -0
  55. truss/templates/docker_server/supervisord.conf.jinja +27 -0
  56. truss/templates/docker_server_requirements.txt +1 -0
  57. truss/templates/server/common/errors.py +231 -0
  58. truss/{server → templates/server}/common/patches/whisper/patch.py +1 -0
  59. truss/{server/common/patches/__init__.py → templates/server/common/patches.py} +1 -3
  60. truss/{server → templates/server}/common/retry.py +1 -0
  61. truss/{server → templates/server}/common/schema.py +11 -9
  62. truss/templates/server/common/tracing.py +157 -0
  63. truss/templates/server/main.py +9 -0
  64. truss/templates/server/model_wrapper.py +961 -0
  65. truss/templates/server/requirements.txt +21 -0
  66. truss/templates/server/truss_server.py +447 -0
  67. truss/templates/server.Dockerfile.jinja +62 -14
  68. truss/templates/shared/dynamic_config_resolver.py +28 -0
  69. truss/templates/shared/lazy_data_resolver.py +164 -0
  70. truss/templates/shared/log_config.py +125 -0
  71. truss/{server → templates}/shared/secrets_resolver.py +1 -2
  72. truss/{server → templates}/shared/serialization.py +31 -9
  73. truss/{server → templates}/shared/util.py +3 -13
  74. truss/templates/trtllm-audio/model/model.py +49 -0
  75. truss/templates/trtllm-audio/packages/sigint_patch.py +14 -0
  76. truss/templates/trtllm-audio/packages/whisper_trt/__init__.py +215 -0
  77. truss/templates/trtllm-audio/packages/whisper_trt/assets.py +25 -0
  78. truss/templates/trtllm-audio/packages/whisper_trt/batching.py +52 -0
  79. truss/templates/trtllm-audio/packages/whisper_trt/custom_types.py +26 -0
  80. truss/templates/trtllm-audio/packages/whisper_trt/modeling.py +184 -0
  81. truss/templates/trtllm-audio/packages/whisper_trt/tokenizer.py +185 -0
  82. truss/templates/trtllm-audio/packages/whisper_trt/utils.py +245 -0
  83. truss/templates/trtllm-briton/src/extension.py +64 -0
  84. truss/tests/conftest.py +302 -94
  85. truss/tests/contexts/image_builder/test_serving_image_builder.py +74 -31
  86. truss/tests/contexts/local_loader/test_load_local.py +2 -2
  87. truss/tests/contexts/local_loader/test_truss_module_finder.py +1 -1
  88. truss/tests/patch/test_calc_patch.py +439 -127
  89. truss/tests/patch/test_dir_signature.py +3 -12
  90. truss/tests/patch/test_hash.py +1 -1
  91. truss/tests/patch/test_signature.py +1 -1
  92. truss/tests/patch/test_truss_dir_patch_applier.py +23 -11
  93. truss/tests/patch/test_types.py +2 -2
  94. truss/tests/remote/baseten/test_api.py +153 -58
  95. truss/tests/remote/baseten/test_auth.py +2 -1
  96. truss/tests/remote/baseten/test_core.py +160 -12
  97. truss/tests/remote/baseten/test_remote.py +489 -77
  98. truss/tests/remote/baseten/test_service.py +55 -0
  99. truss/tests/remote/test_remote_factory.py +16 -18
  100. truss/tests/remote/test_truss_remote.py +26 -17
  101. truss/tests/templates/control/control/helpers/test_context_managers.py +11 -0
  102. truss/tests/templates/control/control/helpers/test_model_container_patch_applier.py +184 -0
  103. truss/tests/templates/control/control/helpers/test_requirement_name_identifier.py +89 -0
  104. truss/tests/{server → templates/control}/control/test_server.py +79 -24
  105. truss/tests/{server → templates/control}/control/test_server_integration.py +24 -16
  106. truss/tests/templates/core/server/test_dynamic_config_resolver.py +108 -0
  107. truss/tests/templates/core/server/test_lazy_data_resolver.py +329 -0
  108. truss/tests/templates/core/server/test_lazy_data_resolver_v2.py +79 -0
  109. truss/tests/{server → templates}/core/server/test_secrets_resolver.py +1 -1
  110. truss/tests/{server → templates/server}/common/test_retry.py +3 -3
  111. truss/tests/templates/server/test_model_wrapper.py +248 -0
  112. truss/tests/{server → templates/server}/test_schema.py +3 -5
  113. truss/tests/{server/core/server/common → templates/server}/test_truss_server.py +8 -5
  114. truss/tests/test_build.py +9 -52
  115. truss/tests/test_config.py +336 -77
  116. truss/tests/test_context_builder_image.py +3 -11
  117. truss/tests/test_control_truss_patching.py +7 -12
  118. truss/tests/test_custom_server.py +38 -0
  119. truss/tests/test_data/context_builder_image_test/test.py +3 -0
  120. truss/tests/test_data/happy.ipynb +56 -0
  121. truss/tests/test_data/model_load_failure_test/config.yaml +2 -0
  122. truss/tests/test_data/model_load_failure_test/model/__init__.py +0 -0
  123. truss/tests/test_data/patch_ping_test_server/__init__.py +0 -0
  124. truss/{test_data → tests/test_data}/patch_ping_test_server/app.py +3 -9
  125. truss/{test_data → tests/test_data}/server.Dockerfile +20 -21
  126. truss/tests/test_data/server_conformance_test_truss/__init__.py +0 -0
  127. truss/tests/test_data/server_conformance_test_truss/model/__init__.py +0 -0
  128. truss/{test_data → tests/test_data}/server_conformance_test_truss/model/model.py +1 -3
  129. truss/tests/test_data/test_async_truss/__init__.py +0 -0
  130. truss/tests/test_data/test_async_truss/model/__init__.py +0 -0
  131. truss/tests/test_data/test_basic_truss/__init__.py +0 -0
  132. truss/tests/test_data/test_basic_truss/config.yaml +16 -0
  133. truss/tests/test_data/test_basic_truss/model/__init__.py +0 -0
  134. truss/tests/test_data/test_build_commands/__init__.py +0 -0
  135. truss/tests/test_data/test_build_commands/config.yaml +13 -0
  136. truss/tests/test_data/test_build_commands/model/__init__.py +0 -0
  137. truss/{test_data/test_streaming_async_generator_truss → tests/test_data/test_build_commands}/model/model.py +2 -3
  138. truss/tests/test_data/test_build_commands_failure/__init__.py +0 -0
  139. truss/tests/test_data/test_build_commands_failure/config.yaml +14 -0
  140. truss/tests/test_data/test_build_commands_failure/model/__init__.py +0 -0
  141. truss/tests/test_data/test_build_commands_failure/model/model.py +17 -0
  142. truss/tests/test_data/test_concurrency_truss/__init__.py +0 -0
  143. truss/tests/test_data/test_concurrency_truss/config.yaml +4 -0
  144. truss/tests/test_data/test_concurrency_truss/model/__init__.py +0 -0
  145. truss/tests/test_data/test_custom_server_truss/__init__.py +0 -0
  146. truss/tests/test_data/test_custom_server_truss/config.yaml +20 -0
  147. truss/tests/test_data/test_custom_server_truss/test_docker_image/Dockerfile +17 -0
  148. truss/tests/test_data/test_custom_server_truss/test_docker_image/README.md +10 -0
  149. truss/tests/test_data/test_custom_server_truss/test_docker_image/VERSION +1 -0
  150. truss/tests/test_data/test_custom_server_truss/test_docker_image/__init__.py +0 -0
  151. truss/tests/test_data/test_custom_server_truss/test_docker_image/app.py +19 -0
  152. truss/tests/test_data/test_custom_server_truss/test_docker_image/build_upload_new_image.sh +6 -0
  153. truss/tests/test_data/test_openai/__init__.py +0 -0
  154. truss/{test_data/test_basic_truss → tests/test_data/test_openai}/config.yaml +1 -2
  155. truss/tests/test_data/test_openai/model/__init__.py +0 -0
  156. truss/tests/test_data/test_openai/model/model.py +15 -0
  157. truss/tests/test_data/test_pyantic_v1/__init__.py +0 -0
  158. truss/tests/test_data/test_pyantic_v1/model/__init__.py +0 -0
  159. truss/tests/test_data/test_pyantic_v1/model/model.py +28 -0
  160. truss/tests/test_data/test_pyantic_v1/requirements.txt +1 -0
  161. truss/tests/test_data/test_pyantic_v2/__init__.py +0 -0
  162. truss/tests/test_data/test_pyantic_v2/config.yaml +13 -0
  163. truss/tests/test_data/test_pyantic_v2/model/__init__.py +0 -0
  164. truss/tests/test_data/test_pyantic_v2/model/model.py +30 -0
  165. truss/tests/test_data/test_pyantic_v2/requirements.txt +1 -0
  166. truss/tests/test_data/test_requirements_file_truss/__init__.py +0 -0
  167. truss/tests/test_data/test_requirements_file_truss/config.yaml +13 -0
  168. truss/tests/test_data/test_requirements_file_truss/model/__init__.py +0 -0
  169. truss/{test_data → tests/test_data}/test_requirements_file_truss/model/model.py +1 -0
  170. truss/tests/test_data/test_streaming_async_generator_truss/__init__.py +0 -0
  171. truss/tests/test_data/test_streaming_async_generator_truss/config.yaml +4 -0
  172. truss/tests/test_data/test_streaming_async_generator_truss/model/__init__.py +0 -0
  173. truss/tests/test_data/test_streaming_async_generator_truss/model/model.py +7 -0
  174. truss/tests/test_data/test_streaming_read_timeout/__init__.py +0 -0
  175. truss/tests/test_data/test_streaming_read_timeout/model/__init__.py +0 -0
  176. truss/tests/test_data/test_streaming_truss/__init__.py +0 -0
  177. truss/tests/test_data/test_streaming_truss/config.yaml +4 -0
  178. truss/tests/test_data/test_streaming_truss/model/__init__.py +0 -0
  179. truss/tests/test_data/test_streaming_truss_with_error/__init__.py +0 -0
  180. truss/tests/test_data/test_streaming_truss_with_error/model/__init__.py +0 -0
  181. truss/{test_data → tests/test_data}/test_streaming_truss_with_error/model/model.py +3 -11
  182. truss/tests/test_data/test_streaming_truss_with_error/packages/__init__.py +0 -0
  183. truss/tests/test_data/test_streaming_truss_with_error/packages/helpers_1.py +5 -0
  184. truss/tests/test_data/test_streaming_truss_with_error/packages/helpers_2.py +2 -0
  185. truss/tests/test_data/test_streaming_truss_with_tracing/__init__.py +0 -0
  186. truss/tests/test_data/test_streaming_truss_with_tracing/config.yaml +43 -0
  187. truss/tests/test_data/test_streaming_truss_with_tracing/model/__init__.py +0 -0
  188. truss/tests/test_data/test_streaming_truss_with_tracing/model/model.py +65 -0
  189. truss/tests/test_data/test_trt_llm_truss/__init__.py +0 -0
  190. truss/tests/test_data/test_trt_llm_truss/config.yaml +15 -0
  191. truss/tests/test_data/test_trt_llm_truss/model/__init__.py +0 -0
  192. truss/tests/test_data/test_trt_llm_truss/model/model.py +15 -0
  193. truss/tests/test_data/test_truss/__init__.py +0 -0
  194. truss/tests/test_data/test_truss/config.yaml +4 -0
  195. truss/tests/test_data/test_truss/model/__init__.py +0 -0
  196. truss/tests/test_data/test_truss/model/dummy +0 -0
  197. truss/tests/test_data/test_truss/packages/__init__.py +0 -0
  198. truss/tests/test_data/test_truss/packages/test_package/__init__.py +0 -0
  199. truss/tests/test_data/test_truss_server_caching_truss/__init__.py +0 -0
  200. truss/tests/test_data/test_truss_server_caching_truss/model/__init__.py +0 -0
  201. truss/tests/test_data/test_truss_with_error/__init__.py +0 -0
  202. truss/tests/test_data/test_truss_with_error/config.yaml +4 -0
  203. truss/tests/test_data/test_truss_with_error/model/__init__.py +0 -0
  204. truss/tests/test_data/test_truss_with_error/model/model.py +8 -0
  205. truss/tests/test_data/test_truss_with_error/packages/__init__.py +0 -0
  206. truss/tests/test_data/test_truss_with_error/packages/helpers_1.py +5 -0
  207. truss/tests/test_data/test_truss_with_error/packages/helpers_2.py +2 -0
  208. truss/tests/test_docker.py +2 -1
  209. truss/tests/test_model_inference.py +1340 -292
  210. truss/tests/test_model_schema.py +33 -26
  211. truss/tests/test_testing_utilities_for_other_tests.py +50 -5
  212. truss/tests/test_truss_gatherer.py +3 -5
  213. truss/tests/test_truss_handle.py +62 -59
  214. truss/tests/test_util.py +2 -1
  215. truss/tests/test_validation.py +15 -13
  216. truss/tests/trt_llm/test_trt_llm_config.py +41 -0
  217. truss/tests/trt_llm/test_validation.py +91 -0
  218. truss/tests/util/test_config_checks.py +40 -0
  219. truss/tests/util/test_env_vars.py +14 -0
  220. truss/tests/util/test_path.py +10 -23
  221. truss/trt_llm/config_checks.py +43 -0
  222. truss/trt_llm/validation.py +42 -0
  223. truss/truss_handle/__init__.py +0 -0
  224. truss/truss_handle/build.py +122 -0
  225. truss/{decorators.py → truss_handle/decorators.py} +1 -1
  226. truss/truss_handle/patch/__init__.py +0 -0
  227. truss/{patch → truss_handle/patch}/calc_patch.py +146 -92
  228. truss/{types.py → truss_handle/patch/custom_types.py} +35 -27
  229. truss/{patch → truss_handle/patch}/dir_signature.py +1 -1
  230. truss/truss_handle/patch/hash.py +71 -0
  231. truss/{patch → truss_handle/patch}/local_truss_patch_applier.py +6 -4
  232. truss/truss_handle/patch/signature.py +22 -0
  233. truss/truss_handle/patch/truss_dir_patch_applier.py +87 -0
  234. truss/{readme_generator.py → truss_handle/readme_generator.py} +3 -2
  235. truss/{truss_gatherer.py → truss_handle/truss_gatherer.py} +3 -2
  236. truss/{truss_handle.py → truss_handle/truss_handle.py} +174 -78
  237. truss/util/.truss_ignore +3 -0
  238. truss/{docker.py → util/docker.py} +6 -2
  239. truss/util/download.py +6 -15
  240. truss/util/env_vars.py +41 -0
  241. truss/util/log_utils.py +52 -0
  242. truss/util/path.py +20 -20
  243. truss/util/requirements.py +11 -0
  244. {truss-0.10.0rc1.dist-info → truss-0.60.0.dist-info}/METADATA +18 -16
  245. truss-0.60.0.dist-info/RECORD +324 -0
  246. {truss-0.10.0rc1.dist-info → truss-0.60.0.dist-info}/WHEEL +1 -1
  247. truss-0.60.0.dist-info/entry_points.txt +4 -0
  248. truss_chains/__init__.py +71 -0
  249. truss_chains/definitions.py +756 -0
  250. truss_chains/deployment/__init__.py +0 -0
  251. truss_chains/deployment/code_gen.py +816 -0
  252. truss_chains/deployment/deployment_client.py +871 -0
  253. truss_chains/framework.py +1480 -0
  254. truss_chains/public_api.py +231 -0
  255. truss_chains/py.typed +0 -0
  256. truss_chains/pydantic_numpy.py +131 -0
  257. truss_chains/reference_code/reference_chainlet.py +34 -0
  258. truss_chains/reference_code/reference_model.py +10 -0
  259. truss_chains/remote_chainlet/__init__.py +0 -0
  260. truss_chains/remote_chainlet/model_skeleton.py +60 -0
  261. truss_chains/remote_chainlet/stub.py +380 -0
  262. truss_chains/remote_chainlet/utils.py +332 -0
  263. truss_chains/streaming.py +378 -0
  264. truss_chains/utils.py +178 -0
  265. CODE_OF_CONDUCT.md +0 -131
  266. CONTRIBUTING.md +0 -48
  267. README.md +0 -137
  268. context_builder.Dockerfile +0 -24
  269. truss/blob/blob_backend.py +0 -10
  270. truss/blob/blob_backend_registry.py +0 -23
  271. truss/blob/http_public_blob_backend.py +0 -23
  272. truss/build/__init__.py +0 -2
  273. truss/build/build.py +0 -143
  274. truss/build/configure.py +0 -63
  275. truss/cli/__init__.py +0 -2
  276. truss/cli/console.py +0 -5
  277. truss/cli/create.py +0 -5
  278. truss/config/trt_llm.py +0 -81
  279. truss/constants.py +0 -61
  280. truss/model_inference.py +0 -123
  281. truss/patch/types.py +0 -30
  282. truss/pytest.ini +0 -7
  283. truss/server/common/errors.py +0 -100
  284. truss/server/common/termination_handler_middleware.py +0 -64
  285. truss/server/common/truss_server.py +0 -389
  286. truss/server/control/patch/model_code_patch_applier.py +0 -46
  287. truss/server/control/patch/requirement_name_identifier.py +0 -17
  288. truss/server/inference_server.py +0 -29
  289. truss/server/model_wrapper.py +0 -434
  290. truss/server/shared/logging.py +0 -81
  291. truss/templates/trtllm/model/model.py +0 -97
  292. truss/templates/trtllm/packages/build_engine_utils.py +0 -34
  293. truss/templates/trtllm/packages/constants.py +0 -11
  294. truss/templates/trtllm/packages/schema.py +0 -216
  295. truss/templates/trtllm/packages/tensorrt_llm_model_repository/ensemble/config.pbtxt +0 -246
  296. truss/templates/trtllm/packages/tensorrt_llm_model_repository/postprocessing/1/model.py +0 -181
  297. truss/templates/trtllm/packages/tensorrt_llm_model_repository/postprocessing/config.pbtxt +0 -64
  298. truss/templates/trtllm/packages/tensorrt_llm_model_repository/preprocessing/1/model.py +0 -260
  299. truss/templates/trtllm/packages/tensorrt_llm_model_repository/preprocessing/config.pbtxt +0 -99
  300. truss/templates/trtllm/packages/tensorrt_llm_model_repository/tensorrt_llm/config.pbtxt +0 -208
  301. truss/templates/trtllm/packages/triton_client.py +0 -150
  302. truss/templates/trtllm/packages/utils.py +0 -43
  303. truss/test_data/context_builder_image_test/test.py +0 -4
  304. truss/test_data/happy.ipynb +0 -54
  305. truss/test_data/model_load_failure_test/config.yaml +0 -2
  306. truss/test_data/test_concurrency_truss/config.yaml +0 -2
  307. truss/test_data/test_streaming_async_generator_truss/config.yaml +0 -2
  308. truss/test_data/test_streaming_truss/config.yaml +0 -3
  309. truss/test_data/test_truss/config.yaml +0 -2
  310. truss/tests/server/common/test_termination_handler_middleware.py +0 -93
  311. truss/tests/server/control/test_model_container_patch_applier.py +0 -203
  312. truss/tests/server/core/server/common/test_util.py +0 -19
  313. truss/tests/server/test_model_wrapper.py +0 -87
  314. truss/util/data_structures.py +0 -16
  315. truss-0.10.0rc1.dist-info/RECORD +0 -216
  316. truss-0.10.0rc1.dist-info/entry_points.txt +0 -3
  317. truss/{server/shared → base}/__init__.py +0 -0
  318. truss/{server → templates/control}/control/helpers/context_managers.py +0 -0
  319. truss/{server/control → templates/control/control/helpers}/errors.py +0 -0
  320. truss/{server/control/patch → templates/control/control/helpers/truss_patch}/__init__.py +0 -0
  321. truss/{server/control/patch → templates/control/control/helpers/truss_patch}/system_packages.py +0 -0
  322. truss/{test_data/annotated_types_truss/model → templates/server}/__init__.py +0 -0
  323. truss/{server → templates/server}/common/__init__.py +0 -0
  324. truss/{test_data/gcs_fix/model → templates/shared}/__init__.py +0 -0
  325. truss/templates/{trtllm → trtllm-briton}/README.md +0 -0
  326. truss/{test_data/server_conformance_test_truss/model → tests/test_data}/__init__.py +0 -0
  327. truss/{test_data/test_basic_truss/model → tests/test_data/annotated_types_truss}/__init__.py +0 -0
  328. truss/{test_data → tests/test_data}/annotated_types_truss/config.yaml +0 -0
  329. truss/{test_data/test_requirements_file_truss → tests/test_data/annotated_types_truss}/model/__init__.py +0 -0
  330. truss/{test_data → tests/test_data}/annotated_types_truss/model/model.py +0 -0
  331. truss/{test_data → tests/test_data}/auto-mpg.data +0 -0
  332. truss/{test_data → tests/test_data}/context_builder_image_test/Dockerfile +0 -0
  333. truss/{test_data/test_truss/model → tests/test_data/context_builder_image_test}/__init__.py +0 -0
  334. truss/{test_data/test_truss_server_caching_truss/model → tests/test_data/gcs_fix}/__init__.py +0 -0
  335. truss/{test_data → tests/test_data}/gcs_fix/config.yaml +0 -0
  336. truss/tests/{local → test_data/gcs_fix/model}/__init__.py +0 -0
  337. truss/{test_data → tests/test_data}/gcs_fix/model/model.py +0 -0
  338. truss/{test_data/test_truss/model/dummy → tests/test_data/model_load_failure_test/__init__.py} +0 -0
  339. truss/{test_data → tests/test_data}/model_load_failure_test/model/model.py +0 -0
  340. truss/{test_data → tests/test_data}/pima-indians-diabetes.csv +0 -0
  341. truss/{test_data → tests/test_data}/readme_int_example.md +0 -0
  342. truss/{test_data → tests/test_data}/readme_no_example.md +0 -0
  343. truss/{test_data → tests/test_data}/readme_str_example.md +0 -0
  344. truss/{test_data → tests/test_data}/server_conformance_test_truss/config.yaml +0 -0
  345. truss/{test_data → tests/test_data}/test_async_truss/config.yaml +0 -0
  346. truss/{test_data → tests/test_data}/test_async_truss/model/model.py +3 -3
  347. /truss/{test_data → tests/test_data}/test_basic_truss/model/model.py +0 -0
  348. /truss/{test_data → tests/test_data}/test_concurrency_truss/model/model.py +0 -0
  349. /truss/{test_data/test_requirements_file_truss → tests/test_data/test_pyantic_v1}/config.yaml +0 -0
  350. /truss/{test_data → tests/test_data}/test_requirements_file_truss/requirements.txt +0 -0
  351. /truss/{test_data → tests/test_data}/test_streaming_read_timeout/config.yaml +0 -0
  352. /truss/{test_data → tests/test_data}/test_streaming_read_timeout/model/model.py +0 -0
  353. /truss/{test_data → tests/test_data}/test_streaming_truss/model/model.py +0 -0
  354. /truss/{test_data → tests/test_data}/test_streaming_truss_with_error/config.yaml +0 -0
  355. /truss/{test_data → tests/test_data}/test_truss/examples.yaml +0 -0
  356. /truss/{test_data → tests/test_data}/test_truss/model/model.py +0 -0
  357. /truss/{test_data → tests/test_data}/test_truss/packages/test_package/test.py +0 -0
  358. /truss/{test_data → tests/test_data}/test_truss_server_caching_truss/config.yaml +0 -0
  359. /truss/{test_data → tests/test_data}/test_truss_server_caching_truss/model/model.py +0 -0
  360. /truss/{patch → truss_handle/patch}/constants.py +0 -0
  361. /truss/{notebook.py → util/notebook.py} +0 -0
  362. {truss-0.10.0rc1.dist-info → truss-0.60.0.dist-info}/LICENSE +0 -0
@@ -1,17 +1,34 @@
1
+ import datetime
2
+ import json
1
3
  import logging
2
- from typing import IO, List, Optional, Tuple
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 load_trussignore_patterns
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 (query_result["id"], query_result["versions"])
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(truss_handle: TrussHandle) -> IO:
107
- """
108
- Archive a TrussHandle into a tar file.
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._spec.truss_dir
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
- truss_ignore_file = truss_dir / ".truss_ignore"
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(truss_dir, ignore_patterns)
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(api: BasetenApi, serialize_file: IO) -> str:
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: Wheter to scale old production deployment to zero
182
- deployment_name: Name to apply to the created deployment. Not applied to development model
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
- f"truss=={truss.version()}",
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 (model_version_json["id"], model_version_json["version_id"])
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=f"truss=={truss.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 (model_version_json["id"], model_version_json["version_id"])
209
-
210
- # Case where there is a model id already, create another version
211
- model_version_json = api.create_model_version_from_truss(
212
- model_id=model_id,
213
- s3_key=s3_key,
214
- config=config,
215
- semver_bump=semver_bump,
216
- client_version=f"truss=={truss.version()}",
217
- is_trusted=is_trusted,
218
- promote=promote,
219
- preserve_previous_prod_deployment=preserve_previous_prod_deployment,
220
- deployment_name=deployment_name,
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 (model_id, model_version_id)
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
@@ -21,3 +21,7 @@ class AuthorizationError(Error):
21
21
  """Raised in places where the user needs to be logged in and is not."""
22
22
 
23
23
  pass
24
+
25
+
26
+ class RemoteError(Error):
27
+ pass