MeUtils 2024.3.4.13.4.45__py3-none-any.whl → 2025.1.16.17.15.52__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.
Files changed (582) hide show
  1. {MeUtils-2024.3.4.13.4.45.dist-info → MeUtils-2025.1.16.17.15.52.dist-info}/METADATA +38 -32
  2. MeUtils-2025.1.16.17.15.52.dist-info/RECORD +864 -0
  3. {MeUtils-2024.3.4.13.4.45.dist-info → MeUtils-2025.1.16.17.15.52.dist-info}/WHEEL +1 -1
  4. {MeUtils-2024.3.4.13.4.45.dist-info → MeUtils-2025.1.16.17.15.52.dist-info}/entry_points.txt +1 -0
  5. apps/spider.py +24 -8
  6. examples/_openaisdk/4v.py +110 -0
  7. examples/_openaisdk/__init__.py +11 -0
  8. examples/_openaisdk/baichuan.py +38 -0
  9. examples/_openaisdk/bpo.py +138 -0
  10. examples/_openaisdk/chat_latex.py +95 -0
  11. examples/_openaisdk/chattts.py +85 -0
  12. examples/_openaisdk/copilot.py +48 -0
  13. examples/_openaisdk/dalle3.py +48 -0
  14. examples/_openaisdk/deeplx.py +31 -0
  15. examples/_openaisdk/demo.py +77 -0
  16. examples/_openaisdk/embeddings.py +34 -0
  17. examples/_openaisdk/gpt4all.py +69 -0
  18. examples/_openaisdk/gpt_fc.py +23 -0
  19. examples/_openaisdk/gr_vl.py +46 -0
  20. examples/_openaisdk/json_mode.py +12 -0
  21. examples/_openaisdk/kimi.py +91 -0
  22. examples/_openaisdk/kimi_qa.py +57 -0
  23. examples/_openaisdk/minimax.py +75 -0
  24. examples/_openaisdk/open_router.py +48 -0
  25. examples/_openaisdk/openai_aiplus.py +54 -0
  26. examples/_openaisdk/openai_audio.py +20 -0
  27. examples/_openaisdk/openai_baichuan.py +59 -0
  28. examples/_openaisdk/openai_cache.py +37 -0
  29. examples/_openaisdk/openai_chatfire.py +228 -0
  30. examples/_openaisdk/openai_chatfire_all.py +166 -0
  31. examples/_openaisdk/openai_deepinfra.py +55 -0
  32. examples/_openaisdk/openai_deepseek.py +29 -0
  33. examples/_openaisdk/openai_doubao.py +43 -0
  34. examples/_openaisdk/openai_embeddings.py +36 -0
  35. examples/_openaisdk/openai_files.py +57 -0
  36. examples/_openaisdk/openai_gitee.py +33 -0
  37. examples/_openaisdk/openai_god.py +45 -0
  38. examples/_openaisdk/openai_groq.py +240 -0
  39. examples/_openaisdk/openai_images.py +203 -0
  40. examples/_openaisdk/openai_json.py +78 -0
  41. examples/_openaisdk/openai_lingyi.py +59 -0
  42. examples/_openaisdk/openai_modelscope.py +54 -0
  43. examples/_openaisdk/openai_moon.py +55 -0
  44. examples/_openaisdk/openai_oi.py +61 -0
  45. examples/_openaisdk/openai_ppu.py +47 -0
  46. examples/_openaisdk/openai_qwen.py +58 -0
  47. examples/_openaisdk/openai_search.py +42 -0
  48. examples/_openaisdk/openai_sensenova.py +81 -0
  49. examples/_openaisdk/openai_siliconflow.py +52 -0
  50. examples/_openaisdk/openai_step.py +45 -0
  51. examples/_openaisdk/openai_test.py +66 -0
  52. examples/_openaisdk/openai_together.py +57 -0
  53. examples/_openaisdk/openai_tune.py +38 -0
  54. examples/_openaisdk/openai_zhipu.py +59 -0
  55. examples/_openaisdk/ppu.py +28 -0
  56. examples/_openaisdk/rag.py +54 -0
  57. examples/_openaisdk/rag_.py +26 -0
  58. examples/_openaisdk/test.py +52 -0
  59. examples/_openaisdk/x.py +32 -0
  60. examples/_openaisdk/xx.py +29 -0
  61. examples/_openaisdk/zhipu_files.py +47 -0
  62. examples/_openaisdk/zhipu_/346/231/272/350/203/275/344/275/223.py +45 -0
  63. examples/_openaisdk//345/205/234/345/272/225/346/265/213/350/257/225.py +50 -0
  64. examples/_openaisdk//345/244/232/346/250/241/346/200/201/346/265/213/350/257/225.py +76 -0
  65. examples/_openaisdk//345/244/232/346/250/241/346/200/201/346/265/213/350/257/225_.py +56 -0
  66. examples/_openaisdk//346/226/207/344/273/266/351/227/256/347/255/224.py +36 -0
  67. examples/_openaisdk//346/226/207/346/241/243/350/247/243/346/236/220.py +34 -0
  68. examples/_openaisdk//346/250/241/345/236/213/346/265/213/350/257/225.py +53 -0
  69. examples/_openaisdk//351/230/277/351/207/214.py +80 -0
  70. {meutils/serving/jina/__demo → examples/ann}/__init__.py +1 -1
  71. examples/ann/main.py +31 -0
  72. examples/apis/kl.py +28 -0
  73. examples/apis/x.py +17 -0
  74. examples/apis/xx.py +17 -0
  75. examples/arq_demo/demo.py +3 -0
  76. examples/backgroundtasks.py +25 -0
  77. examples/bserver.py +513 -21
  78. examples/cache_demo/HermesCache_demo.py +81 -0
  79. examples/cache_demo/acacge.py +26 -0
  80. examples/cache_demo/x.py +31 -0
  81. {meutils/docarray_utils → examples/caches}/__init__.py +1 -1
  82. examples/caches/llmcache.py +18 -0
  83. examples/celery_demo/product_task.py +2 -0
  84. examples/demo.py +17 -1
  85. examples/fastapi_caching.py +59 -0
  86. {meutils/dependencies → examples/gr}/__init__.py +1 -1
  87. examples/gr/d.py +22 -0
  88. examples/gr/demo.py +30 -0
  89. examples/ip2/345/234/260/345/214/272.py +16 -0
  90. examples/jinja2_demo/j2_demo.py +20 -1
  91. examples/json/346/240/207/345/207/206/345/214/226.py +54 -0
  92. examples/md.py +29 -0
  93. {meutils/serving/jina → examples/nesc}/__init__.py +1 -1
  94. examples/nesc/main.py +76 -0
  95. examples/orm/mysql_orm.py +113 -0
  96. examples/orm/sql_creater.py +57 -0
  97. examples/orm/sqlm.py +134 -0
  98. examples/rq_demo/fns.py +18 -0
  99. examples/rq_demo/redis/351/230/237/345/210/227.py +14 -7
  100. examples/rq_demo/redis/351/230/237/345/210/227_add_chatfire.py +30 -0
  101. examples/size_map.py +43 -0
  102. examples/test.py +59 -0
  103. examples/webs/__init__.py +11 -0
  104. examples/webs/main.py +34 -0
  105. examples/x.py +13 -0
  106. examples//345/216/273/346/260/264/345/215/260.py +20 -0
  107. examples//346/226/207/346/241/243/346/231/272/350/203/275/__init__.py +11 -0
  108. meutils/_utils.py +15 -6
  109. meutils/ai_audio/asr/__init__.py +3 -2
  110. meutils/ai_audio/asr/cf_asr.py +53 -0
  111. meutils/ai_audio/asr/de.py +11 -0
  112. meutils/ai_audio/asr/fast_asr.py +15 -7
  113. meutils/ai_audio/asr/openai_asr.py +83 -6
  114. meutils/ai_audio/fast_asr.py +8 -4
  115. meutils/ai_audio/tts/EdgeTTS.py +33 -7
  116. meutils/ai_audio/tts/openai_tts.py +24 -20
  117. meutils/ai_audio/tts/tts_ui.py +1 -0
  118. meutils/ai_audio/utils.py +9 -0
  119. meutils/ai_cv/__init__.py +0 -1
  120. meutils/ai_cv/ocr.py +3 -2
  121. meutils/ai_cv/utils.py +154 -0
  122. meutils/ai_video/avmerge.py +6 -0
  123. meutils/ai_video/video.py +11 -2
  124. meutils/{api → apis}/__init__.py +1 -1
  125. meutils/apis/ali_apis.py +60 -0
  126. meutils/apis/audio/__init__.py +10 -0
  127. meutils/apis/audio/deepinfra.py +59 -0
  128. meutils/apis/audio/fish.py +248 -0
  129. meutils/apis/baidu/__init__.py +9 -0
  130. meutils/apis/baidu/bdaitpzs.py +229 -0
  131. meutils/apis/baidu/test.py +78 -0
  132. meutils/apis/chatglm/__init__.py +11 -0
  133. meutils/apis/chatglm/glm_video.py +273 -0
  134. meutils/apis/chatglm/glm_video_api.py +116 -0
  135. meutils/apis/chatglm/images.py +63 -0
  136. meutils/apis/chatglm/temp.py +259 -0
  137. meutils/apis/chatglm/x.py +31 -0
  138. meutils/{api → apis}/common.py +10 -6
  139. meutils/apis/fal/__init__.py +11 -0
  140. meutils/apis/fal/files.py +53 -0
  141. meutils/apis/fal/images.py +57 -0
  142. meutils/apis/fal/images_.py +72 -0
  143. meutils/apis/fal/videos.py +77 -0
  144. meutils/apis/firecrawl.py +45 -0
  145. meutils/apis/gitee/__init__.py +11 -0
  146. meutils/apis/gitee/images/__init__.py +9 -0
  147. meutils/apis/gitee/images/kolors.py +99 -0
  148. meutils/apis/hailuoai/__init__.py +11 -0
  149. meutils/apis/hailuoai/demo.py +34 -0
  150. meutils/apis/hailuoai/hasha_new.py +248 -0
  151. meutils/apis/hailuoai/music.py +11 -0
  152. meutils/apis/hailuoai/upload.py +116 -0
  153. meutils/apis/hailuoai/videos.py +460 -0
  154. meutils/apis/hailuoai/yy.py +242 -0
  155. meutils/apis/hf/__init__.py +11 -0
  156. meutils/apis/hf/got_ocr.py +64 -0
  157. meutils/apis/hf/gradio.py +34 -0
  158. meutils/apis/hf/hivisionidphotos.py +80 -0
  159. meutils/apis/hf/kolors.py +68 -0
  160. meutils/apis/hf/kolors_virtual_try_on.py +107 -0
  161. meutils/apis/hf/r.py +53 -0
  162. meutils/apis/hf/x.py +26 -0
  163. meutils/apis/hf//350/257/201/344/273/266/347/205/247.py +41 -0
  164. meutils/apis/hunyuan/__init__.py +11 -0
  165. meutils/apis/hunyuan/image_tools.py +84 -0
  166. meutils/apis/images/__init__.py +11 -0
  167. meutils/apis/images/deepinfra.py +92 -0
  168. meutils/apis/images/demo.py +150 -0
  169. meutils/apis/images/eidt.py +36 -0
  170. meutils/apis/images/flux/__init__.py +11 -0
  171. meutils/apis/images/flux/fluxpro.py +108 -0
  172. meutils/apis/images/flux/mystic.py +116 -0
  173. meutils/apis/images/ideogram/__init__.py +10 -0
  174. meutils/apis/images/ideogram/ideogram_images.py +193 -0
  175. meutils/apis/images/prodia/__init__.py +12 -0
  176. meutils/apis/images/prodia/faceswap.py +76 -0
  177. meutils/apis/images/recraft.py +152 -0
  178. meutils/apis/images/virtual_try_on/__init__.py +11 -0
  179. meutils/apis/images/virtual_try_on/images.py +65 -0
  180. meutils/apis/jiema/24mail.py +96 -0
  181. meutils/apis/jiema/__init__.py +11 -0
  182. meutils/apis/jiema/yezi.py +97 -0
  183. meutils/apis/jimeng/__init__.py +11 -0
  184. meutils/apis/jimeng/common.py +328 -0
  185. meutils/apis/jimeng/doubao.py +68 -0
  186. meutils/apis/jimeng/doubao_utils.py +175 -0
  187. meutils/apis/jimeng/files.py +263 -0
  188. meutils/apis/jimeng/images.py +140 -0
  189. meutils/apis/jimeng/lip_sync.py +11 -0
  190. meutils/apis/jina.py +55 -0
  191. meutils/apis/kling/__init__.py +11 -0
  192. meutils/apis/kling/api.py +60 -0
  193. meutils/apis/kling/images.py +174 -0
  194. meutils/apis/kling/kolors_virtual_try_on.py +111 -0
  195. meutils/apis/kling/kolors_virtual_try_on_web.py +126 -0
  196. meutils/apis/kling/videos.py +67 -0
  197. meutils/apis/kling//351/211/264/346/235/203.py +34 -0
  198. meutils/apis/kuaidi.py +32 -0
  199. meutils/apis/kuaishou/__init__.py +10 -0
  200. meutils/apis/kuaishou/klingai.py +523 -0
  201. meutils/apis/kuaishou/klingai_video.py +197 -0
  202. meutils/apis/kuaishou/kolors.py +189 -0
  203. meutils/apis/llm_qa.py +55 -0
  204. meutils/apis/luma/__init__.py +11 -0
  205. meutils/apis/luma/luma.py +123 -0
  206. meutils/apis/minicpm/__init__.py +9 -0
  207. meutils/apis/minicpm/luca.py +137 -0
  208. meutils/apis/monica/__init__.py +11 -0
  209. meutils/apis/monica/llm.py +11 -0
  210. meutils/apis/napkin/__init__.py +11 -0
  211. meutils/apis/napkin/icons.py +42 -0
  212. meutils/apis/niutrans.py +73 -0
  213. meutils/apis/oneapi/__init__.py +11 -0
  214. meutils/apis/oneapi/channel.py +68 -0
  215. meutils/apis/oneapi/common.py +135 -0
  216. meutils/apis/oneapi/log.py +47 -0
  217. meutils/apis/oneapi/token.py +48 -0
  218. meutils/apis/oneapi/token_.py +112 -0
  219. meutils/apis/oneapi/user.py +100 -0
  220. meutils/apis/oneapi/utils.py +47 -0
  221. meutils/apis/pixverse/__init__.py +11 -0
  222. meutils/apis/pixverse/pixverse.py +150 -0
  223. meutils/apis/proxy/__init__.py +11 -0
  224. meutils/apis/proxy/ips.py +178 -0
  225. meutils/apis/remini/__init__.py +11 -0
  226. meutils/apis/remini/remini.py +89 -0
  227. meutils/apis/replicateai/__init__.py +11 -0
  228. meutils/apis/replicateai/images.py +79 -0
  229. meutils/apis/replicateai/raw.py +53 -0
  230. meutils/apis/runwayml/__init__.py +10 -0
  231. meutils/apis/runwayml/gen.py +143 -0
  232. meutils/apis/search/__init__.py +11 -0
  233. meutils/apis/search/baichuan.py +11 -0
  234. meutils/apis/search/metaso.py +218 -0
  235. meutils/apis/search/metaso_.py +77 -0
  236. meutils/apis/search/n.py +99 -0
  237. meutils/apis/search/searxng.py +42 -0
  238. meutils/apis/search_music.py +39 -0
  239. meutils/apis/siliconflow/__init__.py +9 -0
  240. meutils/apis/siliconflow/audio.py +63 -0
  241. meutils/apis/siliconflow/image_to_image.py +116 -0
  242. meutils/apis/siliconflow/images.py +154 -0
  243. meutils/apis/siliconflow/rerankers.py +40 -0
  244. meutils/apis/siliconflow/text_to_image.py +132 -0
  245. meutils/apis/siliconflow/utils.py +66 -0
  246. meutils/apis/siliconflow/videos.py +102 -0
  247. meutils/apis/sunoai/__init__.py +10 -0
  248. meutils/apis/sunoai/haimian.py +135 -0
  249. meutils/apis/sunoai/suno.py +373 -0
  250. meutils/apis/textcard/__init__.py +11 -0
  251. meutils/apis/textcard/demo.py +25 -0
  252. meutils/apis/textcard/hanyuxinjie.py +81 -0
  253. meutils/apis/textin.py +159 -0
  254. meutils/apis/to_image/__init__.py +11 -0
  255. meutils/apis/to_image/html2image.py +29 -0
  256. meutils/apis/to_image/md.py +29 -0
  257. meutils/apis/to_image/url2image.py +41 -0
  258. meutils/apis/together/__init__.py +11 -0
  259. meutils/apis/together/images.py +80 -0
  260. meutils/apis/translator/__init__.py +9 -0
  261. meutils/apis/translator/deeplx.py +55 -0
  262. meutils/apis/tripo3d/__init__.py +11 -0
  263. meutils/apis/tripo3d/images.py +106 -0
  264. meutils/apis/ts.py +60 -0
  265. meutils/apis/uptime_kuma/__init__.py +11 -0
  266. meutils/apis/uptime_kuma/common.py +56 -0
  267. meutils/apis/uptime_kuma//345/233/275/344/272/247/345/210/206/347/273/204.py +68 -0
  268. meutils/apis/utils.py +47 -0
  269. meutils/apis/videos/__init__.py +11 -0
  270. meutils/apis/videos/sora.py +16 -0
  271. meutils/apis/vidu/__init__.py +9 -0
  272. meutils/apis/vidu/vidu_video.py +254 -0
  273. meutils/apis/vidu/x.py +14 -0
  274. meutils/apis/voice_clone/__init__.py +10 -0
  275. meutils/apis/voice_clone/fish.py +236 -0
  276. meutils/apis/voice_clone/fish_api.py +16 -0
  277. meutils/apis/web_search.py +31 -0
  278. meutils/apis/yezi.py +97 -0
  279. meutils/async_task/__init__.py +13 -0
  280. meutils/async_task/celery_config.py +106 -0
  281. meutils/async_task/common.py +37 -0
  282. meutils/async_task/demo_create_tasks.py +73 -0
  283. meutils/async_task/tasks/__init__.py +11 -0
  284. meutils/async_task/tasks/_all.py +20 -0
  285. meutils/async_task/tasks/hailuo.py +24 -0
  286. meutils/async_task/tasks/kling.py +30 -0
  287. meutils/async_task/tasks/replicateai.py +24 -0
  288. meutils/async_task/tasks/test.py +124 -0
  289. meutils/async_task/tasks/vidu.py +28 -0
  290. meutils/async_task/utils.py +191 -0
  291. meutils/async_task//351/200/232/347/224/250/350/256/276/350/256/241.py +119 -0
  292. meutils/async_utils/asyncer_.py +37 -0
  293. meutils/async_utils/background.py +68 -0
  294. meutils/async_utils/common.py +136 -16
  295. meutils/async_utils/test.py +47 -0
  296. meutils/cache_utils.py +29 -23
  297. meutils/caches/__init__.py +9 -0
  298. meutils/caches/acache.py +45 -0
  299. meutils/caches/redis_cache.py +63 -0
  300. meutils/clis/check_api.py +66 -0
  301. meutils/clis/cli.py +1 -1
  302. meutils/common.py +56 -17
  303. meutils/config_utils/__init__.py +11 -0
  304. meutils/config_utils/lark_utils/__init__.py +11 -0
  305. meutils/config_utils/lark_utils/common.py +385 -0
  306. meutils/config_utils/lark_utils/demo.py +13 -0
  307. meutils/config_utils/lark_utils/x.py +50 -0
  308. meutils/config_utils/manager.py +108 -0
  309. meutils/crawlers/__init__.py +11 -0
  310. meutils/data/VERSION +1 -1
  311. meutils/data/cowboy-hat-face.webp +0 -0
  312. meutils/data/oneapi/FOOTER.md +7 -0
  313. meutils/data/oneapi/NOTICE.md +138 -0
  314. meutils/data/oneapi/__init__.py +15 -0
  315. meutils/db/orm.py +179 -0
  316. meutils/db/redis_db.py +87 -0
  317. meutils/decorators/cache.py +1 -1
  318. meutils/decorators/common.py +84 -5
  319. meutils/decorators/contextmanagers.py +17 -6
  320. meutils/decorators/fastapi_decorator.py +77 -3
  321. meutils/decorators/polling.py +46 -0
  322. meutils/decorators/retry.py +150 -26
  323. meutils/fastapi_utils/__init__.py +11 -0
  324. meutils/fastapi_utils/exceptions/http_error.py +72 -0
  325. meutils/fastapi_utils/exceptions/validation_error.py +44 -0
  326. meutils/hash_utils.py +9 -4
  327. meutils/hooks/__init__.py +11 -0
  328. meutils/hooks/hook_test.py +174 -0
  329. meutils/hooks/wechat.py +162 -0
  330. meutils/hooks/wechat_channel.py +303 -0
  331. meutils/init/evn.py +1 -1
  332. meutils/io/files_utils.py +232 -0
  333. meutils/io/image.py +148 -10
  334. meutils/io/x.py +75 -0
  335. meutils/llm/__init__.py +10 -0
  336. meutils/llm/check_api.py +109 -0
  337. meutils/llm/check_utils.py +106 -0
  338. meutils/llm/clients.py +38 -0
  339. meutils/llm/completions/__init__.py +11 -0
  340. meutils/llm/completions/agents/__init__.py +11 -0
  341. meutils/llm/completions/agents/file.py +125 -0
  342. meutils/llm/completions/cp.py +112 -0
  343. meutils/llm/completions/delilegal.py +135 -0
  344. meutils/llm/completions/dify.py +81 -0
  345. meutils/llm/completions/kimi.py +47 -0
  346. meutils/llm/completions/modelscope.py +11 -0
  347. meutils/{fileparser/filetype.py → llm/completions/oi.py} +5 -3
  348. meutils/llm/completions/rag/__init__.py +11 -0
  349. meutils/llm/completions/rag/fire.py +157 -0
  350. meutils/llm/completions/rag/qwen.py +11 -0
  351. meutils/llm/completions/rag/rag.py +41 -0
  352. meutils/llm/completions/rag.py +38 -0
  353. meutils/llm/completions/tryblend.py +201 -0
  354. meutils/llm/completions/tune.py +284 -0
  355. meutils/llm/completions/x.py +26 -0
  356. meutils/llm/completions/xx.py +61 -0
  357. meutils/llm/completions/yuanbao.py +176 -0
  358. meutils/llm/demo.py +114 -0
  359. meutils/llm/functions/__init__.py +11 -0
  360. meutils/llm/mappers.py +15 -0
  361. meutils/llm/openai_utils/__init__.py +11 -0
  362. meutils/llm/openai_utils/common.py +284 -0
  363. meutils/llm/openai_utils/tool_outputs.py +45 -0
  364. meutils/llm/output_parsers/__init__.py +80 -0
  365. meutils/llm/prompts/__init__.py +244 -0
  366. meutils/llm/prompts/demo.py +155 -0
  367. meutils/llm/prompts/html2image_test.py +19 -0
  368. meutils/llm/utils.py +133 -0
  369. meutils/llm/x.py +75 -0
  370. meutils/notice/feishu.py +40 -9
  371. meutils/notice/wechat.py +23 -21
  372. meutils/np_utils.py +10 -1
  373. meutils/office_automation/pdf.py +6 -1
  374. meutils/oss/__init__.py +20 -0
  375. meutils/oss/minio_oss.py +184 -0
  376. meutils/oss/minio_utils.py +48 -0
  377. meutils/other/__demo.py +6 -4
  378. meutils/pandas_utils/__init__.py +1 -0
  379. meutils/pandas_utils/common.py +31 -0
  380. meutils/pandas_utils/pd_utils.py +10 -6
  381. meutils/parsers/__init__.py +10 -0
  382. meutils/parsers/file_parsers.py +110 -0
  383. meutils/parsers/fileparser/demo.py +41 -0
  384. meutils/parsers/fileparser/filetype.py +41 -0
  385. meutils/pay.py +37 -0
  386. meutils/pipe.py +37 -4
  387. meutils/playwright_utils/common.py +20 -12
  388. meutils/plots/common.py +35 -34
  389. meutils/queues/demo.py +56 -0
  390. meutils/queues/smooth_queue.py +120 -0
  391. meutils/queues/uniform_queue.py +3 -1
  392. meutils/request_utils/__init__.py +26 -2
  393. meutils/request_utils/ark.py +47 -0
  394. meutils/request_utils/crawler.py +34 -5
  395. meutils/request_utils/jwt_utils/__init__.py +11 -0
  396. meutils/request_utils/jwt_utils/common.py +42 -0
  397. meutils/request_utils/volc.py +160 -0
  398. meutils/schemas/__init__.py +0 -1
  399. meutils/schemas/baidu_types.py +70 -0
  400. meutils/schemas/batch_types.py +450 -0
  401. meutils/schemas/celery_types.py +64 -0
  402. meutils/schemas/chatfire_types.py +15 -0
  403. meutils/schemas/chatglm_types.py +197 -0
  404. meutils/schemas/db/__init__.py +11 -0
  405. meutils/schemas/db/oneapi_types.py +117 -0
  406. meutils/schemas/dify_types.py +40 -0
  407. meutils/schemas/embedding.py +31 -0
  408. meutils/schemas/fal_types.py +13 -0
  409. meutils/schemas/fish_types.py +11 -0
  410. meutils/schemas/hailuo_types.py +208 -0
  411. meutils/schemas/haimian_types.py +51 -0
  412. meutils/schemas/idphoto_types.py +43 -0
  413. meutils/schemas/image_types.py +476 -0
  414. meutils/schemas/jimeng_types.py +28 -0
  415. meutils/schemas/jina_types.py +67 -0
  416. meutils/schemas/kimi_types.py +86 -0
  417. meutils/schemas/kling_types.py +235 -0
  418. meutils/schemas/kuaishou_types.py +328 -0
  419. meutils/schemas/luma_types.py +59 -0
  420. meutils/schemas/message_types.py +165 -0
  421. meutils/schemas/message_types_.py +219 -0
  422. meutils/schemas/metaso_types.py +64 -0
  423. meutils/schemas/napkin_types.py +85 -0
  424. meutils/schemas/ocr_types.py +37 -0
  425. meutils/schemas/oneapi/__init__.py +11 -0
  426. meutils/schemas/oneapi/_types.py +49 -0
  427. meutils/schemas/oneapi/common.py +883 -0
  428. meutils/schemas/oneapi/icons.py +30 -0
  429. meutils/schemas/oneapi/model_group_info.py +48 -0
  430. meutils/schemas/oneapi/model_info.py +34 -0
  431. meutils/schemas/oneapi/models.py +26 -0
  432. meutils/schemas/oneapi/x.py +26 -0
  433. meutils/schemas/oneapi//351/207/215/345/256/232/345/220/221.py +132 -0
  434. meutils/schemas/openai_api_protocol.py +411 -0
  435. meutils/schemas/openai_types.py +366 -0
  436. meutils/schemas/pixverse_types.py +88 -0
  437. meutils/schemas/playwright_types.py +57 -0
  438. meutils/schemas/prodia_types.py +19 -0
  439. meutils/schemas/replicate_types.py +112 -0
  440. meutils/schemas/request_types.py +20 -0
  441. meutils/schemas/runwayml_types.py +190 -0
  442. meutils/schemas/siliconflow_types.py +80 -0
  443. meutils/schemas/step_types.py +19 -0
  444. meutils/schemas/suno_types.py +319 -0
  445. meutils/schemas/task_types.py +192 -0
  446. meutils/schemas/translator_types.py +29 -0
  447. meutils/schemas/tripo3d_types.py +57 -0
  448. meutils/schemas/tryblend_types.py +51 -0
  449. meutils/schemas/video_types.py +62 -0
  450. meutils/schemas/vidu_types.py +350 -0
  451. meutils/schemas/wechat_types.py +316 -0
  452. meutils/schemas/yuanbao_types.py +260 -0
  453. meutils/serving/celery/__init__.py +8 -0
  454. meutils/serving/celery/config.py +115 -0
  455. meutils/serving/celery/router.py +4 -6
  456. meutils/serving/celery/tasks.py +6 -4
  457. meutils/serving/celery//351/200/232/347/224/250/350/256/276/350/256/241.py +119 -0
  458. meutils/serving/fastapi/common.py +27 -31
  459. meutils/serving/fastapi/dependencies/__init__.py +0 -1
  460. meutils/serving/fastapi/dependencies/auth.py +55 -2
  461. meutils/serving/fastapi/exceptions/http_error.py +67 -2
  462. meutils/serving/fastapi/exceptions/validation_error.py +18 -2
  463. meutils/serving/fastapi/lifespans.py +73 -0
  464. meutils/serving/fastapi/routers/scheduler.py +12 -0
  465. meutils/serving/fastapi/routers/screenshot.py +47 -0
  466. meutils/serving/fastapi/routers/spider.py +8 -3
  467. meutils/serving/fastapi/routers/task.py +48 -0
  468. meutils/serving/fastapi/utils.py +48 -1
  469. meutils/serving/streamlit/common.py +1 -1
  470. meutils/smooth_utils.py +3 -0
  471. meutils/str_utils/__init__.py +22 -3
  472. meutils/str_utils/json_utils.py +7 -0
  473. meutils/str_utils/regular_expression.py +102 -10
  474. meutils/templates/xx.html +21 -0
  475. meutils/templates/xxx.html +117 -0
  476. meutils/todo.py +12 -0
  477. meutils/tools/token_monitor.py +33 -0
  478. MeUtils-2024.3.4.13.4.45.dist-info/RECORD +0 -540
  479. meutils/ai_audio/asr/subtitle.srt +0 -40
  480. meutils/ai_audio/demo.ipynb +0 -1215
  481. meutils/ai_audio/example.srt +0 -348
  482. meutils/ai_audio/new.srt +0 -179
  483. meutils/ai_audio/subtitles.srt +0 -696
  484. meutils/ai_audio/tts/new.srt +0 -179
  485. meutils/ai_audio//350/247/206/351/242/221/345/220/210/345/271/266.sh +0 -32
  486. meutils/ai_cv/1.jpg +0 -0
  487. meutils/ai_cv/197.jpg +0 -0
  488. meutils/ai_cv/2.jpg +0 -0
  489. meutils/ai_cv/img.png +0 -0
  490. meutils/ai_cv/invoice.jpg +0 -0
  491. meutils/ai_cv/tbl.png +0 -0
  492. meutils/ai_cv/test.png +0 -0
  493. meutils/ann/README.md +0 -33
  494. meutils/ann/README_gensim.md +0 -47
  495. meutils/ann/examples/client.py +0 -59
  496. meutils/ann/examples/demo.py +0 -24
  497. meutils/api/deeplx.py +0 -29
  498. meutils/api/qr.png +0 -0
  499. meutils/clis/README.md +0 -29
  500. meutils/clis/__test.sh +0 -17
  501. meutils/clis/deepseek.txt +0 -8
  502. meutils/clis/deepseek_13003330042.json +0 -1
  503. meutils/clis/deepseek_13003872192.json +0 -1
  504. meutils/clis/deepseek_13852263862.json +0 -1
  505. meutils/clis/deepseek_13913898681.json +0 -1
  506. meutils/clis/deepseek_13962978617.json +0 -1
  507. meutils/clis/deepseek_15251801790.json +0 -1
  508. meutils/clis/deepseek_15720826383.json +0 -1
  509. meutils/clis/deepseek_18395563611.json +0 -1
  510. meutils/clis/deepseek_313303303@qq.com.json +0 -1
  511. meutils/clis/kimi_state.json +0 -1
  512. meutils/cmds/README.md +0 -55
  513. meutils/coding/__init__.py +0 -11
  514. meutils/coding/find132.py +0 -40
  515. meutils/db/README.md +0 -51
  516. meutils/decorators/README.md +0 -17
  517. meutils/docarray_utils/demo_es.py +0 -34
  518. meutils/docarray_utils/demo_hnsw.py +0 -55
  519. meutils/docarray_utils/in_memory.py +0 -38
  520. meutils/docarray_utils//346/224/271/351/200/240/344/270/213hnsw.py +0 -43
  521. meutils/io/file.py +0 -20
  522. meutils/io/img.png +0 -0
  523. meutils/io/x.yml +0 -1
  524. meutils/notice/img.png +0 -0
  525. meutils/notice/todo.md +0 -10
  526. meutils/office_automation//346/212/225/350/265/204/347/256/241/347/220/206/347/263/273/347/273/237O3.2_/344/272/244/346/230/223/347/273/204.pdm +0 -22469
  527. meutils/playwright_utils/__test.sh +0 -2
  528. meutils/playwright_utils/kimi1_cookies.json +0 -1
  529. meutils/playwright_utils/kimi2_cookies.json +0 -1
  530. meutils/playwright_utils/kimi_cookies.json +0 -93
  531. meutils/serving/README.md +0 -1
  532. meutils/serving/celery/_run.sh +0 -10
  533. meutils/serving/gui/run.sh +0 -9
  534. meutils/serving/jina/__demo/client.py +0 -42
  535. meutils/serving/jina/__demo/flow.svg +0 -1
  536. meutils/serving/jina/__demo/s.py +0 -34
  537. meutils/serving/jina/__demo/s2.py +0 -37
  538. meutils/serving/jina/__demo/server.py +0 -83
  539. meutils/serving/jina/__demo/test.py +0 -40
  540. meutils/serving/jina/executors/SentenceEncoder.py +0 -62
  541. meutils/serving/jina/executors/SentenceEncoder_.py +0 -63
  542. meutils/serving/jina/executors/__init__.py +0 -46
  543. meutils/serving/jina/executors/base.py +0 -40
  544. meutils/serving/jina/nlp_serving/__init__.py +0 -11
  545. meutils/serving/jina/nlp_serving/word_segmentation.py +0 -40
  546. meutils/serving/streamlit/conf.yaml +0 -5
  547. meutils/serving/streamlit/ocr.png +0 -0
  548. meutils/serving/streamlit/run.sh +0 -17
  549. meutils/serving/webui/.streamlit/_config.toml +0 -186
  550. meutils/serving/webui/.streamlit/config.toml +0 -26
  551. meutils/serving/webui/pages/_1_/345/210/206/350/257/215.py +0 -56
  552. meutils/serving/webui/pages/_2_/350/257/215/346/200/247/346/240/207/346/263/250/344/270/216/345/256/236/344/275/223/350/257/206/345/210/253.py +0 -54
  553. meutils/serving/webui/pages/_3_/346/226/207/346/234/254/345/214/271/351/205/215.py +0 -64
  554. meutils/serving/webui/run.sh +0 -9
  555. meutils/spark/__init__.py +0 -26
  556. meutils/tools/monitor.yml +0 -29
  557. {MeUtils-2024.3.4.13.4.45.dist-info → MeUtils-2025.1.16.17.15.52.dist-info}/LICENSE +0 -0
  558. {MeUtils-2024.3.4.13.4.45.dist-info → MeUtils-2025.1.16.17.15.52.dist-info}/top_level.txt +0 -0
  559. {meutils → examples}/comp_utils/__init__.py +0 -0
  560. {meutils → examples}/comp_utils/reverse_metric.py +0 -0
  561. /meutils/{fileparser/README.md → fastapi_utils/exceptions/__init__.py} +0 -0
  562. /meutils/{fileparser → parsers/fileparser}/PDF/346/212/275/345/217/226.py" +0 -0
  563. /meutils/{fileparser → parsers/fileparser}/__init__.py +0 -0
  564. /meutils/{fileparser → parsers/fileparser}/common.py +0 -0
  565. /meutils/{fileparser → parsers/fileparser}/filetype/__init__.py +0 -0
  566. /meutils/{fileparser → parsers/fileparser}/filetype/__main__.py +0 -0
  567. /meutils/{fileparser → parsers/fileparser}/filetype/filetype.py +0 -0
  568. /meutils/{fileparser → parsers/fileparser}/filetype/helpers.py +0 -0
  569. /meutils/{fileparser → parsers/fileparser}/filetype/match.py +0 -0
  570. /meutils/{fileparser → parsers/fileparser}/filetype/types/__init__.py +0 -0
  571. /meutils/{fileparser → parsers/fileparser}/filetype/types/application.py +0 -0
  572. /meutils/{fileparser → parsers/fileparser}/filetype/types/archive.py +0 -0
  573. /meutils/{fileparser → parsers/fileparser}/filetype/types/audio.py +0 -0
  574. /meutils/{fileparser → parsers/fileparser}/filetype/types/base.py +0 -0
  575. /meutils/{fileparser → parsers/fileparser}/filetype/types/document.py +0 -0
  576. /meutils/{fileparser → parsers/fileparser}/filetype/types/font.py +0 -0
  577. /meutils/{fileparser → parsers/fileparser}/filetype/types/image.py +0 -0
  578. /meutils/{fileparser → parsers/fileparser}/filetype/types/isobmff.py +0 -0
  579. /meutils/{fileparser → parsers/fileparser}/filetype/types/video.py +0 -0
  580. /meutils/{fileparser → parsers/fileparser}/filetype/utils.py +0 -0
  581. /meutils/{fileparser → parsers/fileparser}/pdf.py +0 -0
  582. /meutils/{fileparser → parsers/fileparser}//350/241/250/346/240/274/346/212/275/345/217/226.py" +0 -0
