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
@@ -0,0 +1,87 @@
1
+ import logging
2
+ from pathlib import Path
3
+ from typing import List
4
+
5
+ from truss.base.truss_config import TrussConfig
6
+ from truss.templates.control.control.helpers.custom_types import (
7
+ Action,
8
+ ConfigPatch,
9
+ EnvVarPatch,
10
+ ExternalDataPatch,
11
+ ModelCodePatch,
12
+ PackagePatch,
13
+ Patch,
14
+ PythonRequirementPatch,
15
+ SystemPackagePatch,
16
+ )
17
+ from truss.templates.control.control.helpers.errors import UnsupportedPatch
18
+ from truss.templates.control.control.helpers.truss_patch.model_code_patch_applier import (
19
+ apply_code_patch,
20
+ )
21
+ from truss.templates.control.control.helpers.truss_patch.requirement_name_identifier import (
22
+ identify_requirement_name,
23
+ reqs_by_name,
24
+ )
25
+ from truss.templates.control.control.helpers.truss_patch.system_packages import (
26
+ system_packages_set,
27
+ )
28
+
29
+
30
+ class TrussDirPatchApplier:
31
+ """Applies patches to a truss directory.
32
+ This should be compatible with ModelContainerPatchApplier.
33
+
34
+ Note: This class imported via old_build_setup.sh.jinja in the baseten
35
+ repository
36
+ """
37
+
38
+ def __init__(self, truss_dir: Path, logger: logging.Logger) -> None:
39
+ self._truss_dir = truss_dir
40
+ self._truss_config_path = self._truss_dir / "config.yaml"
41
+ self._truss_config = TrussConfig.from_yaml(self._truss_config_path)
42
+ self._logger = logger
43
+
44
+ def __call__(self, patches: List[Patch]):
45
+ # Apply model code patches immediately
46
+ # Aggregate config patches and apply at end
47
+ reqs = reqs_by_name(self._truss_config.requirements)
48
+ pkgs = system_packages_set(self._truss_config.system_packages)
49
+ new_config = self._truss_config
50
+ for patch in patches:
51
+ self._logger.debug(f"Applying patch {patch.to_dict()}")
52
+ action = patch.body.action
53
+ if isinstance(patch.body, ModelCodePatch):
54
+ model_code_patch: ModelCodePatch = patch.body
55
+ model_module_dir = self._truss_dir / self._truss_config.model_module_dir
56
+ apply_code_patch(model_module_dir, model_code_patch, self._logger)
57
+ elif isinstance(patch.body, PythonRequirementPatch):
58
+ py_req_patch: PythonRequirementPatch = patch.body
59
+ req = py_req_patch.requirement
60
+ req_name = identify_requirement_name(req)
61
+ if action == Action.REMOVE:
62
+ del reqs[req_name]
63
+ elif action == Action.ADD or Action.UPDATE:
64
+ reqs[req_name] = req
65
+ elif isinstance(patch.body, SystemPackagePatch):
66
+ sys_pkg_patch: SystemPackagePatch = patch.body
67
+ pkg = sys_pkg_patch.package
68
+ if action == Action.REMOVE:
69
+ pkgs.remove(pkg)
70
+ elif action == Action.ADD or Action.UPDATE:
71
+ pkgs.add(pkg)
72
+ elif isinstance(patch.body, ConfigPatch):
73
+ new_config = TrussConfig.from_dict(patch.body.config)
74
+ # Each of EnvVarPatch and ExternalDataPatch can be expressed through an
75
+ # overwrite of the config, handled below.
76
+ elif isinstance(patch.body, (EnvVarPatch, ExternalDataPatch)):
77
+ pass
78
+ elif isinstance(patch.body, PackagePatch):
79
+ package_patch: PackagePatch = patch.body
80
+ package_module_dir = (
81
+ self._truss_dir / self._truss_config.bundled_packages_dir
82
+ )
83
+ apply_code_patch(package_module_dir, package_patch, self._logger)
84
+ else:
85
+ raise UnsupportedPatch(f"Unknown patch type {patch.type}")
86
+
87
+ new_config.write_to_yaml_file(self._truss_config_path)
@@ -1,6 +1,7 @@
1
1
  from jinja2 import Template
