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
@@ -4,9 +4,11 @@ from pathlib import Path
4
4
 
5
5
  import pytest
6
6
  import requests
7
+
8
+ from truss.templates.shared import serialization
7
9
  from truss.tests.helpers import create_truss
8
10
  from truss.tests.test_testing_utilities_for_other_tests import ensure_kill_all
9
- from truss.truss_handle import TrussHandle
11
+ from truss.truss_handle.truss_handle import TrussHandle
10
12
 
11
13
  DEFAULT_CONFIG = """model_name: test-truss"""
12
14
  TRUSS_SERVER_ADDR = "http://localhost:8090"
@@ -15,10 +17,8 @@ SCHEMA_URL = f"{TRUSS_SERVER_ADDR}/v1/models/model/schema"
15
17
 
16
18
 
17
19
  @pytest.mark.integration
18
- def test_truss_with_no_annotations():
19
- truss_root = Path(__file__).parent.parent.parent.resolve()
20
-
21
- truss_dir = truss_root / "truss" / "test_data" / "test_basic_truss"
20
+ def test_truss_with_no_annotations(test_data_path):
21
+ truss_dir = test_data_path / "test_basic_truss"
22
22
 
23
23
  tr = TrussHandle(truss_dir)
24
24
 
@@ -26,14 +26,14 @@ def test_truss_with_no_annotations():
26
26
  _ = tr.docker_run(local_port=8090, detach=True, wait_for_server_ready=True)
27
27
 
28
28
  response = requests.post(INFERENCE_URL, json={"prompt": "value"})
29
- assert response.json() == {
30
- "prompt": "value",
31
- }
29
+ assert response.json() == {"prompt": "value"}
32
30
 
33
31
  schema_response = requests.get(SCHEMA_URL)
34
32
  assert schema_response.status_code == 404
35
33
 
36
34
  assert schema_response.json()["error"] == "No schema found"
35
+ assert schema_response.headers["x-baseten-error-source"] == "04"
36
+ assert schema_response.headers["x-baseten-error-code"] == "600"
37
37
 
38
38
 
39
39
  @pytest.mark.integration
@@ -57,8 +57,9 @@ class Model:
57
57
 
58
58
  schema_response = requests.get(SCHEMA_URL)
59
59
  assert schema_response.status_code == 404
60
-
61
60
  assert schema_response.json()["error"] == "No schema found"
61
+ assert schema_response.headers["x-baseten-error-source"] == "04"
62
+ assert schema_response.headers["x-baseten-error-code"] == "600"
62
63
 
63
64
 
64
65
  @pytest.mark.integration
@@ -92,40 +93,48 @@ class Model:
92
93
 
93
94
 
94
95
  @pytest.mark.integration
95
- def test_truss_with_annotated_inputs_outputs():
96
- truss_root = Path(__file__).parent.parent.resolve()
97
-
98
- truss_dir = truss_root / "test_data" / "annotated_types_truss"
96
+ def test_truss_with_annotated_inputs_outputs(test_data_path):
97
+ truss_dir = test_data_path / "annotated_types_truss"
99
98
 
100
99
  tr = TrussHandle(truss_dir)
101
100
 
102
101
  with ensure_kill_all():
103
102
  _ = tr.docker_run(local_port=8090, detach=True, wait_for_server_ready=True)
103
+ # Valid JSON input.
104
+ json_input = {"prompt": "value"}
105
+ response = requests.post(INFERENCE_URL, json=json_input)
106
+ assert response.json() == {"generated_text": "value"}
104
107
 
105
- response = requests.post(INFERENCE_URL, json={"prompt": "value"})
106
- assert response.json() == {
107
- "generated_text": "value",
108
- }
108
+ # Valid binary input.
109
+ byte_input = serialization.truss_msgpack_serialize(json_input)
110
+ print(byte_input)
111
+ response = requests.post(
112
+ INFERENCE_URL,
113
+ data=byte_input,
114
+ headers={"Content-Type": "application/octet-stream"},
115
+ )
116
+ assert response.content == b"\x81\xaegenerated_text\xa5value"
109
117
 
110
118
  # An invalid input
111
-
112
119
  response = requests.post(INFERENCE_URL, json={"bad_key": "value"})
113
-
114
120
  assert response.status_code == 400
115
121
  assert "error" in response.json()