@@ -21,7 +21,7 @@ import wrapt
21
21
  from loguru import logger
22
22
  from tqdm.auto import tqdm
23
23
  from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
24
- from contextlib import contextmanager
24
+ from contextlib import contextmanager, asynccontextmanager
25
25
  from typing import *
26
26
  # ME
27
27
  from meutils.decorators.decorator import decorator
@@ -77,7 +77,7 @@ def return2log(func, sink=sys.stderr, logkwargs=None, *args, **kwargs):
77
77
 
78
78
 
79
79
  @contextmanager
80
- def timer(task="Task"):
80
+ def timer(task="Task", notice_fn: Optional[Callable] = None):
81
81
  """https://www.kaggle.com/lopuhin/mercari-golf-0-3875-cv-in-75-loc-1900-s
82
82
  # 其他装饰器可学习这种写法
83
83
  with timer() as t:
@@ -88,13 +88,50 @@ def timer(task="Task"):
88
88
  print('sleeping')
89
89
  time.sleep(6)
90
90
  return 6
91
+
92
+
93
+ from meutils.notice import feishu
94
+ feishu.send_message
91
95
  """
92
96
 
93
97
  logger.info(f"{task} started")
94
98
  s = time.perf_counter()
95
99
  yield
96
100
  e = time.perf_counter()