2
- from truss.constants import README_TEMPLATE_NAME, TEMPLATES_DIR
3
- from truss.truss_spec import TrussSpec
2
+
3
+ from truss.base.constants import README_TEMPLATE_NAME, TEMPLATES_DIR
4
+ from truss.base.truss_spec import TrussSpec
4
5
 
5
6
 
6
7
  def generate_readme(_spec: TrussSpec) -> str:
@@ -1,9 +1,10 @@
1
1
  from pathlib import Path
2
2
 
3
3
  import yaml
4
+
4
5
  from truss.local.local_config_handler import LocalConfigHandler
5
- from truss.patch.hash import str_hash_str
6
- from truss.truss_handle import TrussHandle
6
+ from truss.truss_handle.patch.hash import str_hash_str
7
+ from truss.truss_handle.truss_handle import TrussHandle
7
8
  from truss.util.path import copy_file_path, copy_tree_path, remove_tree_path
8
9
 
9
10
 
@@ -6,7 +6,7 @@ import sys
6
6
  import uuid
7
7
  from dataclasses import replace
8
8
  from pathlib import Path
9
- from typing import Any, Callable, Dict, List, Optional, Tuple, Union
9
+ from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union
10
10
  from urllib.error import HTTPError
11
11
 
12
12
  import requests
@@ -24,19 +24,46 @@ from tenacity import (
24
24
  stop_after_delay,
25
25
  wait_fixed,
26
26
  )
