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
truss/build/build.py DELETED
@@ -1,143 +0,0 @@
1
- import logging
2
- import os
3
- import sys
4
- from pathlib import Path
5
- from typing import List, Optional
6
-
7
- import yaml
8
- from truss.constants import CONFIG_FILE, TEMPLATES_DIR, TRUSS
9
- from truss.docker import kill_containers
10
- from truss.model_inference import infer_python_version, map_to_supported_python_version
11
- from truss.notebook import is_notebook_or_ipython
12
- from truss.truss_config import Build, TrussConfig
13
- from truss.truss_handle import TrussHandle
14
- from truss.util.path import build_truss_target_directory, copy_tree_path
15
-
16
- logger: logging.Logger = logging.getLogger(__name__)
17
-
18
- if is_notebook_or_ipython():
19
- logger.setLevel(logging.INFO)
20
- logger.addHandler(logging.StreamHandler(sys.stdout))
21
-
22
-
23
- def populate_target_directory(
24
- config: TrussConfig,
25
- target_directory_path: Optional[str] = None,
26
- template: str = "custom",
27
- populate_dirs: bool = True,
28
- ) -> Path:
29
- target_directory_path_typed = None
30
- if target_directory_path is None:
31
- target_directory_path_typed = build_truss_target_directory(template)
32
- else:
33
- target_directory_path_typed = Path(target_directory_path)
34
- target_directory_path_typed.mkdir(parents=True, exist_ok=True)
35
-
36
- if populate_dirs:
37
- # Create data dir
38
- (target_directory_path_typed / config.data_dir).mkdir()
39
-
40
- # Create bundled packages dir
41
- # TODO: Drop by default
42
- (target_directory_path_typed / config.bundled_packages_dir).mkdir()
43
-
44
- # Create model module dir
45
- model_dir = target_directory_path_typed / config.model_module_dir
46
- template_path = TEMPLATES_DIR / template
47
- copy_tree_path(template_path / "model", model_dir)
48
-
49
- # Write config
50
- with (target_directory_path_typed / CONFIG_FILE).open("w") as config_file:
51
- yaml.dump(config.to_dict(verbose=False), config_file)
52
-
53
- return target_directory_path_typed
54
-
55
-
56
- def init(
57
- target_directory: str,
58
- data_files: Optional[List[str]] = None,
59
- requirements_file: Optional[str] = None,
60
- bundled_packages: Optional[List[str]] = None,
61
- build_config: Optional[Build] = None,
62
- model_name: Optional[str] = None,
63
- ) -> TrussHandle:
64
- """
65
- Initialize an empty placeholder Truss. A Truss is a build context designed
66
- to be built as a container locally or uploaded into a baseten serving
67
- environment. This placeholder structure can be filled to represent ML
68
- models.
69
-
70
- Args:
71
- target_directory: Absolute or relative path of the directory to create
72
- Truss in. The directory is created if it doesn't exist.
73
- """
74
- config = TrussConfig(
75
- model_name=model_name,
76
- python_version=map_to_supported_python_version(infer_python_version()),
77
- )
78
-
79
- if build_config:
80
- config.build = build_config
81
-
82
- target_directory_path = populate_target_directory(
83
- config=config,
84
- target_directory_path=target_directory,
85
- populate_dirs=True,
86
- )
87
-
88
- scaf = TrussHandle(target_directory_path)
89
- _update_truss_props(scaf, data_files, requirements_file, bundled_packages)
90
- return scaf
91
-
92
-
93
- def load(truss_directory: str) -> TrussHandle:
94
- """Get a handle to a Truss. A Truss is a build context designed to be built
95
- as a container locally or uploaded into a model serving environment.
96
-
97
- Args:
98
- truss_directory (str): The local directory of an existing Truss
99
- Returns:
100
- TrussHandle
101
- """
102
- return TrussHandle(Path(truss_directory))
103
-
104
-
105
- def from_directory(*args, **kwargs):
106
- logger.warn(
107
- "DeprecationWarning: from_directory() is deprecated. Use load() instead."
108
- )
109
- return load(*args, **kwargs)
110
-
111
-
112
- def cleanup() -> None:
113
- """
114
- Cleans up .truss directory.
115
- """
116
- build_folder_path = Path(Path.home(), ".truss")
117
- if build_folder_path.exists():
118
- for obj in build_folder_path.glob("**/*"):
119
- if (not obj.name == "config.yaml") and (obj.is_file()):
120
- os.remove(obj)
121
- return
122
-
123
-
124
- def _update_truss_props(
125
- scaf: TrussHandle,
126
- data_files: Optional[List[str]] = None,
127
- requirements_file: Optional[str] = None,
128
- bundled_packages: Optional[List[str]] = None,
129
- ) -> None:
130
- if data_files is not None:
131
- for data_file in data_files:
132
- scaf.add_data(data_file)
133
-
134
- if bundled_packages is not None:
135
- for package in bundled_packages:
136
- scaf.add_bundled_package(package)
137
-
138
- if requirements_file is not None:
139
- scaf.update_requirements_from_file(requirements_file)
140
-
141
-
142
- def kill_all() -> None:
143
- kill_containers({TRUSS: True})
truss/build/configure.py DELETED
@@ -1,63 +0,0 @@
1
- import json
2
- import logging
3
- import os
4
- import sys
5
- from pathlib import Path
6
- from typing import Optional
7
-
8
- import typer
9
- from truss import load
10
- from truss.patch.hash import directory_content_hash
11
- from truss.patch.signature import calc_truss_signature
12
- from truss.patch.truss_dir_patch_applier import TrussDirPatchApplier
13
- from truss.server.control.patch.types import Patch
14
-
15
- logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
16
-
17
-
18
- app = typer.Typer()
19
-
20
-
21
- @app.command()
22
- def configure_truss_for_build(
23
- truss_dir: str,
24
- build_context_path: str,
25
- use_control_server: bool = False,
26
- patches_path: Optional[str] = None,
27
- hash_file_path: Optional[str] = None,
28
- signature_file_path: Optional[str] = None,
29
- ):
30
- tr = load(truss_dir)
31
-
32
- if patches_path is not None:
33
- logging.info("Applying patches")
34
- logger = logging.getLogger("patch_applier")
35
- patch_applier = TrussDirPatchApplier(Path(truss_dir), logger)
36
- patches = json.loads(Path(patches_path).read_text())
37
- patch_applier([Patch.from_dict(patch) for patch in patches])
38
-
39
- # Important to do this before making changes to truss, we want
40
- # to capture hash of original truss.
41
- if hash_file_path is not None:
42
- logging.info("Recording truss hash")
43
- Path(hash_file_path).write_text(directory_content_hash(Path(truss_dir)))
44
-
45
- if signature_file_path is not None:
46
- logging.info("Recording truss signature")
47
- signature_str = json.dumps(calc_truss_signature(Path(truss_dir)).to_dict())
48
- Path(signature_file_path).write_text(signature_str)
49
-
50
- tr.live_reload(enable=use_control_server)
51
-
52
- logging.debug("Setting up docker build context for truss")
53
-
54
- # check if we have a hf_secret
55
- tr.docker_build_setup(
56
- Path(build_context_path), use_hf_secret="HUGGING_FACE_HUB_TOKEN" in os.environ
57
- )
58
- logging.info("docker build context is set up for the truss")
59
-
60
-
61
- if __name__ == "__main__":
62
- # parse the things
63
- app()
truss/cli/__init__.py DELETED
@@ -1,2 +0,0 @@
1
- # flake8: noqa
2
- from truss.cli.cli import truss_cli
truss/cli/console.py DELETED
@@ -1,5 +0,0 @@
1
- import rich
2
-
3
- console = rich.console.Console()
4
-
5
- error_console = rich.console.Console(stderr=True, style="bold red")
truss/cli/create.py DELETED
@@ -1,5 +0,0 @@
1
- from InquirerPy import inquirer
2
-
3
-
4
- def ask_name() -> str:
5
- return inquirer.text(message="What's the name of your model?").execute()
truss/config/trt_llm.py DELETED
@@ -1,81 +0,0 @@
1
- import logging
2
- from enum import Enum
3
- from typing import Optional
4
-
5
- from pydantic import BaseModel, model_validator
6
-
7
- logging.basicConfig(level=logging.INFO)
8
- logger = logging.getLogger(__name__)
9
-
10
-
11
- class TRTLLMModelArchitecture(Enum):
12
- LLAMA: str = "llama"
13
- MISTRAL: str = "mistral"
14
-
15
-
16
- class TRTLLMQuantizationType(Enum):
17
- NO_QUANT: str = "no_quant"
18
- WEIGHTS_ONLY_INT8: str = "weights_int8"
19
- WEIGHTS_KV_INT8: str = "weights_kv_int8"
20
- WEIGHTS_ONLY_INT4: str = "weights_int4"
21
- WEIGHTS_KV_INT4: str = "weights_kv_int4"
22
- SMOOTH_QUANT: str = "smooth_quant"
23
- FP8: str = "fp8"
24
- FP8_KV: str = "fp8_kv"
25
-
26
-
27
- class TrussTRTLLMPluginConfiguration(BaseModel):
28
- multi_block_mode: bool = False
29
- paged_kv_cache: bool = False
30
- use_fused_mlp: bool = False
31
-
32
-
33
- class TrussTRTLLMBuildConfiguration(BaseModel):
34
- huggingface_ckpt_repository: str
35
- base_model_architecture: TRTLLMModelArchitecture
36
- max_input_len: int
37
- max_output_len: int
38
- max_batch_size: int
39
- max_beam_width: int = 1
40
- max_prompt_embedding_table_size: int = 0
41
- gather_all_token_logits: bool = False
42
- strongly_typed: bool = False
43
- quantization_type: TRTLLMQuantizationType = TRTLLMQuantizationType.NO_QUANT
44
- tensor_parallel_count: int = 1
45
- pipeline_parallel_count: int = 1
46
- plugin_configuration: TrussTRTLLMPluginConfiguration = (
47
- TrussTRTLLMPluginConfiguration()
48
- )
49
-
50
-
51
- class TrussTRTLLMServingConfiguration(BaseModel):
52
- engine_repository: str
53
- tokenizer_repository: str
54
- tensor_parallel_count: int = 1
55
- pipeline_parallel_count: int = 1
56
-
57
-
58
- class TRTLLMConfiguration(BaseModel):
59
- serve: Optional[TrussTRTLLMServingConfiguration] = None
60
- build: Optional[TrussTRTLLMBuildConfiguration] = None
61
-
62
- @model_validator(mode="after")
63
- def check_minimum_required_configuration(self):
64
- if not self.serve and not self.build:
65
- raise ValueError("Either serve or build configurations must be provided")
66
- if self.serve and self.build:
67
- raise ValueError("Both serve and build configurations cannot be provided")
68
- if self.serve is not None:
69
- if (self.serve.engine_repository is None) ^ (
70
- self.serve.tokenizer_repository is None
71
- ):
72
- raise ValueError(
73
- "Both engine_repository and tokenizer_repository must be provided"
74
- )
75
- return self
76
-
77
- @property
78
- def requires_build(self):
79
- if self.build is not None:
80
- return True
81
- return False
truss/constants.py DELETED
@@ -1,61 +0,0 @@
1
- import os
2
- import pathlib
3
-
4
- TRUSS_PACKAGE_DIR = pathlib.Path(__file__).resolve().parent
5
-
6
- SKLEARN = "sklearn"
7
- TENSORFLOW = "tensorflow"
8
- KERAS = "keras"
9
- XGBOOST = "xgboost"
10
- PYTORCH = "pytorch"
11
- CUSTOM = "custom"
12
- HUGGINGFACE_TRANSFORMER = "huggingface_transformer"
13
- LIGHTGBM = "lightgbm"
14
-
15
- BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
16
- CODE_DIR = pathlib.Path(BASE_DIR, "truss")
17
-
18
- TEMPLATES_DIR = pathlib.Path(CODE_DIR, "templates")
19
- TRTLLM_TRUSS_DIR: pathlib.Path = TEMPLATES_DIR / "trtllm"
20
-
21
- SUPPORTED_PYTHON_VERSIONS = {"3.8", "3.9", "3.10", "3.11"}
22
-
23
-
24
- REQUIREMENTS_TXT_FILENAME = "requirements.txt"
25
- USER_SUPPLIED_REQUIREMENTS_TXT_FILENAME = "user_requirements.txt"
26
- SYSTEM_PACKAGES_TXT_FILENAME = "system_packages.txt"
27
-
28
- FILENAME_CONSTANTS_MAP = {
29
- "config_requirements_filename": REQUIREMENTS_TXT_FILENAME,
30
- "user_supplied_requirements_filename": USER_SUPPLIED_REQUIREMENTS_TXT_FILENAME,
31
- "system_packages_filename": SYSTEM_PACKAGES_TXT_FILENAME,
32
- }
33
-
34
- SERVER_DOCKERFILE_TEMPLATE_NAME = "server.Dockerfile.jinja"
35
- MODEL_DOCKERFILE_NAME = "Dockerfile"
36
-
37
- README_TEMPLATE_NAME = "README.md.jinja"
38
- MODEL_README_NAME = "README.md"
39
-
40
- CONFIG_FILE = "config.yaml"
41
- DOCKERFILE = "Dockerfile"
42
- # Used to indicate whether to associate a container with Truss
43
- TRUSS = "truss"
44
- # Used to create unique identifier based on last time truss was updated
45
- TRUSS_MODIFIED_TIME = "truss_modified_time"
46
- # Path of the Truss used to identify which Truss is being referred
47
- TRUSS_DIR = "truss_dir"
48
- TRUSS_HASH = "truss_hash"
49
-
50
- INFERENCE_SERVER_PORT = 8080
51
-
52
- HTTP_PUBLIC_BLOB_BACKEND = "http_public"
53
-
54
- REGISTRY_BUILD_SECRET_PREFIX = "DOCKER_REGISTRY_"
55
-
56
- TRTLLM_BASE_IMAGE = "baseten/trtllm-build-server:r23.12_baseten_v0.7.1_20240111"
57
- BASE_TRTLLM_REQUIREMENTS = [
58
- "tritonclient[all]==2.42.0",
59
- "transformers==4.33.1",
60
- "jinja2==3.1.3",
61
- ]
truss/model_inference.py DELETED
@@ -1,123 +0,0 @@
1
- import inspect
2
- import logging
3
- import sys
4
- from ast import ClassDef, FunctionDef
5
- from dataclasses import dataclass
6
- from typing import Any, Dict, List, Tuple
7
-
8
- logger: logging.Logger = logging.getLogger(__name__)
9
-
10
-
11
- @dataclass
12
- class ModelBuildStageOne:
13
- # the Python Class of the model
14
- model_type: str
15
- # the framework that the model is built in
16
- model_framework: str
17
-
18
-
19
- def _model_class(model: Any):
20
- return model.__class__
21
-
22
-
23
- def infer_python_version() -> str:
24
- return f"py{sys.version_info.major}{sys.version_info.minor}"
25
-
26
-
27
- def map_to_supported_python_version(python_version: str) -> str:
28
- """Map python version to truss supported python version.
29
-
30
- Currently, it maps any versions greater than 3.9 to 3.9.
31
-
32
- Args:
33
- python_version: in the form py[major_version][minor_version] e.g. py39,
34
- py310
35
- """
36
- python_major_version = int(python_version[2:3])
37
- python_minor_version = int(python_version[3:])
38
-
39
- if python_major_version > 3:
40
- raise NotImplementedError("Only python version 3 is supported")
41
-
42
- if python_minor_version > 11:
43
- logger.info(
44
- f"Mapping python version {python_major_version}.{python_minor_version}"
45
- " to 3.11, the highest version that Truss currently supports."
46
- )
47
- return "py311"
48
-
49
- if python_minor_version < 8:
50
- logger.info(
51
- f"Mapping python version {python_major_version}.{python_minor_version}"
52
- " to 3.8, the lowest version that Truss currently supports."
53
- )
54
- return "py38"
55
-
56
- return python_version
57
-
58
-
59
- def _infer_model_init_parameters(model_class: Any) -> Tuple[List, List]:
60
- full_arg_spec = inspect.getfullargspec(model_class.__init__)
61
- named_args = full_arg_spec.args[1:]
62
- number_of_kwargs = full_arg_spec.defaults and len(full_arg_spec.defaults) or 0
63
- required_args = full_arg_spec.args[1:-number_of_kwargs]
64
- return named_args, required_args
65
-
66
-
67
- def _infer_model_init_parameters_ast(model_class_def: ClassDef) -> Tuple[List, List]:
68
- named_args: List[str] = []
69
- required_args: List[str] = []
70
- init_model_functions = [
71
- node
72
- for node in model_class_def.body
73
- if isinstance(node, FunctionDef) and node.name == "__init__"
74
- ]
75
-
76
- if not init_model_functions:
77
- return named_args, required_args
78
-
79
- assert (
80
- len(init_model_functions) == 1
81
- ), "There should only be one __init__ function in the model class"
82
- init_model_function = init_model_functions[0]
83
- named_args = [arg.arg for arg in init_model_function.args.args][1:]
84
- number_of_defaults = len(init_model_function.args.defaults)
85
- required_args = named_args[:-number_of_defaults]
86
- return named_args, required_args
87
-
88
-
89
- def validate_provided_parameters_with_model(
90
- model_class: Any, provided_parameters: Dict[str, Any]
91
- ) -> None:
92
- """
93
- Validates that all provided parameters match the signature of the model.
94
-
95
- Args:
96
- model_class: The model class to validate against
97
- provided_parameters: The parameters to validate
98
- """
99
- if type(model_class) == ClassDef:
100
- named_args, required_args = _infer_model_init_parameters_ast(model_class)
101
- else:
102
- named_args, required_args = _infer_model_init_parameters(model_class)
103
-
104
- # Check that there are no extra parameters
105
- if not named_args:
106
- return
107
-
108
- if provided_parameters and type(provided_parameters) is not dict:
109
- raise TypeError(
110
- f"Provided parameters must be a dict, not {type(provided_parameters)}"
111
- )
112
-
113
- for arg in provided_parameters:
114
- if arg not in named_args:
115
- raise ValueError(
116
- f"Provided parameter {arg} is not a valid init parameter for the model."
117
- )
118
-
119
- for arg in required_args:
120
- if arg not in provided_parameters:
121
- raise ValueError(
122
- f"Required init parameter {arg} was not provided for this model."
123
- )
truss/patch/types.py DELETED
@@ -1,30 +0,0 @@
1
- from dataclasses import dataclass
2
- from typing import Dict
3
-
4
-
5
- @dataclass
6
- class TrussSignature:
7
- """Truss signature stores information for calculating patches for future
8
- changes to Truss.
9
-
10
- Currently, it stores hashes of all of the paths in the truss directory excluding the data dir,
11
- and the truss config contents. Path hashes allow calculating added/updated/removes
12
- paths in future trusses compared to this. Config contents allow calculating
13
- config changes, such as add/update/remove of python requirements etc.
14
- """
15
-
16
- content_hashes_by_path: Dict[str, str]
17
- config: str
18
-
19
- def to_dict(self) -> dict:
20
- return {
21
- "content_hashes_by_path": self.content_hashes_by_path,
22
- "config": self.config,
23
- }
24
-
25
- @staticmethod
26
- def from_dict(d) -> "TrussSignature":
27
- return TrussSignature(
28
- content_hashes_by_path=d["content_hashes_by_path"],
29
- config=d["config"],
30
- )
truss/pytest.ini DELETED
@@ -1,7 +0,0 @@
1
- [pytest]
2
- addopts = --capture=no
3
- filterwarnings =
4
- ignore::DeprecationWarning
5
- ignore::PendingDeprecationWarning
6
- markers =
7
- integration: mark tests for use in local integration testing only (deselect with '-m "not integration"')
@@ -1,100 +0,0 @@
1
- from http import HTTPStatus
2
- from typing import Optional
3
-
4
- from fastapi.responses import JSONResponse
5
-
6
-
7
- class ModelMissingError(Exception):
8
- def __init__(self, path):
9
- self.path = path
10
-
11
- def __str__(self):
12
- return self.path
13
-
14
-
15
- class InferenceError(RuntimeError):
16
- def __init__(self, reason):
17
- self.reason = reason
18
-
19
- def __str__(self):
20
- return self.reason
21
-
22
-
23
- class InvalidInput(ValueError):
24
- """
25
- Exception class indicating invalid input arguments.
26
- HTTP Servers should return HTTP_400 (Bad Request).
27
- """
28
-
29
- def __init__(self, reason):
30
- self.reason = reason
31
-
32
- def __str__(self):
33
- return self.reason
34
-
35
-
36
- class ModelNotFound(Exception):
37
- """
38
- Exception class indicating requested model does not exist.
39
- HTTP Servers should return HTTP_404 (Not Found).
40
- """
41
-
42
- def __init__(self, model_name=None):
43
- self.reason = f"Model with name {model_name} does not exist."
44
-
45
- def __str__(self):
46
- return self.reason
47
-
48
-
49
- class ModelNotReady(RuntimeError):
50
- def __init__(self, model_name: str, detail: Optional[str] = None):
51
- self.model_name = model_name
52
- self.error_msg = f"Model with name {self.model_name} is not ready."
53
- if detail:
54
- self.error_msg = self.error_msg + " " + detail
55
-
56
- def __str__(self):
57
- return self.error_msg
58
-
59
-
60
- async def exception_handler(_, exc):
61
- return JSONResponse(
62
- status_code=HTTPStatus.INTERNAL_SERVER_ERROR, content={"error": str(exc)}
63
- )
64
-
65
-
66
- async def invalid_input_handler(_, exc):
67
- return JSONResponse(status_code=HTTPStatus.BAD_REQUEST, content={"error": str(exc)})
68
-
69
-
70
- async def inference_error_handler(_, exc):
71
- return JSONResponse(
72
- status_code=HTTPStatus.INTERNAL_SERVER_ERROR, content={"error": str(exc)}
73
- )
74
-
75
-
76
- async def generic_exception_handler(_, exc):
77
- return JSONResponse(
78
- status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
79
- content={"error": f"{type(exc).__name__} : {str(exc)}"},
80
- )
81
-
82
-
83
- async def model_not_found_handler(_, exc):
84
- return JSONResponse(status_code=HTTPStatus.NOT_FOUND, content={"error": str(exc)})
85
-
86
-
87
- async def model_not_ready_handler(_, exc):
88
- return JSONResponse(
89
- status_code=HTTPStatus.SERVICE_UNAVAILABLE, content={"error": str(exc)}
90
- )
91
-
92
-
93
- async def not_implemented_error_handler(_, exc):
94
- return JSONResponse(
95
- status_code=HTTPStatus.NOT_IMPLEMENTED, content={"error": str(exc)}
96
- )
97
-
98
-
99
- async def http_exception_handler(_, exc):
100
- return JSONResponse(status_code=exc.status_code, content={"error": exc.detail})
@@ -1,64 +0,0 @@
1
- import asyncio
2
- import signal
3
- from typing import Callable
4
-
5
- from fastapi import Request
6
-
7
- # This is to allow the last request's response to finish handling. There may be more
8
- # middlewares that the response goes through, and then there's the time for the bytes
9
- # to be pushed to the caller.
10
- DEFAULT_TERM_DELAY_SECS = 5.0
11
-
12
-
13
- class TerminationHandlerMiddleware:
14
- """
15
- This middleware allows for swiftly and safely terminating the server. It
16
- listens to a set of termination signals. On receiving such a signal, it
17
- first informs on the on_stop callback, then waits for currently executing
18
- requests to finish, before informing on the on_term callback.
19
-
20
- Stop means that the process to stop the server has started. As soon as
21
- outstading requests go to zero after this, on_term will be called.
22
-
23
- Term means that this is the right time to terminate the server process, no
24
- outstanding requests at this point.
25
-
26
- The caller would typically handle on_stop by stop sending more requests to
27
- the FastApi server. And on_term by exiting the server process.
28
- """
29
-
30
- def __init__(
31
- self,
32
- on_stop: Callable[[], None],
33
- on_term: Callable[[], None],
34
- termination_delay_secs: float = DEFAULT_TERM_DELAY_SECS,
35
- ):
36
- self._outstanding_request_count = 0
37
- self._on_stop = on_stop
38
- self._on_term = on_term
39
- self._termination_delay_secs = termination_delay_secs
40
- self._stopped = False
41
- for sig in [signal.SIGINT, signal.SIGTERM, signal.SIGQUIT]:
42
- signal.signal(sig, self._stop)
43
-
44
- async def __call__(self, request: Request, call_next):
45
- self._outstanding_request_count += 1
46
- try:
47
- response = await call_next(request)
48
- finally:
49
- self._outstanding_request_count -= 1
50
- if self._outstanding_request_count == 0 and self._stopped:
51
- # There's a delay in term to allow some time for current
52
- # response flow to finish.
53
- asyncio.create_task(self._term())
54
- return response
55
-
56
- def _stop(self, sig, frame):
57
- self._on_stop()
58
- self._stopped = True
59
- if self._outstanding_request_count == 0:
60
- self._on_term()
61
-
62
- async def _term(self):
63
- await asyncio.sleep(self._termination_delay_secs)
64
- self._on_term()