97
- logger.info(f"{task} done in {e - s:.3f} s")
101
+ msg = f"{task} done in {e - s:.3f} s"
102
+ logger.info(msg) # feishu
103
+
104
+ # notice
105
+ if notice_fn: notice_fn(msg)
106
+
107
+
108
+ @asynccontextmanager
109
+ async def async_timer(task="Task", notice_fn: Optional[Callable] = None):
110
+ """
111
+ Async context manager for timing tasks.
112
+
113
+ Usage:
114
+ ```python
115
+ async with async_timer() as t:
116
+ await asyncio.sleep(3)
117
+
118
+ @async_timer()
119
+ async def f():
120
+ print('sleeping')
121
+ await asyncio.sleep(6)
122
+ return 6
123
+ ```
124
+ """
125
+ logger.info(f"{task} started")
126
+ s = time.perf_counter()
127
+ yield
128
+ e = time.perf_counter()
129
+ msg = f"{task} done in {e - s:.3f} s"
130
+ logger.info(msg) # feishu
131
+
132
+ # notice
133
+ if notice_fn:
134
+ await notice_fn(msg)
98
135
 
99
136
 
100
137
  @contextmanager
@@ -170,6 +207,7 @@ def background_task(func, max_workers=1, *args, **kwargs):
170
207
  # pool.shutdown(wait=False) # 不等待