27
- from truss.constants import (
27
+
28
+ from truss.base.constants import (
28
29
  INFERENCE_SERVER_PORT,
29
30
  TRUSS,
30
31
  TRUSS_DIR,
31
32
  TRUSS_HASH,
32
33
  TRUSS_MODIFIED_TIME,
33
34
  )
35
+ from truss.base.custom_types import Example
36
+ from truss.base.errors import ContainerIsDownError, ContainerNotFoundError
37
+ from truss.base.truss_config import (
38
+ BaseImage,
39
+ ExternalData,
40
+ ExternalDataItem,
41
+ TrussConfig,
42
+ )
43
+ from truss.base.truss_spec import TrussSpec
44
+ from truss.base.validation import validate_secret_name
34
45
  from truss.contexts.image_builder.serving_image_builder import (
35
46
  ServingImageBuilderContext,
36
47
  )
37
48
  from truss.contexts.local_loader.load_model_local import LoadModelLocal
38
- from truss.decorators import proxy_to_shadow_if_scattered
39
- from truss.docker import (
49
+ from truss.contexts.truss_context import TrussContext
50
+ from truss.local.local_config_handler import LocalConfigHandler
51
+ from truss.templates.shared.serialization import (
52
+ truss_msgpack_deserialize,
53
+ truss_msgpack_serialize,
54
+ )
55
+ from truss.trt_llm.validation import validate
56
+ from truss.truss_handle.decorators import proxy_to_shadow_if_scattered
57
+ from truss.truss_handle.patch.calc_patch import calc_truss_patch
58
+ from truss.truss_handle.patch.custom_types import (
59
+ PatchDetails,
60
+ PatchRequest,
61
+ TrussSignature,
62
+ )
63
+ from truss.truss_handle.patch.hash import directory_content_hash
64
+ from truss.truss_handle.patch.signature import calc_truss_signature
65
+ from truss.truss_handle.readme_generator import generate_readme
66
+ from truss.util.docker import (
40
67
  Docker,
41
68
  DockerStates,
42
69
  get_container_logs,
@@ -46,28 +73,13 @@ from truss.docker import (
46
73
  get_urls_from_container,
47
74
  kill_containers,
48
75
  )
49
- from truss.errors import ContainerIsDownError, ContainerNotFoundError
50
- from truss.local.local_config_handler import LocalConfigHandler
51
- from truss.notebook import is_notebook_or_ipython
52
- from truss.patch.calc_patch import calc_truss_patch
53
- from truss.patch.hash import directory_content_hash
54
- from truss.patch.signature import calc_truss_signature
55
- from truss.patch.types import TrussSignature
56
- from truss.readme_generator import generate_readme
57
- from truss.server.shared.serialization import (
58
- truss_msgpack_deserialize,
59
- truss_msgpack_serialize,
60
- )
61
- from truss.truss_config import BaseImage, ExternalData, ExternalDataItem, TrussConfig
62
- from truss.truss_spec import TrussSpec
63
- from truss.types import Example, PatchDetails, PatchRequest
76
+ from truss.util.notebook import is_notebook_or_ipython
64
77
  from truss.util.path import (
65
78
  copy_file_path,
66
79
  copy_tree_path,
67
80
  get_max_modified_time_of_dir,
68
81
  load_trussignore_patterns,
69
82
  )
70
- from truss.validation import validate_secret_name
71
83
 
72
84
  logger: logging.Logger = logging.getLogger(__name__)
73
85
 
@@ -76,16 +88,32 @@ if is_notebook_or_ipython():
76
88
  logger.addHandler(logging.StreamHandler(sys.stdout))
77
89
 
78
90
 
91
+ class RunningContainer:
92
+ def __init__(self, container):
93
+ self.container = container
94
+
95
+ def logs(self):
96
+ from python_on_whales import docker
97
+
98
+ return docker.logs(self.container, follow=True, stream=True)
99
+
100
+ def wait(self):
101
+ from python_on_whales import docker
102
+
103
+ return docker.wait(self.container)
104
+
105
+
79
106
  class TrussHandle:
80
107
  def __init__(self, truss_dir: Path, validate: bool = True) -> None:
81
108
  self._truss_dir = truss_dir
82
- self._spec = TrussSpec(truss_dir)
109
+ self._spec = TrussSpec(self._truss_dir)
83
110
  self._hash_for_mod_time: Optional[Tuple[float, str]] = None
84
111
  if validate:
85
112
  self.validate()
86
113
 
87
114
  def validate(self):
88
115
  self._validate_external_packages()
116
+ self._validate_extensions()
89
117
 
90
118
  @property
91
119
  def spec(self) -> TrussSpec:
@@ -149,6 +177,57 @@ class TrussHandle:
149
177
  """[Deprecated] Do not use."""
150
178
  return _docker_image_from_labels(labels)
151
179
 
180
+ @proxy_to_shadow_if_scattered
181
+ def run_python_script(self, script_path: Path, build_dir: Optional[Path] = None):
182
+ from python_on_whales.exceptions import DockerException
183
+
184
+ image = self.build_serving_docker_image(build_dir=build_dir)
185
+ secrets_mount_dir_path = _prepare_secrets_mount_dir()
186
+
187
+ envs: Dict[str, str] = {}
188
+ # Add bundled packages to the PYTHONPATH. Note
189
+ # that this is necessary to achieve the same environment as Truss Server
190
+ # -- this is setup that is done by Truss Server, that won't be available
191
+ # to the standalone script.
192
+ bundled_packages_path = Path("/packages")
193
+ envs["PYTHONPATH"] = bundled_packages_path.as_posix()
194
+
195
+ # Note that the entrypoint command should match
196
+ # what we use when executing Truss Server.
197
+ entrypoint_command = self.spec.python_executable_path or "python3"
198
+
199
+ def _docker_run(gpus: Optional[str] = None):
200
+ container = Docker.client().run(
201
+ image.id,
202
+ entrypoint=entrypoint_command,
203
+ command=["/app/script.py"],
204
+ detach=True,
205
+ mounts=[
206
+ [
207
+ "type=bind",
208
+ f"src={str(secrets_mount_dir_path)}",
209
+ "target=/secrets",
210
+ ],
211
+ [
212
+ "type=bind",
213
+ f"src={str(script_path.absolute())}",
214
+ "target=/app/script.py",
215
+ ],
216
+ ],
217
+ gpus=gpus,
218
+ envs=envs,
219
+ add_hosts=[("host.docker.internal", "host-gateway")],
220
+ )
221
+
222
+ return RunningContainer(container)
223
+
224
+ try:
225
+ return _docker_run("all" if self._spec.config.resources.use_gpu else None)
226
+ except DockerException:
227
+ # The reason we'd wind up here is if the Truss needs
228
+ # a GPU, but the host does not have one that can attach.
229
+ return _docker_run(None)
230
+
152
231
  @proxy_to_shadow_if_scattered
153
232
  def docker_run(
154
233
  self,
@@ -159,7 +238,9 @@ class TrussHandle:
159
238
  patch_ping_url: Optional[str] = None,
160
239
  wait_for_server_ready: bool = True,
161
240
  network: Optional[str] = None,
162
- cache: bool = True,
241
+ container_name_prefix: Optional[str] = None,
242
+ model_server_stop_retry_override=None,
243
+ disable_json_logging: bool = False,
163
244
  ):
164
245
  """
165
246
  Builds a docker image and runs it as a container. For control trusses,
@@ -173,7 +254,10 @@ class TrussHandle:
173
254
  patch_ping_url: Mostly for testing, if supplied then a live
174
255
  reload capable truss queries for truss changes
175
256
  by hitting this url.
176
- wait_for_server_ready: If true, wait for server to pass readiness probe before returning.
257
+ wait_for_server_ready: If true, wait for server to pass readiness
258
+ probe before returning.
259
+ network: docker network name.
260
+ container_name_prefix: optional docker container name prefix.
177
261
 
178
262
  Returns:
179
263
  Container, which can be used to get information about the running,
@@ -186,7 +270,7 @@ class TrussHandle:
186
270
  container = container_if_patched
187
271
  else:
188
272
  image = self.build_serving_docker_image(
189
- build_dir=build_dir, tag=tag, network=network, cache=cache
273
+ build_dir=build_dir, tag=tag, network=network
190
274
  )
191
275
  secrets_mount_dir_path = _prepare_secrets_mount_dir()
192
276
  publish_ports = [[local_port, INFERENCE_SERVER_PORT]]
@@ -198,6 +282,14 @@ class TrussHandle:
198
282
  envs = {}
199
283
  if patch_ping_url is not None:
200
284
  envs["PATCH_PING_URL_TRUSS"] = patch_ping_url
285
+ if disable_json_logging:
286
+ envs["DISABLE_JSON_LOGGING"] = "true"
287
+
288
+ if container_name_prefix:
289
+ suffix = str(uuid.uuid4()).split("-")[0]
290
+ name = f"{container_name_prefix}-{suffix}"
291
+ else:
292
+ name = None
201
293
 
202
294
  def _run_docker(gpus: Optional[str] = None):
203
295
  return Docker.client().run(
@@ -210,11 +302,23 @@ class TrussHandle:
210
302
  "type=bind",
211
303
  f"src={str(secrets_mount_dir_path)}",
212
304
  "target=/secrets",
213
- ]
305
+ ],
306
+ [
307
+ "type=bind",
308
+ f"src={str(LocalConfigHandler.bptr_data_resolution_dir_path())}",
309
+ "target=/bptr",
310
+ ],
311
+ [
312
+ "type=bind",
313
+ f"src={str(LocalConfigHandler.dynamic_config_path())}",
314
+ "target=/etc/b10_dynamic_config",
315
+ "readonly=false",
316
+ ],
214
317
  ],
215
318
  gpus=gpus,
216
319
  envs=envs,
217
320
  add_hosts=[("host.docker.internal", "host-gateway")],
321
+ name=name,
218
322
  )
219
323
 
220
324
  try:
@@ -232,7 +336,12 @@ class TrussHandle:
232
336
  )
233
337
  model_base_url = f"http://localhost:{local_port}/v1/models/model"
234
338
  try:
235
- wait_for_truss(model_base_url, container, wait_for_server_ready)
339
+ wait_for_truss(
340
+ model_base_url,
341
+ container,
342
+ wait_for_server_ready,
343
+ model_server_stop_retry_override,
344
+ )
236
345
  except ContainerNotFoundError as err:
237
346
  raise err
238
347
  except (ContainerIsDownError, HTTPError, ConnectionError) as err:
@@ -263,6 +372,7 @@ class TrussHandle:
263
372
  else:
264
373
  return self.server_predict(request)
265
374
 
375
+ # TODO(marius): can we kill this?
266
376
  def server_predict(self, request: Dict):
267
377
  """Run the prediction flow locally."""
268
378
  model = LoadModelLocal.run(self._truss_dir)
@@ -384,11 +494,7 @@ class TrussHandle:
384
494
  validate_secret_name(secret_name)
385
495
  self._update_config(
386
496
  lambda conf: replace(
387
- conf,
388
- secrets={
389
- **conf.secrets,
390
- secret_name: default_secret_value,
391
- },
497
+ conf, secrets={**conf.secrets, secret_name: default_secret_value}
392
498
  )
393
499
  )
394
500
 
@@ -410,23 +516,12 @@ class TrussHandle:
410
516
  self._spec.config.external_data or ExternalData([])
411
517
  )
412
518
  new_external_data = replace(
413
- current_external_data,
414
- items=current_external_data.items + [item],
415
- )
416
- self._update_config(
417
- lambda conf: replace(
418
- conf,
419
- external_data=new_external_data,
420
- )
519
+ current_external_data, items=current_external_data.items + [item]
421
520
  )
521
+ self._update_config(lambda conf: replace(conf, external_data=new_external_data))
422
522
 
423
523
  def remove_all_external_data(self):
424
- self._update_config(
425
- lambda conf: replace(
426
- conf,
427
- external_data=None,
428
- )
429
- )
524
+ self._update_config(lambda conf: replace(conf, external_data=None))
430
525
 
431
526
  def update_requirements(self, requirements: List[str]):
432
527
  """Update requirements in truss model's config.
@@ -554,9 +649,7 @@ class TrussHandle:
554
649
 
555
650
  @proxy_to_shadow_if_scattered
556
651
  def get_serving_docker_containers_from_labels(
557
- self,
558
- all: bool = False,
559
- labels: Optional[dict] = None,
652
+ self, all: bool = False, labels: Optional[dict] = None
560
653
  ) -> list:
561
654
  """Get serving docker containers, with given labels.
562
655
 
@@ -568,10 +661,7 @@ class TrussHandle:
568
661
  labels = self._get_serving_lookup_labels()
569
662
  else:
570
663
  # Make sure we're looking for serving container for this truss.
571
- labels = {
572
- TRUSS: True,
573
- **labels,
574
- }
664
+ labels = {TRUSS: True, **labels}
575
665
 
576
666
  return sorted(get_containers(labels, all=all), key=lambda c: c.created)
577
667
 
@@ -630,10 +720,7 @@ class TrussHandle:
630
720
  python_executable_path=python_executable_path,
631
721
  )
632
722
  return replace(conf, base_image=new_base_image)
633
- new_base_image = BaseImage(
634
- image,
635
- python_executable_path,
636
- )
723
+ new_base_image = BaseImage(image, python_executable_path)
637
724
  return replace(conf, base_image=new_base_image)
638
725
 
639
726
  self._update_config(define_base_image_fn)
@@ -691,10 +778,7 @@ class TrussHandle:
691
778
  inferred_python_version = f"py{version_parts[0]}{version_parts[1]}"
692
779
 
693
780
  self._update_config(
694
- lambda conf: replace(
695
- conf,
696
- python_version=inferred_python_version,
697
- )
781
+ lambda conf: replace(conf, python_version=inferred_python_version)
698
782
  )
699
783
 
700
784
  def _control_serving_container_has_partially_applied_patch(self) -> Optional[bool]:
@@ -758,7 +842,6 @@ class TrussHandle:
758
842
  if prev_sign_str is None:
759
843
  logger.info(f"Signature not found for truss for hash {prev_truss_hash}")
760
844
  return None
761
-
762
845
  prev_sign = TrussSignature.from_dict(json.loads(prev_sign_str))
763
846
  ignore_patterns = truss_ignore_patterns + self._spec.hash_ignore_patterns
764
847
  patch_ops = calc_truss_patch(self._truss_dir, prev_sign, ignore_patterns)
@@ -783,7 +866,7 @@ class TrussHandle:
783
866
  gatherer and a handle to that truss is returned. These gathered trusses
784
867
  are caches and resused.
785
868
  """
786
- from truss.truss_gatherer import gather
869
+ from truss.truss_handle.truss_gatherer import gather
787
870
 
788
871
  if not self.is_scattered():
789
872
  return self._truss_dir
@@ -847,7 +930,7 @@ class TrussHandle:
847
930
 
848
931
  def _build_image(
849
932
  self,
850
- builder_context,
933
+ builder_context: Type[TrussContext],
851
934
  labels: Dict[str, str],
852
935
  build_dir: Optional[Path] = None,
853
936
  tag: Optional[str] = None,
@@ -855,7 +938,7 @@ class TrussHandle:
855
938
  network: Optional[str] = None,
856
939
  ):
857
940
  image = _docker_image_from_labels(labels=labels)
858
- if cache and image is not None:
941
+ if image is not None:
859
942
  return image
860
943
 
861
944
  build_dir_path = Path(build_dir) if build_dir is not None else None
@@ -917,7 +1000,7 @@ class TrussHandle:
917
1000
  )
918
1001
  resp = self.patch_container(patch_request)
919
1002
  if "error" in resp:
920
- raise RuntimeError(f'Failed to patch control truss {resp["error"]}')
1003
+ raise RuntimeError(f"Failed to patch control truss {resp['error']}")
921
1004
  self._store_signature()
922
1005
  return container
923
1006
 
@@ -951,6 +1034,11 @@ class TrussHandle:
951
1034
  f"{path.resolve()} but that path does not exist."
952
1035
  )
953
1036
 
1037
+ def _validate_extensions(self):
1038
+ # Only one extenstion right now.
1039
+ if self._spec.config.trt_llm is not None:
1040
+ validate(self._spec)
1041
+
954
1042
 
955
1043
  def _prediction_flow(model, request: Dict):
956
1044
  """This flow attempts to mimic the request life-cycle of a server"""
@@ -974,31 +1062,39 @@ def _wait_for_docker_build(container) -> None:
974
1062
  raise ContainerIsDownError(f"Container stuck in state: {state.value}.")
975
1063
 
976
1064
 
977
- @retry(
978
- stop=stop_after_delay(120),
979
- wait=wait_fixed(2),
980
- retry=(
981
- retry_if_result(lambda response: response.status_code == 503)
982
- | retry_if_exception_type(exceptions.ConnectionError)
983
- ),
984
- )
985
- def _wait_for_model_server(url: str) -> Response:
986
- return requests.get(url)
1065
+ def _wait_for_model_server(url: str, stop=stop_after_delay(120)) -> Response: # type: ignore[return]
1066
+ for attempt in Retrying(
1067
+ stop=stop,
1068
+ wait=wait_fixed(2),
1069
+ retry=(
1070
+ retry_if_result(lambda response: response.status_code in [502, 503])
1071
+ | retry_if_exception_type(exceptions.ConnectionError)
1072
+ ),
1073
+ ):
1074
+ with attempt:
1075
+ response = requests.get(url)
1076
+ return response
987
1077
 
988
1078
 
989
1079
  def wait_for_truss(
990
- url: str, container: str, wait_for_server_ready: bool = True
1080
+ url: str,
1081
+ container: str,
1082
+ wait_for_server_ready: bool = True,
1083
+ model_server_stop_retry_override=None,
991
1084
  ) -> None:
992
1085
  from python_on_whales.exceptions import NoSuchContainer
993
1086
 
994
1087
  try:
995
1088
  _wait_for_docker_build(container)
1089
+ if wait_for_server_ready:
1090
+ if model_server_stop_retry_override is not None:
1091
+ _wait_for_model_server(url, stop=model_server_stop_retry_override)
1092
+ else:
1093
+ _wait_for_model_server(url)
996
1094
  except NoSuchContainer:
997
1095
  raise ContainerNotFoundError(message=f"Container {container} was not found")
998
1096
  except RetryError as retry_err:
999
1097
  retry_err.reraise()
1000
- if wait_for_server_ready:
1001
- _wait_for_model_server(url)
1002
1098
 
1003
1099
 
1004
1100
  def _prepare_secrets_mount_dir() -> Path:
truss/util/.truss_ignore CHANGED
@@ -141,6 +141,9 @@ venv.bak/
141
141
  .dmypy.json
142
142
  dmypy.json
143
143
 
144
+ # ruff
145
+ .ruff_cache/
146
+
144
147
  # Pyre type checker
145
148
  .pyre/
146
149
 
@@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, Any, Dict, List
5
5
  if TYPE_CHECKING:
6
6
  from python_on_whales.components.container.cli_wrapper import Container
7
7
 
8
- from truss.constants import TRUSS_DIR
8
+ from truss.base.constants import TRUSS, TRUSS_DIR
9
9
  from truss.local.local_config_handler import LocalConfigHandler
10
10
 
11
11
 
@@ -57,7 +57,7 @@ def get_urls_from_container(container_details) -> Dict[int, List[str]]:
57
57
  )