116
- assert "Request Validation Error" in response.json()["error"]
122
+ assert (
123
+ "Input Parsing Error:\n `prompt`: Field required."
124
+ in response.json()["error"]
125
+ )
126
+ assert response.headers["x-baseten-error-source"] == "04"
127
+ assert response.headers["x-baseten-error-code"] == "700"
117
128
 
129
+ # Schema response.
118
130
  schema_response = requests.get(SCHEMA_URL)
119
-
120
131
  schema = schema_response.json()
121
-
122
132
  assert schema["input_schema"] == {
123
133
  "properties": {"prompt": {"title": "Prompt", "type": "string"}},
124
134
  "required": ["prompt"],
125
135
  "title": "ModelInput",
126
136
  "type": "object",
127
137
  }
128
-
129
138
  assert schema["output_schema"] == {
130
139
  "properties": {
131
140
  "generated_text": {"title": "Generated Text", "type": "string"}
@@ -442,9 +451,7 @@ class Model:
442
451
  schema = schema_response.json()
443
452
 
444
453
  assert schema["input_schema"] == {
445
- "properties": {
446
- "prompt": {"title": "Prompt", "type": "string"},
447
- },
454
+ "properties": {"prompt": {"title": "Prompt", "type": "string"}},
448
455
  "required": ["prompt"],
449
456
  "title": "ModelInput",
450
457
  "type": "object",
@@ -1,15 +1,15 @@
1
1
  # This file contains shared code to be used in other tests
2
2
  # TODO(pankaj): Using a tests file for shared code is not ideal, we should
3
3
  # move it to a regular file. This is a short term hack.
4
-
4
+ import json
5
+ import logging
5
6
  import shutil
6
7
  import subprocess
7
8
  import time
8
9
  from contextlib import contextmanager
9
10
 
10
- from truss.build import kill_all
11
- from truss.constants import TRUSS
12
- from truss.docker import get_containers
11
+ from truss.base.constants import TRUSS
12
+ from truss.util.docker import get_containers, kill_all
13
13
 
14
14
  DISK_SPACE_LOW_PERCENTAGE = 20
15
15
 
@@ -17,12 +17,57 @@ DISK_SPACE_LOW_PERCENTAGE = 20
17
17
  @contextmanager
18
18
  def ensure_kill_all():
19
19
  try:
20
- yield
20
+ with _show_container_logs_if_raised():
21
+ yield
21
22
  finally:
22
23
  kill_all_with_retries()
23
24
  ensure_free_disk_space()
24
25
 
25
26
 
27
+ def _human_readable_json_logs(raw_logs: str) -> str:
28
+ output = []
29
+ for line in raw_logs.splitlines():
30
+ try:
31
+ log_entry = json.loads(line)
32
+ human_readable_log = " ".join(
33
+ f"{key}: {value}" for key, value in log_entry.items()
34
+ )
35
+ output.append(f"\t{human_readable_log}")
36
+ except Exception:
37
+ output.append(line)
38
+ return "\n".join(output)
39
+
40
+
41
+ @contextmanager
42
+ def _show_container_logs_if_raised():
43
+ initial_ids = {c.id for c in get_containers({TRUSS: True})}
44
+ exception_raised = False
45
+ try:
46
+ yield
47
+ except Exception:
48
+ exception_raised = True
49
+ raise
50
+ finally:
51
+ if exception_raised:
52
+ print("An exception was raised, showing logs of all containers.")
53
+ containers = get_containers({TRUSS: True})
54
+ new_containers = [c for c in containers if c.id not in initial_ids]
55
+ parts = ["\n"]
56
+ for container in new_containers:
57
+ parts.append(f"Logs for container {container.name} ({container.id}):")
58
+ parts.append(_human_readable_json_logs(container.logs()))
59
+ parts.append("\n")
60
+ logging.warning("\n".join(parts))
61
+
62
+
63
+ def get_container_logs_from_prefix(prefix: str) -> str:
64
+ containers = get_containers({TRUSS: True})
65
+ for container in containers:
66
+ if container.name.startswith(prefix):
67
+ return _human_readable_json_logs(container.logs())
68
+ return ""
69
+
70
+
26
71
  def kill_all_with_retries(num_retries: int = 10):
27
72
  kill_all()
28
73
  attempts = 0
@@ -1,8 +1,8 @@
1
1
  from pathlib import Path
2
2
  from typing import List
3
3
 
4
- from truss.patch.dir_signature import directory_content_signature
5
- from truss.truss_gatherer import gather
4
+ from truss.truss_handle.patch.dir_signature import directory_content_signature
5
+ from truss.truss_handle.truss_gatherer import gather
6
6
 
7
7
 
8
8
  def test_gather(custom_model_with_external_package):
@@ -21,9 +21,7 @@ def test_gather(custom_model_with_external_package):
21
21
  ext_pkg_top_module2.unlink()
22
22
 
23
23
  assert _same_dir_content(
24
- custom_model_with_external_package,
25
- gathered_truss_path,
26
- ["config.yaml"],
24
+ custom_model_with_external_package, gathered_truss_path, ["config.yaml"]
27
25
  )
28
26
 
29
27
 
@@ -7,16 +7,24 @@ import pytest
7
7
  import requests
8
8
  from python_on_whales.exceptions import DockerException
9
9
  from tenacity import RetryError
10
- from truss.docker import Docker, DockerStates
11
- from truss.errors import ContainerIsDownError, ContainerNotFoundError
10
+
11
+ from truss.base.custom_types import Example
12
+ from truss.base.errors import ContainerIsDownError, ContainerNotFoundError
13
+ from truss.base.truss_config import map_local_to_supported_python_version
12
14
  from truss.local.local_config_handler import LocalConfigHandler
13
- from truss.server.control.patch.types import Action, ModelCodePatch, Patch, PatchType
15
+ from truss.templates.control.control.helpers.custom_types import (
16
+ Action,
17
+ ModelCodePatch,
18
+ Patch,
19
+ PatchType,
20
+ )
14
21
  from truss.tests.test_testing_utilities_for_other_tests import (
15
22
  ensure_kill_all,
16
23
  kill_all_with_retries,
17
24
  )
18
- from truss.truss_handle import TrussHandle, wait_for_truss
19
- from truss.types import Example, PatchRequest
25
+ from truss.truss_handle.patch.custom_types import PatchRequest
26
+ from truss.truss_handle.truss_handle import TrussHandle, wait_for_truss
27
+ from truss.util.docker import Docker, DockerStates
20
28
 
21
29
 
22
30
  def test_spec(custom_model_truss_dir_with_pre_and_post):
@@ -51,16 +59,18 @@ def test_server_predict(custom_model_truss_dir_with_pre_and_post):
51
59
  assert resp == {"predictions": [4, 5, 6, 7]}
52
60
 
53
61
 
54
- def test_readme_generation_int_example(custom_model_truss_dir_with_pre_and_post):
62
+ def test_readme_generation_int_example(
63
+ test_data_path, custom_model_truss_dir_with_pre_and_post
64
+ ):
55
65
  th = TrussHandle(custom_model_truss_dir_with_pre_and_post)
56
66
  readme_contents = th.generate_readme()
57
67
  readme_contents = readme_contents.replace("\n", "")
58
- correct_readme_contents = _read_readme("readme_int_example.md")
68
+ correct_readme_contents = _read_readme(test_data_path / "readme_int_example.md")
59
69
  assert readme_contents == correct_readme_contents
60
70
 
61
71
 
62
72
  def test_readme_generation_no_example(
63
- custom_model_truss_dir_with_pre_and_post_no_example,
73
+ test_data_path, custom_model_truss_dir_with_pre_and_post_no_example
64
74
  ):
65
75
  th = TrussHandle(custom_model_truss_dir_with_pre_and_post_no_example)
66
76
  if os.path.exists(th._spec.examples_path):
@@ -68,17 +78,17 @@ def test_readme_generation_no_example(
68
78
  os.remove(th._spec.examples_path)
69
79
  readme_contents = th.generate_readme()
70
80
  readme_contents = readme_contents.replace("\n", "")
71
- correct_readme_contents = _read_readme("readme_no_example.md")
81
+ correct_readme_contents = _read_readme(test_data_path / "readme_no_example.md")
72
82
  assert readme_contents == correct_readme_contents
73
83
 
74
84
 
75
85
  def test_readme_generation_str_example(
76
- custom_model_truss_dir_with_pre_and_post_str_example,
86
+ test_data_path, custom_model_truss_dir_with_pre_and_post_str_example
77
87
  ):
78
88
  th = TrussHandle(custom_model_truss_dir_with_pre_and_post_str_example)
79
89
  readme_contents = th.generate_readme()
80
90
  readme_contents = readme_contents.replace("\n", "")
81
- correct_readme_contents = _read_readme("readme_str_example.md")
91
+ correct_readme_contents = _read_readme(test_data_path / "readme_str_example.md")
82
92
  assert readme_contents == correct_readme_contents
83
93
 
84
94
 
@@ -96,6 +106,7 @@ def test_build_docker_image(custom_model_truss_dir_with_pre_and_post):
96
106
  [
97
107
  ("baseten/truss-server-base:3.9-v0.4.8rc4", "/usr/local/bin/python3", False),
98
108
  ("python:3.8", "/usr/local/bin/python3", False),
109
+ ("python:3.10", "/usr/local/bin/python3", False),
99
110
  ("python:3.11", "/usr/local/bin/python3", False),
100
111
  ("python:alpine", "/usr/local/bin/python3", True),
101
112
  ("python:2.7-slim", "/usr/local/bin/python", True),
@@ -389,15 +400,10 @@ def test_enable_gpu(custom_model_truss_dir_with_pre_and_post):
389
400
 
390
401
  @pytest.mark.parametrize(
391
402
  "python_version, expected_python_version",
392
- [
393
- ("3.8", "py38"),
394
- ("py38", "py38"),
395
- ],
403
+ [("3.8", "py38"), ("py38", "py38"), ("3.9", "py39"), ("py39", "py39")],
396
404
  )
397
405
  def test_update_python_version(
398
- python_version,
399
- expected_python_version,
400
- custom_model_truss_dir_with_pre_and_post,
406
+ python_version, expected_python_version, custom_model_truss_dir_with_pre_and_post
401
407
  ):
402
408
  th = TrussHandle(custom_model_truss_dir_with_pre_and_post)
403
409
  th.update_python_version(python_version)
@@ -406,10 +412,7 @@ def test_update_python_version(
406
412
 
407
413
  def test_update_requirements(custom_model_truss_dir_with_pre_and_post):
408
414
  th = TrussHandle(custom_model_truss_dir_with_pre_and_post)
409
- requirements = [
410
- "tensorflow==2.3.1",
411
- "uvicorn==0.12.2",
412
- ]
415
+ requirements = ["tensorflow==2.3.1", "uvicorn==0.12.2"]
413
416
  th.update_requirements(requirements)
414
417
  sc_requirements = th.spec.requirements
415
418
  assert sc_requirements == requirements
@@ -425,10 +428,7 @@ def test_update_requirements_from_file(
425
428
  " # this is comment with a big space. Please don't add.",
426
429
  "uvicorn==0.12.2",
427
430
  ]
428
- allowed_requirements = [
429
- "tensorflow==2.3.1",
430
- "uvicorn==0.12.2",
431
- ]
431
+ allowed_requirements = ["tensorflow==2.3.1", "uvicorn==0.12.2"]
432
432
  req_file_path = tmp_path / "requirements.txt"
433
433
  with req_file_path.open("w") as req_file:
434
434
  for req in file_requirements:
@@ -450,6 +450,25 @@ def test_add_environment_variable(custom_model_truss_dir_with_pre_and_post):
450
450
  Docker.client().kill(container)
451
451
 
452
452
 
453
+ @pytest.mark.integration
454
+ def test_build_commands(test_data_path):
455
+ truss_dir = test_data_path / "test_build_commands"
456
+ tr = TrussHandle(truss_dir)
457
+ with ensure_kill_all():
458
+ r1 = tr.docker_predict([1, 2])
459
+ assert r1 == {"predictions": [1, 2]}
460
+
461
+
462
+ @pytest.mark.integration
463
+ def test_build_commands_failure(test_data_path):
464
+ truss_dir = test_data_path / "test_build_commands_failure"
465
+ tr = TrussHandle(truss_dir)
466
+ try:
467
+ tr.docker_run(local_port=8090, detach=True, wait_for_server_ready=True)
468
+ except DockerException as exc:
469
+ assert "It returned with code 1" in str(exc)
470
+
471
+
453
472
  def test_add_data_file(custom_model_truss_dir_with_pre_and_post, tmp_path):
454
473
  th = TrussHandle(custom_model_truss_dir_with_pre_and_post)
455
474
  data_filepath = tmp_path / "test_data.txt"
@@ -513,18 +532,13 @@ def test_add_example_new(custom_model_truss_dir_with_pre_and_post):
513
532
  th = TrussHandle(custom_model_truss_dir_with_pre_and_post)
514
533
  orig_examples = th.examples()
515
534
  th.add_example("example2", [[1]])
516
- assert th.examples() == [
517
- *orig_examples,
518
- Example("example2", [[1]]),
519
- ]
535
+ assert th.examples() == [*orig_examples, Example("example2", [[1]])]
520
536
 
521
537
 
522
538
  def test_add_example_update(custom_model_truss_dir_with_pre_and_post):
523
539
  th = TrussHandle(custom_model_truss_dir_with_pre_and_post)
524
540
  th.add_example("example1", [[1]])
525
- assert th.examples() == [
526
- Example("example1", [[1]]),
527
- ]
541
+ assert th.examples() == [Example("example1", [[1]])]
528
542
 
529
543
 
530
544
  def test_model_without_pre_post(custom_model_truss_dir):
@@ -562,11 +576,9 @@ class Model:
562
576
  Patch(
563
577
  type=PatchType.MODEL_CODE,
564
578
  body=ModelCodePatch(
565
- action=Action.UPDATE,
566
- path="model.py",
567
- content=new_model_code,
579
+ action=Action.UPDATE, path="model.py", content=new_model_code
568
580
  ),
569
- ),
581
+ )
570
582
  ],
571
583
  )
572
584
 
@@ -604,10 +616,9 @@ class Model:
604
616
  assert len(th.get_all_docker_images()) == orig_num_truss_images + 1
605
617
 
606
618
 
607
- @patch("truss.truss_handle.directory_content_hash")
619
+ @patch("truss.truss_handle.truss_handle.directory_content_hash")
608
620
  def test_truss_hash_caching_based_on_max_mod_time(
609
- directory_content_patcher,
610
- custom_model_truss_dir,
621
+ directory_content_patcher, custom_model_truss_dir
611
622
  ):
612
623
  directory_content_patcher.return_value = "mock_hash"
613
624
  th = TrussHandle(custom_model_truss_dir)
@@ -623,14 +634,14 @@ def test_truss_hash_caching_based_on_max_mod_time(
623
634
  directory_content_patcher.call_count == 2
624
635
 
625
636
 
626
- @patch("truss.truss_handle.get_container_state")
637
+ @patch("truss.truss_handle.truss_handle.get_container_state")
627
638
  def test_container_oom_caught_during_waiting(container_state_mock):
628
639
  container_state_mock.return_value = DockerStates.OOMKILLED
629
640
  with pytest.raises(ContainerIsDownError):
630
641
  wait_for_truss(url="localhost:8000", container=MagicMock())
631
642
 
632
643
 
633
- @patch("truss.truss_handle.get_container_state")
644
+ @patch("truss.truss_handle.truss_handle.get_container_state")
634
645
  @pytest.mark.integration
635
646
  def test_container_stuck_in_created(container_state_mock):
636
647
  container_state_mock.return_value = DockerStates.CREATED
@@ -674,10 +685,7 @@ class Model:
674
685
  @pytest.mark.integration
675
686
  @pytest.mark.parametrize(
676
687
  "patch_path, expected_call_count",
677
- [
678
- ("hash_is_current", 1),
679
- ("hash_is_current_but_only_every_third_call_succeeds", 3),
680
- ],
688
+ [("hash_is_current", 1), ("hash_is_current_but_only_every_third_call_succeeds", 3)],
681
689
  )
682
690
  def test_patch_ping_flow(
683
691
  patch_path, expected_call_count, custom_model_control, patch_ping_test_server
@@ -687,11 +695,7 @@ def test_patch_ping_flow(
687
695
  th = TrussHandle(custom_model_control)
688
696
  tag = "test-docker-custom-model-control-tag:0.0.1"
689
697
  with ensure_kill_all():
690
- result = th.docker_predict(
691
- [1],
692
- tag=tag,
693
- patch_ping_url=patch_ping_url,
694
- )
698
+ result = th.docker_predict([1], tag=tag, patch_ping_url=patch_ping_url)
695
699
  assert result == [1]
696
700
 
697
701
  # Make sure the patch ping url was actually hit
@@ -775,28 +779,27 @@ def verify_python_requirement_not_installed_on_container(container, req: str):
775
779
 
776
780
 
777
781
  def verify_environment_variable_on_container(
778
- container,
779
- env_var_name: str,
780
- env_var_value: str,
782
+ container, env_var_name: str, env_var_value: str
781
783
  ):
782
784
  resp = container.execute(["env"])
783
785
  needle = f"{env_var_name}={env_var_value}"
784
786
  assert needle in resp.splitlines()
785
787
 
786
788
 
787
- def _read_readme(filename: str) -> str:
788
- readme_correct_path = Path(__file__).parent.parent / "test_data" / filename
789
- readme_contents = readme_correct_path.open().read().replace("\n", "")
790
- return readme_contents
789
+ def _read_readme(readme_correct_path: Path) -> str:
790
+ return readme_correct_path.open().read().replace("\n", "")
791
791
 
792
792
 
793
793
  def generate_default_config():
794
+ # The test fixture varies with host version.
795
+ python_version = map_local_to_supported_python_version()
794
796
  config = {
797
+ "build_commands": [],
795
798
  "environment_variables": {},
796
799
  "external_package_dirs": [],
797
800
  "model_metadata": {},
798
801
  "model_name": None,
799
- "python_version": "py39",
802
+ "python_version": python_version,
800
803
  "requirements": [],
801
804
  "resources": {
802
805
  "accelerator": None,
truss/tests/test_util.py CHANGED
@@ -2,7 +2,8 @@ import os
2
2
  from unittest.mock import patch
3
3
 
4
4
  import requests_mock
5
- from truss.truss_config import ExternalData
5
+
6
+ from truss.base.truss_config import ExternalData
6
7
  from truss.util.download import download_external_data
7
8
 
8
9
  TEST_DOWNLOAD_URL = "http://example.com/some-download-url"
@@ -1,6 +1,7 @@
1
1
  import pytest
2
- from truss.errors import ValidationError
3
- from truss.validation import (
2
+
3
+ from truss.base.errors import ValidationError
4
+ from truss.base.validation import (
4
5
  validate_cpu_spec,
5
6
  validate_memory_spec,
6
7
  validate_secret_name,
@@ -64,21 +65,22 @@ def test_validate_cpu_spec(cpu_spec, expected_valid):
64
65
 
65
66
 
66
67
  @pytest.mark.parametrize(
67
- "mem_spec, expected_valid",
68
+ "mem_spec, expected_valid, memory_in_bytes",
68
69
  [
69
- (None, False),
70
- (1, False),
71
- ("1m", False),
72
- ("1k", True),
73
- ("512k", True),
74
- ("512M", True),
75
- ("1.5Gi", True),
76
- ("abc", False),
70
+ (None, False, None),
71
+ (1, False, None),
72
+ ("1m", False, None),
73
+ ("1k", True, 10**3),
74
+ ("512k", True, 512 * 10**3),
75
+ ("512M", True, 512 * 10**6),
76
+ ("1.5Gi", True, 1.5 * 1024**3),
77
+ ("abc", False, None),
78
+ ("1024", True, 1024),
77
79
  ],
78
80
  )
79
- def test_validate_mem_spec(mem_spec, expected_valid):
81
+ def test_validate_mem_spec(mem_spec, expected_valid, memory_in_bytes):
80
82
  if not expected_valid:
81
83
  with pytest.raises(ValidationError):
82
84
  validate_memory_spec(mem_spec)
83
85
  else:
84
- validate_memory_spec(mem_spec)
86
+ assert memory_in_bytes == validate_memory_spec(mem_spec)
@@ -0,0 +1,41 @@
1
+ from truss.base.trt_llm_config import (
2
+ TRTLLMConfiguration,
3
+ TrussTRTLLMBatchSchedulerPolicy,
4
+ TrussTRTLLMBuildConfiguration,
5
+ TrussTRTLLMRuntimeConfiguration,
6
+ )
7
+
8
+
9
+ def test_trt_llm_config_init_from_pydantic_models(trtllm_config):
10
+ build_config = TrussTRTLLMBuildConfiguration(**trtllm_config["trt_llm"]["build"])
11
+ TRTLLMConfiguration(build=build_config, runtime=TrussTRTLLMRuntimeConfiguration())
12
+
13
+
14
+ def test_trt_llm_configuration_init_and_migrate_deprecated_runtime_fields(
15
+ deprecated_trtllm_config,
16
+ ):
17
+ trt_llm_config = TRTLLMConfiguration(**deprecated_trtllm_config["trt_llm"])
18
+ assert trt_llm_config.runtime.model_dump() == {
19
+ "kv_cache_free_gpu_mem_fraction": 0.1,
20
+ "kv_cache_host_memory_bytes": None,
21
+ "enable_chunked_context": True,
22
+ "batch_scheduler_policy": TrussTRTLLMBatchSchedulerPolicy.MAX_UTILIZATION.value,
23
+ "request_default_max_tokens": 10,
24
+ "total_token_limit": 50,
25
+ }
26
+
27
+
28
+ def test_trt_llm_configuration_init_and_migrate_deprecated_runtime_fields_existing_runtime(
29
+ deprecated_trtllm_config_with_runtime_existing,
30
+ ):
31
+ trt_llm_config = TRTLLMConfiguration(
32
+ **deprecated_trtllm_config_with_runtime_existing["trt_llm"]
33
+ )
34
+ assert trt_llm_config.runtime.model_dump() == {
35
+ "kv_cache_free_gpu_mem_fraction": 0.1,
36
+ "kv_cache_host_memory_bytes": None,
37
+ "enable_chunked_context": True,
38
+ "batch_scheduler_policy": TrussTRTLLMBatchSchedulerPolicy.MAX_UTILIZATION.value,
39
+ "request_default_max_tokens": 10,
40
+ "total_token_limit": 100,
41
+ }
@@ -0,0 +1,91 @@
1
+ import pytest
2
+ from truss.base.errors import ValidationError
3
+ from truss.base.truss_spec import TrussSpec
4
+ from truss.trt_llm.validation import _verify_has_class_init_arg, validate
5
+
6
+
7
+ @pytest.mark.parametrize(
8
+ "src, class_name, expected_arg, expected_to_raise",
9
+ [
10
+ (
11
+ """
12
+ class Model:
13
+ def __init__(self, foo):
14
+ pass
15
+ """,
16
+ "Model",
17
+ "foo",
18
+ False,
19
+ ),
20
+ # Missing arg
21
+ (
22
+ """
23
+ class Model:
24
+ def __init__(self, foo):
25
+ pass
26
+ """,
27
+ "Model",
28
+ "bar",
29
+ True,
30
+ ),
31
+ # Missing class
32
+ (
33
+ """
34
+ class Model:
35
+ def __init__(self, foo):
36
+ pass
37
+ """,
38
+ "Missing",
39
+ "bar",
40
+ True,
41
+ ),
42
+ # With default value should still work
43
+ (
44
+ """
45
+ class Model:
46
+ def __init__(self, foo=None):
47
+ pass
48
+ """,
49
+ "Model",
50
+ "foo",
51
+ False,
52
+ ),
53
+ # not the only arg
54
+ (
55
+ """
56
+ class Model:
57
+ def __init__(self, first, foo, third):
58
+ pass
59
+ """,
60
+ "Model",
61
+ "foo",
62
+ False,
63
+ ),
64
+ ],
65
+ )
66
+ def test_has_class_init_arg(src, expected_arg, class_name, expected_to_raise):
67
+ if expected_to_raise:
68
+ with pytest.raises(ValidationError):
69
+ _verify_has_class_init_arg(src, class_name, expected_arg)
70
+ else:
71
+ _verify_has_class_init_arg(src, class_name, expected_arg)
72
+
73
+
74
+ def test_validate(custom_model_trt_llm):
75
+ spec = TrussSpec(custom_model_trt_llm)
76
+ validate(spec)
77
+
78
+ # overwrite with model code that doesn't take trt_llm as input
79
+ override_model_code_invalid = """
80
+ class Model:
81
+ def __init__(self):
82
+ pass
83
+ """
84
+ spec.model_class_filepath.write_text(override_model_code_invalid)
85
+ new_spec = TrussSpec(custom_model_trt_llm)
86
+ with pytest.raises(ValidationError):
87
+ validate(new_spec)
88
+
89
+ # If model class file is removed, it should be ok
90
+ spec.model_class_filepath.unlink()
91
+ validate(new_spec)