171
208
  # pool.shutdown(wait=True) # 等待
172
209
 
210
+ # with ThreadPoolExecutor(max_workers=max_workers, thread_name_prefix='🐶') as pool: # 失去异步效果
173
211
  pool = ThreadPoolExecutor(max_workers=max_workers, thread_name_prefix='🐶')
174
212
  future = pool.submit(func, *args, **kwargs) # pool.map(fun4, ips)
175
213
  future.add_done_callback(
@@ -177,6 +215,8 @@ def background_task(func, max_workers=1, *args, **kwargs):
177
215
  )
178
216
  # future.add_done_callback()
179
217
 
218
+ # pool.shutdown(wait=False) # 不等待
219
+
180
220
  return future.running() # future.done()
181
221
 
182
222
 
@@ -187,7 +227,7 @@ background = background_task
187
227
  def background_task_plus(func, *args, **kwargs):
188
228
  pool = ThreadPoolExecutor(max_workers=1, thread_name_prefix='🐶')
189
229
  future = pool.submit(func, *args, **kwargs) # pool.map(fun4, ips)
190
- future.add_done_callback(lambda x: logger.error(future.exception()) if future.exception() else None)
230
+ future.add_done_callback(lambda x: logger.error(f"{future.exception()}") if future.exception() else None)
191
231
  # 详细错误 traceback.format_exc()
192
232
  return future.running() # future.done()
193
233
 
@@ -283,6 +323,43 @@ def requires_dependencies(
283
323
  return decorator
284
324
 
285
325
 
326
+ def ratelimit(
327
+ name: str = "ratelimit",
328
+ weight: int = 1,
329
+ rates: Optional[List[Any]] = None,
330
+ ):
331
+ """ https://github.com/vutran1710/PyrateLimiter
332
+ :param name:
333
+ :param weight:
334
+ :param rates:
335
+ :return:
336
+ """
337
+ from pyrate_limiter import Duration, Rate, Limiter, BucketFullException
338
+
339
+ rates = rates or [
340
+ Rate(1, Duration.SECOND),
341
+ Rate(2, Duration.SECOND * 15),
342
+ Rate(2 ** 2, Duration.MINUTE),
343
+ Rate(2 ** 4, Duration.HOUR),
344
+ Rate(2 ** 8, Duration.DAY)
345
+ ]
346
+ limiter = Limiter(rates)
347
+
348
+ def name2weight(*args, **kwargs): # 动态限频 limiter.try_acquire(self, name: str, weight: int = 1)
349
+ return name, weight
350
+
351
+ limiter_decorator = limiter.as_decorator()(name2weight)
352
+
353
+ @wrapt.decorator
354
+ def wrapper(wrapped, instance, args, kwargs):
355
+ try:
356
+ return limiter_decorator(wrapped)(*args, **kwargs)
357
+ except BucketFullException as e:
358
+ return e.meta_info
359
+
360
+ return wrapper
361
+
362
+
286
363
  def ratelimiter(limit_value: str = '3/1', callback=None):
287
364
  from ratelimiter import RateLimiter
288
365
 
@@ -321,6 +398,8 @@ def limit(limit_value: str = '1/second', key_func: Callable[..., str] = None, er
321
398
  return inner
322
399
 
323
400
 
401
+
402
+
324
403
  if __name__ == '__main__':
325
404
  import time
326
405
 
@@ -398,7 +477,7 @@ if __name__ == '__main__':
398
477
  # pass
399
478
 
400
479
  def f():
401
- return 1/0
480
+ return 1 / 0
402
481
  # return 1
403
482
 
404
483
 
@@ -10,9 +10,7 @@
10
10
 
11
11
  from meutils.pipe import *
12
12
 
13
- from contextlib import contextmanager
14
-
15
- from urllib3 import HTTPResponse
13
+ from contextlib import contextmanager, asynccontextmanager
16
14
 
17
15
 
18
16
  @contextmanager
@@ -37,18 +35,31 @@ def timer(task="Task"):
37
35
 
38
36
 
39
37
  @contextmanager
40
- def error_catcher(task, is_trace=False):
38
+ def try_catcher(task="Task", fallback: Callable = None, is_trace: bool = False):
41
39
  try:
42
40
  yield
43
41
  except Exception as e:
44
42
  error = traceback.format_exc() if is_trace else e
45
43
  logger.error(f"{task}: {error}")
44
+ if fallback:
45
+ yield fallback()
46
46
 
47
47
 
48
- @contextmanager
49
- def try_catcher(task, is_trace=False):
48
+ @asynccontextmanager
49
+ async def atry_catcher(task="Task", fallback: Callable = None, is_trace: bool = False):
50
50
  try:
51
51
  yield
52
52
  except Exception as e:
53
53
  error = traceback.format_exc() if is_trace else e
54
54
  logger.error(f"{task}: {error}")
55
+ if fallback:
56
+ yield await fallback()
57
+
58
+
59
+ if __name__ == '__main__':
60
+ async def f():
61
+ return 1/0
62
+
63
+
64
+ with try_catcher("test"):
65
+ arun(f())
@@ -34,17 +34,91 @@ def catch_exceptions(func=None, *, exception_type=Exception, status_code=404):
34
34
  return async_wrapper if asyncio.iscoroutinefunction(func) else sync_wrapper
35
35
 
36
36
 
37
+ def catch_exceptions_(func):
38
+ @wraps(func)
39
+ async def wrapper(*args, **kwargs):
40
+ try:
41
+ return await func(*args, **kwargs)
42
+ except CustomException as e:
43
+ return JSONResponse(
44
+ status_code=418,
45
+ content={"message": f"An error occurred: {str(e)}"},
46
+ )
47
+ except Exception as e:
48
+ return JSONResponse(
49
+ status_code=500,
50
+ content={"message": "An unexpected error occurred."}
51
+ )
52
+
53
+ return wrapper
54
+
55
+
56
+ # 然后在你的路由中使用装饰器:
57
+ # @app.get("/items/{item_id}")
58
+ # @catch_exceptions
59
+ # async def read_item(item_id: int):
60
+ # # 你的业务逻辑
61
+ # pass
62
+
63
+
37
64
  if __name__ == '__main__':
38
65
  from meutils.serving.fastapi import App
66
+ from fastapi import Depends
39
67
 
40
68
  app = App()
41
69
 
42
70
 
71
+ async def catch_exceptions(exception_type=Exception, status_code=404):
72
+ try:
73
+ yield
74
+ except exception_type as e:
75
+ raise HTTPException(status_code=status_code, detail=f"Error: {e}")
76
+
77
+
78
+ from fastapi import FastAPI, HTTPException, Depends, Request
79
+ from starlette.responses import JSONResponse
80
+
81
+
82
+
83
+ async def catch_exceptions(request: Request, call_next):
84
+ try:
85
+ response = await call_next(request)
86
+ return response
87
+ except IOError as e:
88
+ return JSONResponse(status_code=500, content={"detail": f"IOError: {e}"})
89
+
90
+
91
+ @app.middleware("http")
92
+ async def catch_exceptions_middleware(request: Request, call_next):
93
+ return await catch_exceptions(request, call_next)
94
+
95
+
43
96
  @app.get("/test")
44
- @catch_exceptions(exception_type=IOError, status_code=500)
45
- def f(file_id: str):
46
- logger.debug(file_id)
97
+ def test_endpoint(file_id: str):
98
+ # Your endpoint logic here
47
99
  raise Exception("test")
100
+ # return {"file_id": file_id}
101
+
102
+
103
+
104
+ # @app.get("/test_plus")
105
+ # def test_endpoint(file_id: str, _=Depends(catch_exceptions(exception_type=IOError, status_code=500))):
106
+ # # Your endpoint logic here
107
+ # return {"file_id": file_id}
108
+
109
+
110
+ # @app.get("/test")
111
+ # @catch_exceptions(exception_type=IOError, status_code=500)
112
+ # def f(file_id: str):
113
+ # logger.debug(file_id)
114
+ # # raise Exception("test")
115
+ #
116
+ #
117
+ # @app.get("/{file_id}")
118
+ # @catch_exceptions(status_code=1)
119
+ # def f(file_id: str):
120
+ # logger.debug(file_id)
121
+ # raise Exception("test")
48
122
 
49
123
 
50
124
  app.run(port=9000)
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # @Project : AI. @by PyCharm
4
+ # @File : polling
5
+ # @Time : 2024/12/26 14:08
6
+ # @Author : betterme
7
+ # @WeChat : meutils
8
+ # @Software : PyCharm
9
+ # @Description :
10
+ import time
11
+
12
+ from meutils.pipe import *
13
+
14
+
15
+ def poll(n: int = 30, sleep_fn: Optional[Callable] = None):
16
+ if sleep_fn is None:
17
+ sleep_fn = lambda i: max(n / (i + 1), 1) # 预估大概 2~3 *n
18
+
19
+ def decorator(fn):
20
+ is_coroutine = inspect.iscoroutinefunction(fn)
21
+
22
+ @wraps(fn)
23
+ async def wrapper(*args, **kwargs):
24
+ for i in range(n):
25
+ await asyncio.sleep(sleep_fn(i))
26
+ # 根据函数类型选择调用方式
27
+ result = await fn(*args, **kwargs) if is_coroutine else fn(*args, **kwargs)
28
+ if result: # 跳出
29
+ return result
30
+ return None
31
+
32
+ return wrapper
33
+
34
+ return decorator
35
+
36
+
37
+ if __name__ == '__main__':
38
+ @poll(n=5)
39
+ async def check_something():
40
+ # 你的检查逻辑
41
+
42
+ logger.debug(time.ctime())
43
+ return {"status": "ok"}
44
+
45
+
46
+ arun(check_something())
@@ -9,29 +9,89 @@
9
9
  # @Description :
10
10
 
11
11
  from meutils.pipe import *
12
- from tenacity import retry, wait_fixed, stop_after_attempt, wait_exponential, before_sleep_log
13
- from tenacity import retry_if_result, retry_if_exception_type # 重试策略
12
+ from tenacity import retry, stop_after_attempt, before_sleep_log
13
+ from tenacity import wait_fixed, wait_exponential, wait_incrementing, wait_exponential_jitter # Wait strategy
14
+ from tenacity import retry_if_result, RetryCallState # 重试策略
15
+ from tenacity import retry_if_exception, retry_if_exception_type, retry_if_not_exception_type
14
16
 
17
+ # 不兼容异步
18
+ from meutils.notice.feishu import send_message
15
19
 
16
- @decorator
17
- def retrying(func, max_retries=2, min_seconds=1, max_seconds=32,
18
- retry_error_callback: Callable = logger.exception,
19
- predicate: Callable[[Any], bool] = lambda x: False,
20
- *args, **kwargs):
20
+
21
+ class IgnoredRetryException(Exception):
22
+ pass
23
+
24
+
25
+ def default_retry_error_callback(retry_state: RetryCallState, title: Optional[str] = None):
26
+ """return the result of the last call attempt"""
27
+ # logger.debug(f"最后一次重试仍然失败调用的函数: {retry_state.outcome}")
28
+ logger.debug(f"最后一次重试仍然失败调用的函数: {retry_state}")
29
+
30
+ send_message(f"""{retry_state}""", title)
31
+
32
+ # logger.debug(retry_state.outcome.result())
33
+
34
+ exc = retry_state.outcome.exception() # 最后抛出错误
35
+ if exc:
36
+ raise exc # 最后返回结果
37
+
38
+
39
+ def not_in_status_codes(exception):
40
+ """451不触发重试"""
41
+ # logger.debug(exception)
42
+
43
+ if isinstance(exception, httpx.HTTPStatusError):
44
+ # logger.debug(f"status_code: {exception.response.status_code}")
45
+
46
+ status_code = exception.response.status_code
47
+ return status_code not in {451}
48
+ return True
49
+
50
+
51
+ def retrying(
52
+ max_retries=2,
53
+ exp_base=2,
54
+ min: int = 0,
55
+ max: int = 100000,
56
+ retry_error_callback: Optional[Callable[[RetryCallState], Any]] = None,
57
+ predicate: Callable[[Any], bool] = lambda r: False,
58
+ title: Optional[str] = None,
59
+ ignored_exception_types: Optional[typing.Union[
60
+ typing.Type[BaseException],
61
+ typing.Tuple[typing.Type[BaseException], ...],
62
+ ]] = None, # 该错误类型不重试
63
+ ):
21
64
  import logging
22
65
 
23
66
  logger = logging.getLogger()
24
67
 
68
+ retry_error_callback = retry_error_callback or partial(default_retry_error_callback, title=title)
69
+
70
+ # 抛错或者返回结果判断为True重试 就重试
71
+ retry_reasons = (
72
+ (
73
+ retry_if_exception_type()
74
+ & retry_if_exception(not_in_status_codes)
75
+ )
76
+ | retry_if_result(predicate)
77
+ )
78
+ if ignored_exception_types:
79
+ retry_reasons = retry_reasons & retry_if_not_exception_type(ignored_exception_types)
80
+
25
81
  _retry_decorator = retry(
26
82
  reraise=True,
27
83
  stop=stop_after_attempt(max_retries),
28
- wait=wait_exponential(multiplier=1, min=min_seconds, max=max_seconds),
29
- retry=retry_if_exception_type() | retry_if_result(predicate), # 抛错或者返回结果判断为True重试 就重试
30
- before_sleep=before_sleep_log(logger, 30),
84
+ wait=wait_exponential(multiplier=1.0, exp_base=exp_base, min=min, max=max), # max=max_seconds
85
+ retry=retry_reasons,
86
+ # before_sleep=before_sleep_log(logger, 30),
31
87
  retry_error_callback=retry_error_callback,
32
88
  )
33
89
 
34
- return _retry_decorator(func)(*args, **kwargs)
90
+ @wrapt.decorator
91
+ def wrapper(wrapped, instance, args, kwargs):
92
+ return _retry_decorator(wrapped)(*args, **kwargs)
93
+
94
+ return wrapper
35
95
 
36
96
 
37
97
  def create_retry_decorator() -> Callable[[Any], Any]: # todo: Retrying
@@ -84,25 +144,89 @@ def wait_retry(n=3):
84
144
 
85
145
 
86
146
  if __name__ == '__main__':
87
- s = time.time() # 1616145296
88
- print(s)
89
- e1 = s + 10
90
- e2 = e1 + 10
147
+ # s = time.time() # 1616145296
148
+ # print(s)
149
+ # e1 = s + 10
150
+ # e2 = e1 + 10
151
+ #
152
+ #
153
+ # @wait_retry(5)
154
+ # def f(e):
155
+ # return time.time() > e # 变的
156
+ #
157
+ #
158
+ # def run(e):
159
+ # f(e)
160
+ # print(f"task {e}")
161
+ #
162
+ #
163
+ # # for e in [e2, e1]:
164
+ # # print(run(e))
165
+ # #
166
+ # # print("耗时", time.time() - s)
167
+ #
168
+ # [e1, e2, 1000000000000] | xProcessPoolExecutor(run, 2)
169
+
170
+ # class retry_state:
171
+ # attempt_number = 0
172
+ #
173
+ #
174
+ # for i in range(1, 10):
175
+ # retry_state.attempt_number = i
176
+ # # print(wait_incrementing(100, -10)(retry_state))
177
+ # print(wait_exponential(1, exp_base=2)(retry_state))
178
+
179
+ # @retrying(3)
180
+ # async def f():
181
+ # logger.debug("retry")
182
+ # pass
183
+ # # 1 / 0
184
+ # raise Exception('xx')
185
+
186
+ # try:
187
+ # f()
188
+ #
189
+ # except Exception as e:
190
+ # print(e)
191
+ # print(type(e))
91
192
 
193
+ # @retrying(3)
194
+ # def f():
195
+ # # async def f():
196
+ # logger.debug("retry")
197
+ # for i in range(10):
198
+ # yield ""
199
+ # if i == 8:
200
+ # raise Exception('xx')
92
201
 
93
- @wait_retry(5)
94
- def f(e):
95
- return time.time() > e # 变的
202
+ # arun(f())
96
203
 
204
+ # f()
97
205
 
98
- def run(e):
99
- f(e)
100
- print(f"task {e}")
206
+ # 示例使用
207
+ class CustomError1(Exception):
208
+ pass
101
209
 
102
210
 
103
- # for e in [e2, e1]:
104
- # print(run(e))
105
- #
106
- # print("耗时", time.time() - s)
211
+ class CustomError2(Exception):
212
+ pass
213
+
214
+
215
+ @retrying(
216
+ max_retries=3,
217
+ ignored_exception_types=(CustomError1, IgnoredRetryException)
218
+ )
219
+ def my_function():
220
+ logger.debug(1)
221
+ # 模拟抛出异常
222
+ raise IgnoredRetryException("This is a custom error")
223
+
224
+
225
+ def main():
226
+ try:
227
+ my_function()
228
+ except Exception as e:
229
+ print(f"Operation failed after all retries: {e}")
230
+
107
231
 
108
- [e1, e2, 1000000000000] | xProcessPoolExecutor(run, 2)
232
+ main()
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # @Project : AI. @by PyCharm
4
+ # @File : __init__.py
5
+ # @Time : 2024/6/7 16:58
6
+ # @Author : betterme
7
+ # @WeChat : meutils
8
+ # @Software : PyCharm
9
+ # @Description :
10
+
11
+ from meutils.pipe import *
@@ -0,0 +1,72 @@
1
+ import json
2
+ import traceback
3
+
4
+ from fastapi import status
5
+ from starlette.requests import Request
6
+ from starlette.responses import JSONResponse
7
+
8
+ from fastapi.exceptions import RequestValidationError, HTTPException
9
+
10
+ from meutils.notice.feishu import send_message
11
+
12
+ UNAUTHORIZED_HTTPException = HTTPException(
13
+ status_code=status.HTTP_401_UNAUTHORIZED,
14
+ detail={
15
+ "error": {
16
+ "message": "",
17
+ "type": "invalid_request_error",
18
+ "param": None,
19
+ "code": "invalid_api_key",
20
+ }
21
+ })
22
+
23
+
24
+ async def http_error_handler(_: Request, exc: HTTPException) -> JSONResponse:
25
+ # print(exc)
26
+ content = {
27
+ "error":
28
+ {
29
+ "message": f"{exc.detail}",
30
+ "type": "http-error",
31
+ }
32
+ }
33
+ return JSONResponse(
34
+ content=content,
35
+ status_code=exc.status_code
36
+ )
37
+
38
+
39
+ async def general_exception_handler(request: Request, exc: Exception):
40
+ return JSONResponse(
41
+ content={"message": str(exc)},
42
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
43
+ )
44
+
45
+
46
+ async def chatfire_api_exception_handler(request: Request, exc: Exception):
47
+ content = {
48
+ "error":
49
+ {
50
+ "message": f"{exc}",
51
+ "type": "cf-api-error",
52
+ },
53
+
54
+ # "code": status.HTTP_500_INTERNAL_SERVER_ERROR
55
+ }
56
+ content_detail = f"{traceback.format_exc()}"
57
+
58
+ send_message(
59
+ content_detail,
60
+ title="cf-api-error",
61
+ url="https://open.feishu.cn/open-apis/bot/v2/hook/79fc258f-46a9-419e-b131-1d79b3d0bcff"
62
+ )
63
+
64
+ # send_message
65
+ return JSONResponse(
66
+ content=content,
67
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
68
+ )
69
+
70
+
71
+ if __name__ == '__main__':
72
+ from meutils.notice.feishu import send_message
@@ -0,0 +1,44 @@
1
+ from typing import Union
2
+
3
+ from fastapi import status
4
+ from fastapi.exceptions import RequestValidationError
5
+ from fastapi.openapi.constants import REF_PREFIX
6
+ from fastapi.openapi.utils import validation_error_response_definition
7
+ from pydantic import ValidationError
8
+ from starlette.requests import Request
9
+ from starlette.responses import JSONResponse
10
+ from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY
11
+
12
+
13
+ async def http422_error_handler(
14
+ _: Request,
15
+ exc: Union[RequestValidationError, ValidationError],
16
+ ) -> JSONResponse:
17
+ return JSONResponse(
18
+ {"errors": exc.errors()},
19
+ status_code=HTTP_422_UNPROCESSABLE_ENTITY,
20
+ )
21
+
22
+
23
+ validation_error_response_definition["properties"] = {
24
+ "errors": {
25
+ "title": "Errors",
26
+ "type": "array",
27
+ "items": {"$ref": "{0}ValidationError".format(REF_PREFIX)},
28
+ },
29
+ }
30
+
31
+
32
+ async def validation_exception_handler(_: Request, exc: RequestValidationError) -> JSONResponse:
33
+ # print(exc)
34
+ content = {
35
+ "error":
36
+ {
37
+ "message": f"{exc}",
38
+ "type": "RequestValidationError",
39
+ }
40
+ }
41
+ return JSONResponse(
42
+ content=content,
43
+ status_code=status.HTTP_400_BAD_REQUEST
44
+ )