58
58
 
59
59
  def urls_from_port_protocol_values(
60
- port_protocol_values: List[Dict[str, str]]
60
+ port_protocol_values: List[Dict[str, str]],
61
61
  ) -> List[str]:
62
62
  return [url_from_port_protocol_value(v) for v in port_protocol_values]
63
63
 
@@ -115,3 +115,7 @@ def _create_label_filters(labels: Dict) -> Dict[str, Any]:
115
115
  return {
116
116
  f"label={label_key}": label_value for label_key, label_value in labels.items()
117
117
  }
118
+
119
+
120
+ def kill_all() -> None:
121
+ kill_containers({TRUSS: True})
truss/util/download.py CHANGED
@@ -5,7 +5,7 @@ from pathlib import Path
5
5
  from typing import Optional
6
6
 
7
7
  import requests
8
- from truss.truss_config import ExternalData
8
+ from truss.base.truss_config import ExternalData
9
9
 
10
10
  B10CP_EXECUTABLE_NAME = "b10cp"
11
11
  BLOB_DOWNLOAD_TIMEOUT_SECS = 600 # 10 minutes
@@ -41,9 +41,7 @@ def _b10cp_path() -> Optional[str]:
41
41
 
42
42
 
43
43
  def _download_external_data_using_b10cp(
44
- b10cp_path: str,
45
- data_dir: Path,
46
- external_data: ExternalData,
44
+ b10cp_path: str, data_dir: Path, external_data: ExternalData
47
45
  ):
48
46
  procs = []
49
47
  # TODO(pankaj) Limit concurrency here
@@ -56,11 +54,7 @@ def _download_external_data_using_b10cp(
56
54
  proc.wait()
57
55
 
58
56
 
59
- def _download_from_url_using_b10cp(
60
- b10cp_path: str,
61
- url: str,
62
- download_to: Path,
63
- ):
57
+ def _download_from_url_using_b10cp(b10cp_path: str, url: str, download_to: Path):
64
58
  return subprocess.Popen(
65
59
  [
66
60
  b10cp_path,
@@ -74,18 +68,15 @@ def _download_from_url_using_b10cp(
74
68
 
75
69
  def _download_external_data_using_requests(data_dir: Path, external_data: ExternalData):
76
70
  for item in external_data.items:
77
- _download_from_url_using_requests(
71
+ download_from_url_using_requests(
78
72
  item.url, (data_dir / item.local_data_path).resolve()
79
73
  )
80
74
 
81
75
 
82
- def _download_from_url_using_requests(URL: str, download_to: Path):
76
+ def download_from_url_using_requests(URL: str, download_to: Path):
83
77
  # Streaming download to keep memory usage low
84
78
  resp = requests.get(
85
- URL,
86
- allow_redirects=True,
87
- stream=True,
88
- timeout=BLOB_DOWNLOAD_TIMEOUT_SECS,
79
+ URL, allow_redirects=True, stream=True, timeout=BLOB_DOWNLOAD_TIMEOUT_SECS
89
80
  )
90
81
  resp.raise_for_status()
91
82
  with download_to.open("wb") as file: