MeUtils 2025.6.24.16.15.48__py3-none-any.whl → 2025.6.25.20.25.36__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.
@@ -125,7 +125,7 @@ examples/_openaisdk/openai_kimi.py,sha256=Y0ohLt2GVBrUzR286mDTJL7kPdLWVKjw36XSBE
125
125
  examples/_openaisdk/openai_lingyi.py,sha256=wmwdKaHqKB9lwoHS47hsG-zYrUy2Y3c_0Zu7ANy5IXI,3046
126
126
  examples/_openaisdk/openai_local.py,sha256=w-MedYgmRiO5eoMfbTQsB5J8ILFPfla0m6vP7qbQAxY,1889
127
127
  examples/_openaisdk/openai_luchentech.py,sha256=Jy0JxpL1u3pXcmslViPvrbwSysVBV-Dz8wSKqv6QtxY,1960
128
- examples/_openaisdk/openai_modelscope.py,sha256=PCuhZi3G1_-7Dyad9a0BZQU-NKe-8EecveQ3EVJA-GE,3424
128
+ examples/_openaisdk/openai_modelscope.py,sha256=ujzfwn90TLMtYsL5y37WmShZZM_G0-aX7hr4843pH8M,3424
129
129
  examples/_openaisdk/openai_moderations.py,sha256=WoIyXDEn4dfVPwqFc54HSz0-7wLPu7pd4ZisZcyLOWM,1369
130
130
  examples/_openaisdk/openai_moon.py,sha256=7-gILGwZArZ1VHVb-jtIXEqWJMv65SaMmBSKJ90fx_w,1889
131
131
  examples/_openaisdk/openai_oi.py,sha256=8KJ62QgpAZdGWAoYN6AC9M9TrD8JQf7ZO_NAgXZywTo,1414
@@ -259,7 +259,7 @@ examples/wget/demo.py,sha256=b-wASDBKND8_TtdIorNXV45sMjbWnfsYCBVk6XXee3o,438
259
259
  examples/wget/progress_bar/__init__.py,sha256=mlmNLOEplBy1h_Me-UWbgidVNrkie5okV1A8HQ0Ihy8,271
260
260
  examples/文档智能/__init__.py,sha256=JKHlkF5vTvwFJnFLIT7raQxsvBoK12b8lvVz-c03Uec,271
261
261
  meutils/__init__.py,sha256=X_i77Bvnt4-c4XUwuzGZTvXP2doPtTBqQsHl9DE455E,348
262
- meutils/_utils.py,sha256=bnT4-8C_o4ctat-iWAMzaGX21ppjkr0WI-YSOaqf5HA,2107
262
+ meutils/_utils.py,sha256=bwFkgDC5J1AOC0XCUJboxJJulkdm4hs14HhwUN_rwR4,2225
263
263
  meutils/cache_utils.py,sha256=6vz3G8wZ5iOXH91J-dp7ciU_BuLDzjjQUi4Hl8rrzOY,8425
264
264
  meutils/common.py,sha256=B5LhebAm4SXPqYfL_K8ho7pC_9wz2n8X_jN2xVaS2Ds,16889
265
265
  meutils/date_utils.py,sha256=--rh58qfa2iagLjgA0eh1myyvaZ0hgxHiy-WCsrNsuk,2497
@@ -343,7 +343,7 @@ meutils/apis/niutrans.py,sha256=tWUyGH5SReLBQyVuB7kZvoFB35dsN6gXN-anbiHc_B4,2298
343
343
  meutils/apis/search_music.py,sha256=HBLtdterztrccnLAPZrWBlrYSx4WCRflCqz-V30fOA8,972
344
344
  meutils/apis/textin.py,sha256=3L23RqYiR7bl6rymQ2YugDO-K1ItPX2sd0wyCrLST90,4897
345
345
  meutils/apis/ts.py,sha256=Q13EOS9Q-Y2-KwOG_cFMVmGj9RUmDtxk5A3E27dxbN0,1511
346
- meutils/apis/utils.py,sha256=SHJAWdEV6_YNrZSCU-IgvnhDtBRJElgQ3oxcyd0mYYw,2041
346
+ meutils/apis/utils.py,sha256=4ksGw3wkyeZrR80qmxHby4SAjf4YG_T5JMbRK3Zwq58,2085
347
347
  meutils/apis/web_search.py,sha256=6gS3leIB2iyeLtqhB0IbpL_mKzDgArRTqnR7odTWT3E,1035
348
348
  meutils/apis/yezi.py,sha256=26vhnA3lC5049Rqx-CHO-wyGKbdZAfvjEOG90W38cr0,3675
349
349
  meutils/apis/aitools/__init__.py,sha256=USdDfW2JZyUVY8ko54Dwpl801O766bvO_3F1lM4b8Gc,271
@@ -359,7 +359,7 @@ meutils/apis/baidu/test.py,sha256=nb9ivelHIw84-d1V-MNGRpGoTpLFsNXPk-TTKpjwOfQ,20
359
359
  meutils/apis/chatglm/__init__.py,sha256=uFuc9qY-ZjGqbsfcdGZkcEkhjATojWpzk2WXTTujc70,271
360
360
  meutils/apis/chatglm/chat.py,sha256=VARWXh3A2PnoScBgvfgAJC2C8OfVy9vWs3Q-qKg6F8Q,4253
361
361
  meutils/apis/chatglm/glm_video.py,sha256=9LA9pyeIcDDHXGhJbZSJfjxrLeNC3SIuCKJwDIXRKR8,14015
362
- meutils/apis/chatglm/glm_video_api.py,sha256=Wa1uBHIOwPWoAz90RMDeo-nMOvQzdQast1ZMBDTKq4Y,3964
362
+ meutils/apis/chatglm/glm_video_api.py,sha256=IEm7QIWZ_uvh7nVcxNwhtOvURU0fQQzDcSgQNVwyKFo,3965
363
363
  meutils/apis/chatglm/images.py,sha256=k2EtOpksgAfJb2MD6kLOKKem713kamTIinRmgr8_3n0,1974
364
364
  meutils/apis/chatglm/temp.py,sha256=zYe6JGUHVfb77T_TdNsdmpTs2D9OyqDTUEkblDAIoYY,17811
365
365
  meutils/apis/chatglm/x.py,sha256=lI86Cd6SN4noCN5HM9gRugcVmjHDtxDTV4m-7Bj61N0,24312
@@ -471,15 +471,15 @@ meutils/apis/monica/llm.py,sha256=gYyBPOTvmoNFaa1KmW3OlSsRKeN7C97EyPUa264nJ08,26
471
471
  meutils/apis/napkin/__init__.py,sha256=EWwpRJEbN46d6Dk9PHAZvsYmqD_EOK0jjKQL1kYtcKs,271
472
472
  meutils/apis/napkin/icons.py,sha256=_L8EaSeQ6ChT5w7q3jnj_AcRhKvNiBg3-qUKo9JQ12o,2217
473
473
  meutils/apis/oneapi/__init__.py,sha256=wg_kqNkFqOkP70vnOHvAeKREps57Rqliu5yKC0gsgLk,284
474
- meutils/apis/oneapi/channel.py,sha256=ri682XvJUznZT2AeH7GTZOUI7wM2rt3mHNMXVr1s8Fs,13867
474
+ meutils/apis/oneapi/channel.py,sha256=TU7cNC-Z-0KvP0FlRdDAl96aIG4RRWUx9zW9K7rMHmo,13918
475
475
  meutils/apis/oneapi/common.py,sha256=AIs8ro-1qui3FG42msBY6dL_zt9QJ0jS63qtp-XTlY4,3617
476
476
  meutils/apis/oneapi/demo.py,sha256=i9iBK2OftTvOZdPcCo2nxu8zs0fSKIZbzD8DRKQNla8,1851
477
477
  meutils/apis/oneapi/log.py,sha256=gNFFXXcG2Xp5ttO7Q7qR6n6GQUheuU8SOCjJPXZudLY,1447
478
478
  meutils/apis/oneapi/system.py,sha256=WmsGEEAig1rbOPkNxu3yxY67fnoRAiHWYnFWQmvAqtU,911
479
- meutils/apis/oneapi/token.py,sha256=LaKwkHXNvF46wXEVtbSNwfi0ujuQo7oRyln39MOPKX0,1638
479
+ meutils/apis/oneapi/token.py,sha256=sTsKWZQ4V5uSvqNsUvWTjsJWgIHXrsnVPDhNuOqCqmQ,1637
480
480
  meutils/apis/oneapi/token_.py,sha256=3NPU1jbjiRbcXIkw8bANcnby3rXq4U2LjU_8W3PaE_4,2560
481
- meutils/apis/oneapi/user.py,sha256=hLebQrEuvBpyDnDkPXQsEPVGkhQrqqY1qzbhXitW8Zg,4034
482
- meutils/apis/oneapi/utils.py,sha256=kuXwRQee3lSgJH7ffGP3Is4BhaUVylKJviG8FVN0F-I,1660
481
+ meutils/apis/oneapi/user.py,sha256=wKg5jrzc4YnbKV2ywFJEc1i5lyYPQ8FZtcakm2irm2g,3961
482
+ meutils/apis/oneapi/utils.py,sha256=92Ikgf0ndz6vUx8UobJYH5eLmUGBNJ32PO49K02FrOk,1777
483
483
  meutils/apis/pixverse/__init__.py,sha256=WiboEUfJ_3Hs2WI3OymEspx8_ZSTgMglxTJd97Qk7qo,271
484
484
  meutils/apis/pixverse/pixverse.py,sha256=dvnyYVUXCEY_cLnmX9lvq9TesvplCMCuJmmP7ShchQk,5534
485
485
  meutils/apis/ppio/__init__.py,sha256=ZCz9kagqxmWkpvDqDS8pkjGYVPpuBonPLfkTF9GuBgI,271
@@ -598,7 +598,7 @@ meutils/config_utils/lark_utils/demo.py,sha256=3g0Fs7oLaeW75T60gYWMLgyNg1OnfOjfH
598
598
  meutils/config_utils/lark_utils/x.py,sha256=MlMQGhehP9xMEgetxVCX68XFaosfKoW1JA5cZ3JqN2w,1857
599
599
  meutils/crawlers/__init__.py,sha256=TBU4xA-IOsHV-0yIkW7YXxn_QT7TT8NncqxO7IykEfs,271
600
600
  meutils/data/SimHei.ttf,sha256=-XEnekS5yHP_URkT4XBI2w22ylV-KxudhkeIYFbrILA,10062565
601
- meutils/data/VERSION,sha256=CU1jsNwEEVPILiPzLdlLhK_pZ7dSlzifRAIRUAEBDJQ,19
601
+ meutils/data/VERSION,sha256=WqRg9XXVPEwoTZK7SSVGABEhZJz7lFaDM5_eQntTpDk,19
602
602
  meutils/data/_FLAG,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
603
603
  meutils/data/_SUCCESS,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
604
604
  meutils/data/__init__.py,sha256=Hfwkkxs4zHqKhxht0YrhS566a9P5axtmgNvM5wF8ceQ,243
@@ -612,7 +612,7 @@ meutils/db/__init__.py,sha256=HR99rqxoFTWXUHDhLVl33tzIn8M86gigHLmEzOKH1Ec,7637
612
612
  meutils/db/mongo.py,sha256=B-B_t939rxtnNGt0PxhivjIUwinmHPzLUpXsjUIaTkQ,2337
613
613
  meutils/db/neo4j.py,sha256=eYd3jP3COWlOFBaF20UXphW67-HwlZ1t0Q34Cp-j6o0,2168
614
614
  meutils/db/orm.py,sha256=NEOO6p6D98EARszGXKuc9iTFQburllQS_vlgjp15lls,5094
615
- meutils/db/redis_db.py,sha256=nQHVTOxE0Apoaj9mjjAYzTTd2QpU6Ry41kPxdJiPb2w,2990
615
+ meutils/db/redis_db.py,sha256=Q0EPQDRrYHZr0npXlcqBpN7wlKgQye3h1PpghScbo4c,3029
616
616
  meutils/decorators/__ai.py,sha256=QAz005-Wa-sp0YUUoelaR1pMbt6hPSBML5j0My6TbEI,1681
617
617
  meutils/decorators/__init__.py,sha256=hgpHo40pfFWYXEnrW74o8W7SIfCD0GHr3gnujBw1hIQ,3284
618
618
  meutils/decorators/cache.py,sha256=-sqhCuiSYZK1UtsRw7bBog19G65O9N27DVTAp_nlBk4,2972
@@ -724,9 +724,9 @@ meutils/llm/openai_polling/chat.py,sha256=PT7Xb621RIa7SSwdlOCq5OMgk7nSyN7cBaBW4q
724
724
  meutils/llm/openai_polling/images.py,sha256=qKMk3vCvamS_48ceC-_y2LPpP5XsD476FHG9MUu8kks,1042
725
725
  meutils/llm/openai_utils/__init__.py,sha256=MWyNhP2K49oaHGEZlInZc3XlwqlStFultP8k7HDPAwk,290
726
726
  meutils/llm/openai_utils/adapters.py,sha256=-6e-gpSYVPUouP9o8leAdOOCNuk-dtndUhzMOyvQpUM,3425
727
+ meutils/llm/openai_utils/bling_utils.py,sha256=AbobMExB4TfgtV6PyXmEwH8SxMpOlP8Gr3HRTs37M4E,5103
727
728
  meutils/llm/openai_utils/common.py,sha256=H24wag3LD2RqKV_sXD4OBa4VtmWh8JNUo5h5xvHVmAk,10557
728
729
  meutils/llm/openai_utils/tool_outputs.py,sha256=6mNkm4btgy0uzF98gdmcah1bYmoflXdLz2Sqm0KC_LQ,1224
729
- meutils/llm/openai_utils/usage_utils.py,sha256=GfwZ8PqXrIVXDyKSvyQ7-GewFW-VOdaUqjpGbY_N8l8,2787
730
730
  meutils/llm/output_parsers/__init__.py,sha256=EGKvgUD47ReyV5Z9RXDCrdDLgfKMHdoayzsXVmBuQxw,3474
731
731
  meutils/llm/prompts/__init__.py,sha256=VlEEViFoUSRS0EF1rHJXHh9Ik9FpvAiR1luKjHOsUc4,8580
732
732
  meutils/llm/prompts/demo.py,sha256=vQ6MeR-3ds2js3TzDbZid-YKbo_pH0ehn58B7kjJaMg,3665
@@ -833,7 +833,7 @@ meutils/schemas/fish_types.py,sha256=yC0ZFr3Ebh8F0OhtMsXYaIfNNvzOM2LT9YtKTaRoHGU
833
833
  meutils/schemas/hailuo_types.py,sha256=3nx2jgDmi2dpwEfJ6xRiZQ-9nhOOXQgTz1yyLz5d-ik,7722
834
834
  meutils/schemas/haimian_types.py,sha256=jGu484UviAeBgy5OIUyRY4uYCxXfv16zDPqiJQr9wNQ,1364
835
835
  meutils/schemas/idphoto_types.py,sha256=nuHbpppejRSkJCiQ7YKx0Gnke0ShKZhOvdg0e7tk9-0,1074
836
- meutils/schemas/image_types.py,sha256=0qQdx6GRrFTLrd59bpqYAaU7EJcJZKan6vKbBLetLy8,16541
836
+ meutils/schemas/image_types.py,sha256=xDKXSffaLawfkY60LRFQlpJ2f_s-AClspgMw3ENt6Bc,16404
837
837
  meutils/schemas/jimeng_types.py,sha256=z0mAICgNE0Yaq09_puzgMfHOP-QKWiZqqMlFbLVHtmY,1995
838
838
  meutils/schemas/jina_types.py,sha256=SLRRBCap2B1uXnHF7Sgnlz1Work8HvdIltjj4oVlGTk,8826
839
839
  meutils/schemas/kimi_types.py,sha256=PjCgHwCDNzKasn4X6rUzvOENqKYT3xj07cgp71IdsDA,3607
@@ -856,7 +856,7 @@ meutils/schemas/runwayml_types.py,sha256=q6g00kg1PYCDjpw-notgbcUGwRAlIa8kAmU52Zu
856
856
  meutils/schemas/siliconflow_types.py,sha256=KClkwA2huq8YKuUCYIJZ4RF94ALhy3BsOMF1FcqRO1A,9266
857
857
  meutils/schemas/step_types.py,sha256=nGTPXZ7RwOF2RTsPBQguLLcIaBxHs4bsZkYa_LalcJ0,648
858
858
  meutils/schemas/suno_types.py,sha256=CxEXHGnLGZ7xvmoIYpz7IYPL73aLjtpHezJRIjWryKs,14965
859
- meutils/schemas/task_types.py,sha256=Zjbn6AiopkPA3px2ZiMouU9QrL43p9O8bJB5OTI-O_4,4638
859
+ meutils/schemas/task_types.py,sha256=8fCGpBNa1UOAsxYDG3a8P1MMv9tvWiyOn3kt7D34cZw,6371
860
860
  meutils/schemas/textin_types.py,sha256=-h9sRDYFUPtcANT5R-KeK-PalIENDMEckpttXgkt-fA,2306
861
861
  meutils/schemas/translator_types.py,sha256=xufNQeyim7RhkzAK_J5_JchZfqaUBDXFwMtrPUu1xzI,627
862
862
  meutils/schemas/tripo3d_types.py,sha256=mQF65HwHYmczRgAIuXK5hGxWDWNYDq-Xu9pja7Dwy4o,1452
@@ -894,7 +894,7 @@ meutils/serving/fastapi/utils.py,sha256=H5lQSU7-IfJ2w9FWbaJ34LCbQSaNTFSU7z1pG5wZ
894
894
  meutils/serving/fastapi/__demo/__init__.py,sha256=TxXjqy2ZxAkadPxqN92Xq3ixCUYkQ-4X6UxsReRpHhc,271
895
895
  meutils/serving/fastapi/__demo/异步任务.py,sha256=60_ruA4ljlTLIP5zxcejmm9WJ0SDuqpsO49SZK9vA_s,1444
896
896
  meutils/serving/fastapi/dependencies/__init__.py,sha256=TQcxvWqZdA2jZZX84NtAij-bhS7ihcMLx1-xsbSpV4g,384
897
- meutils/serving/fastapi/dependencies/auth.py,sha256=o6U-PB5laYhPGHWm_-AUVER2hV-K783K5DVfbfFWPm4,2538
897
+ meutils/serving/fastapi/dependencies/auth.py,sha256=1IvBOazIjjvfoGxBrxMOGEYquh5ylsUBM--dK9cJMYs,2644
898
898
  meutils/serving/fastapi/dependencies/headers.py,sha256=fBJxhNaRNVMJFoSBFcHJyiayR-MJR9gol21ndH3IW40,815
899
899
  meutils/serving/fastapi/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
900
900
  meutils/serving/fastapi/exceptions/http_error.py,sha256=-cBBWNJH3qp1GMSaa9AlojJ18lBLFEk0KHoGUnmV3u4,2601
@@ -998,9 +998,9 @@ meutils/tools/seize.py,sha256=nOKAS63w-Lbi48I0m2MPhdsokUTwxco0laPxYVmW4Mw,1064
998
998
  meutils/tools/service_monitor.py,sha256=ibsLtBN2g2DL7ZnLJ8vhiZOiOcqTAyx711djDdBK-3M,1255
999
999
  meutils/tools/sys_monitor.py,sha256=6MoyzrItqDUOSjfHcMJmMofQkEPTW36CT_aKui0rg84,429
1000
1000
  meutils/tools/token_monitor.py,sha256=Np-YK-R4P4IPAXyZvMxwvXI4sFmNJQAQK1lSegNaYpA,997
1001
- MeUtils-2025.6.24.16.15.48.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1002
- MeUtils-2025.6.24.16.15.48.dist-info/METADATA,sha256=C0178dwGy_62iysEaY0NfTDB2TUJJiIXR81hn-MhUAY,32834
1003
- MeUtils-2025.6.24.16.15.48.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
1004
- MeUtils-2025.6.24.16.15.48.dist-info/entry_points.txt,sha256=lufZlBHRqqZKdY-ZQJ4CSZb0qhV5hQC37egZna9M7ug,357
1005
- MeUtils-2025.6.24.16.15.48.dist-info/top_level.txt,sha256=cInfxMmkgNOskurdjwP5unau4rA7Uw48nu07tYhS7KY,22
1006
- MeUtils-2025.6.24.16.15.48.dist-info/RECORD,,
1001
+ MeUtils-2025.6.25.20.25.36.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1002
+ MeUtils-2025.6.25.20.25.36.dist-info/METADATA,sha256=FCQl9iVoFMJT2zVI20QdQ2o-r5gnXIgdbgnpaAQIydY,32834
1003
+ MeUtils-2025.6.25.20.25.36.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
1004
+ MeUtils-2025.6.25.20.25.36.dist-info/entry_points.txt,sha256=lufZlBHRqqZKdY-ZQJ4CSZb0qhV5hQC37egZna9M7ug,357
1005
+ MeUtils-2025.6.25.20.25.36.dist-info/top_level.txt,sha256=cInfxMmkgNOskurdjwP5unau4rA7Uw48nu07tYhS7KY,22
1006
+ MeUtils-2025.6.25.20.25.36.dist-info/RECORD,,
@@ -23,7 +23,7 @@ client = OpenAI(
23
23
  # base_url="https://api.stepfun.com/v1",
24
24
  base_url=os.getenv("MODELSCOPE_BASE_URL"),
25
25
  # api_key=os.getenv("MODELSCOPE_API_KEY"),
26
- api_key="3f82dcb0-f061-41e9-83aa-626f35fa8194"
26
+ api_key="81ccebd2-1933-4996-8c65-8e170d4f4264"
27
27
  )
28
28
 
29
29
  # print(client.models.list().model_dump_json(indent=4))
meutils/_utils.py CHANGED
@@ -102,4 +102,7 @@ def dict_merge(dicts):
102
102
 
103
103
 
104
104
  if __name__ == '__main__':
105
- print(bjson('xx'))
105
+ # print(bjson('xx'))
106
+ l2 = "async-result/{id}"
107
+ l1 = "/async-result/if123456"#.removeprefix("/")
108
+ print(list_difference(l1, l2))
@@ -117,3 +117,4 @@ if __name__ == '__main__':
117
117
  request = ImageRequest(prompt="https://oss.ffire.cc/files/kling_watermark.png 让这个女人笑起来")
118
118
 
119
119
  arun(generate(request, n=30))
120
+
@@ -116,7 +116,7 @@ async def create_or_update_channel(
116
116
  ids = range(start, end)
117
117
 
118
118
  request_list = []
119
- for i, k in zip(ids, request.key.split()): # api_key不为空
119
+ for i, k in zip(ids, request.key.split()): # api_key不为空, 如果id很多是否考虑复制 api_key不为空
120
120
  _request = request.copy()
121
121
  _request.id = i
122
122
  _request.key = k
@@ -43,4 +43,3 @@ async def get_api_key_money(api_key):
43
43
 
44
44
  if __name__ == '__main__':
45
45
  arun(get_api_key_money(os.getenv("OPENAI_API_KEY_GUOCHAN")))
46
-
@@ -35,27 +35,23 @@ headers = {
35
35
  # if response.is_success:
36
36
  # data = response.json()
37
37
  # return data
38
- @alru_cache(ttl=3 * 60 * 60) # todo cache
38
+ @rcache(ttl=7 * 24 * 3600)
39
39
  async def get_api_key_log(api_key: str) -> Optional[list]: # 日志查询会超时:为了获取 user_id, todo缓存 永久缓存 sk => user
40
40
  try:
41
- if onelog := await redis_aclient.get(f"user:{api_key}"):
42
- return json.loads(onelog)
43
- else:
44
-
45
- async with httpx.AsyncClient(base_url=BASE_URL) as client:
46
- response = await client.get("/api/log/token", params={"key": api_key})
47
- response.raise_for_status()
48
- data = response.json()
49
- if onelog := data['data'][:1]:
50
- await redis_aclient.set(f"user:{api_key}", json.dumps(onelog))
51
- return onelog
41
+ async with httpx.AsyncClient(base_url=BASE_URL) as client:
42
+ response = await client.get("/api/log/token", params={"key": api_key})
43
+ response.raise_for_status()
44
+ data = response.json()
45
+ if onelog := data['data'][:1]:
46
+ await redis_aclient.set(f"user:{api_key}", json.dumps(onelog))
47
+ return onelog
52
48
  except Exception as e:
53
49
  logger.error(e)
54
50
  send_message(f"获取api-key日志失败:{api_key}", title=__name__)
55
51
  return
56
52
 
57
53
 
58
- @alru_cache(ttl=60)
54
+ @rcache(ttl=1 * 24 * 3600)
59
55
  async def get_user(user_id):
60
56
  async with httpx.AsyncClient(base_url=BASE_URL, headers=headers, timeout=30) as client:
61
57
  response = await client.get(f"/api/user/{user_id}")
@@ -67,9 +63,13 @@ async def get_user(user_id):
67
63
 
68
64
 
69
65
  async def get_user_money(api_key):
70
- onelog = await get_api_key_log(api_key)
71
- if onelog:
72
- user_id = onelog[0]['user_id']
66
+ if onelog := await get_api_key_log(api_key):
67
+ onelog = onelog[0]
68
+ if quota := onelog.get('quota'):
69
+ return quota / 500000
70
+
71
+ user_id = onelog['user_id']
72
+
73
73
  data = await get_user(user_id)
74
74
  logger.debug(data)
75
75
  if data:
@@ -106,11 +106,12 @@ async def get_user_from_api_key(api_key):
106
106
 
107
107
  if __name__ == '__main__':
108
108
  # api-key => get_one_log => get_user => put_user
109
- # arun(get_user(814))
110
- payload = arun(get_user(1))
109
+ # arun(get_user(11047))
110
+ # payload = arun(get_user(1))
111
111
  # print(payload)
112
- arun(put_user(payload['data'], -1))
112
+ # arun(put_user(payload['data'], -1))
113
+ # arun(get_api_key_log("sk-2KedjhqS6uubaONCS1Dxyq28Tc1P4AtQk3WFfBpzy4enyalH"))
113
114
 
114
- # arun(get_api_key_log('sk-gpoH1z3G6nHovD8MY40i6xx5tsC1vbh7B3Aao2jmejYNoKhv'))
115
- # arun(get_user_money("sk-LlB4W38z9kv5Wy1c3ceeu4PHeIWs6bbWsjr8Om31jYvsucRv"))
116
- # arun(get_user_from_api_key('sk-blrcheysazcdqkyghaumetjhzscjedyppghmlujmzhuuyfeu'))
115
+ # arun(get_api_key_log('sk-'))
116
+ arun(get_user_money("sk-2KedjhqS6uubaONCS1Dxyq28Tc1P4AtQk3WFfBpzy4enyalH"))
117
+ # arun(get_user_from_api_key('sk-'))
@@ -48,15 +48,18 @@ if __name__ == '__main__':
48
48
  # arun(get_user_quota(os.getenv("OPENAI_API_KEY")))
49
49
  # arun(get_user_quota(user_id=1))
50
50
 
51
- async def task():
52
- filter_kwargs = dict(
53
- username=f"{shortuuid.random(length=6)}@chatfire.com",
54
- )
55
- return await update_or_insert(OneapiUser, filter_kwargs)
56
-
57
-
58
- async def main():
59
- await asyncio.gather(*[task() for _ in range(5000)])
60
-
61
-
62
- arun(main())
51
+ # async def task():
52
+ # filter_kwargs = dict(
53
+ # username=f"{shortuuid.random(length=6)}@chatfire.com",
54
+ # )
55
+ # return await update_or_insert(OneapiUser, filter_kwargs)
56
+ #
57
+ #
58
+ # async def main():
59
+ # await asyncio.gather(*[task() for _ in range(5000)])
60
+ #
61
+ #
62
+ # arun(main())
63
+
64
+
65
+ arun(get_user_quota("sk-2KedjhqS6uubaONCS1Dxyq28Tc1P4AtQk3WFfBpzy4enyalH"))
meutils/apis/utils.py CHANGED
@@ -34,6 +34,7 @@ async def make_request(
34
34
  options["params"] = params
35
35
 
36
36
  path = path or "/"
37
+ path = f"""/{path.removeprefix("/")}"""
37
38
 
38
39
  if method.upper() == 'GET':
39
40
  response = await client.get(path, options=options, cast_to=object)
meutils/data/VERSION CHANGED
@@ -1 +1 @@
1
- 2025.06.24.16.15.48
1
+ 2025.06.25.20.25.36
meutils/db/redis_db.py CHANGED
@@ -96,5 +96,6 @@ if __name__ == '__main__':
96
96
 
97
97
  # r = redis_client.sadd('set1', 'a', 'b', 'c')
98
98
  # r = redis_client.sadd('set1', 'd')
99
- k="meutils.config_utils.lark_utils.commonaget_spreadsheet_values()[('feishu_url', 'https://xchatllm.feishu.cn/sheets/GYCHsvI4qhnDPNtI4VPcdw2knEd?sheet=Gvm9dt'), ('to_dataframe', True)] "
100
- redis_client.delete(k)
99
+ # k="meutils.config_utils.lark_utils.commonaget_spreadsheet_values()[('feishu_url', 'https://xchatllm.feishu.cn/sheets/GYCHsvI4qhnDPNtI4VPcdw2knEd?sheet=Gvm9dt'), ('to_dataframe', True)] "
100
+ # redis_client.delete(k)
101
+ print(redis_client.get('test'))
@@ -0,0 +1,217 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # @Project : AI. @by PyCharm
4
+ # @File : usage_utils
5
+ # @Time : 2025/6/24 08:53
6
+ # @Author : betterme
7
+ # @WeChat : meutils
8
+ # @Software : PyCharm
9
+ # @Description :
10
+ """
11
+ 1. 同步任务(流 非流)
12
+ - 按次
13
+ - 按量
14
+ 2. 异步任务
15
+ - 按次
16
+ - 按量
17
+ """
18
+
19
+ from meutils.pipe import *
20
+ from meutils.llm.clients import AsyncOpenAI
21
+ from meutils.apis.utils import make_request
22
+
23
+ base_url = "https://api.chatfire.cn/flux/v1"
24
+
25
+
26
+ # base_url="http://110.42.51.201:38888/flux/v1"
27
+ # base_url = "http://0.0.0.0:8000/v1/async/flux/v1"
28
+ # base_url = "https://openai-dev.chatfire.cn/usage/async/flux/v1"
29
+
30
+ async def bling_for_async_task(
31
+ model: str = "usage-async",
32
+ task_id: str = "123456",
33
+ n: float = 1,
34
+ api_key: Optional[str] = None
35
+ ):
36
+ """todo: 错误如何传进去 post可行 还是 必须get入口"""
37
+ if n := int(np.round(n)):
38
+ tasks = [
39
+ make_request(
40
+ base_url=base_url,
41
+ api_key=api_key,
42
+ path=f"/{model}",
43
+ payload={
44
+ "id": task_id,
45
+ # 'polling_url': f'{base_url}/get_result?id={task_id}',
46
+ }
47
+ )
48
+ for i in range(n)
49
+ ]
50
+
51
+ _ = await asyncio.gather(*tasks)
52
+ return _
53
+
54
+
55
+ async def get_async_task(id: str = "123456"):
56
+ # 计费
57
+ _ = await make_request(
58
+ base_url=base_url,
59
+ path=f"/get_result?id={id}",
60
+
61
+ method="GET"
62
+ )
63
+
64
+ return _
65
+
66
+
67
+ async def bling_for_tokens(
68
+ model: str = "usage-chat",
69
+
70
+ usage: Optional[dict] = None,
71
+
72
+ api_key: Optional[str] = None,
73
+
74
+ n: Optional[float] = None, # 按次走以前逻辑也行
75
+ ):
76
+ """
77
+
78
+ image_usage = {
79
+ "input_tokens": input_tokens,
80
+ "input_tokens_details": {
81
+ "text_tokens": input_tokens,
82
+ "image_tokens": 0,
83
+ },
84
+ "output_tokens": output_tokens,
85
+ "total_tokens": total_tokens
86
+ }
87
+
88
+ # usage = {
89
+ # "prompt_tokens": input_tokens,
90
+ # "completion_tokens": output_tokens,
91
+ # "total_tokens": total_tokens
92
+ # }
93
+ """
94
+ usage = usage or {}
95
+ n = n and int(np.round(n))
96
+
97
+ client = AsyncOpenAI(api_key=api_key)
98
+ if n:
99
+ _ = await client.images.generate(
100
+ model=model,
101
+ prompt="ChatfireAPI",
102
+ n=n
103
+ )
104
+
105
+ elif "input_tokens" in usage:
106
+ _ = await client.images.generate(
107
+ model=model,
108
+ prompt="ChatfireAPI",
109
+ n=n,
110
+ extra_body={"extra_fields": usage}
111
+ )
112
+ else:
113
+ _ = await client.chat.completions.create(
114
+ model=model,
115
+ messages=[{"role": "user", "content": "ChatfireAPI"}],
116
+ extra_body={"extra_body": usage}
117
+ )
118
+ return _
119
+
120
+
121
+ def get_billing_n(request: Union[BaseModel, dict], duration: float = 6):
122
+ """继续拓展其兼容性
123
+
124
+ :param request:
125
+ :param duration:
126
+ :return:
127
+ """
128
+ if isinstance(request, BaseModel):
129
+ request = request.model_dump()
130
+
131
+ # 数量
132
+ N = request.get("n") or request.get("num_images") or 1
133
+
134
+ # 时长
135
+ N += np.ceil(request.get("duration", 0) / duration)
136
+
137
+ # 分辨率
138
+ if "1080p" in str(request).lower():
139
+ N += 1
140
+
141
+ # 命令行参数 --duration 5
142
+ s = {"--duration 10", "--dur 10"}
143
+ if any(i in str(request) for i in s):
144
+ N += 1
145
+
146
+ return N
147
+
148
+
149
+ @asynccontextmanager
150
+ async def billing_flow_for_async_task(
151
+ model: str = "usage-async",
152
+ task_id: str = "123456",
153
+ n: float = 1,
154
+ api_key: Optional[str] = None
155
+ ):
156
+ if n: # 计费
157
+ await bling_for_async_task(model, task_id=task_id, n=n, api_key=api_key)
158
+ yield
159
+
160
+ else: # 不计费
161
+ a = yield
162
+ logger.debug(a)
163
+
164
+
165
+ @asynccontextmanager
166
+ async def billing_flow_for_tokens(
167
+ model: str = "usage-chat",
168
+
169
+ usage: Optional[dict] = None, # None就是按次
170
+
171
+ api_key: Optional[str] = None,
172
+ ):
173
+ await bling_for_tokens(model, usage=usage, api_key=api_key)
174
+
175
+ yield
176
+
177
+
178
+ if __name__ == '__main__':
179
+ # arun(create_usage_for_tokens())
180
+ # usage = {
181
+ # "input_tokens": 1,
182
+ # "input_tokens_details": {
183
+ # "text_tokens": 1,
184
+ # "image_tokens": 0,
185
+ # },
186
+ # "output_tokens": 100,
187
+ # "total_tokens": 101
188
+ # }
189
+ # n = 1
190
+ # arun(create_usage_for_tokens(usage=usage, n=n))
191
+
192
+ # arun(create_usage_for_async_task(task_id="task_id", n=1))
193
+
194
+ model = "usage-async"
195
+ model = "fal-ai/model1"
196
+ task_id = f"{model}-{int(time.time())}"
197
+
198
+ # arun(create_usage_for_async_task(model, task_id=task_id, n=3))
199
+
200
+ #
201
+ # arun(get_async_task(task_id))
202
+ #
203
+ # arun(get_async_task(f"{task_id}-Ready", status="Ready"))
204
+
205
+ # arun(get_async_task('chatfire-123456-Ready-1'))
206
+
207
+ # {
208
+ # "id": "chatfire-1750769977.856766",
209
+ # "result": {},
210
+ # "status": "Error",
211
+ # "details": {
212
+ # "xx": [
213
+ # "xxxx"
214
+ # ]
215
+ # },
216
+ # "progress": 99
217
+ # }
@@ -58,10 +58,6 @@ ASPECT_RATIOS = {
58
58
  }
59
59
 
60
60
 
61
- # prompt: str,
62
- # model: Union[str, ImageModel, None] | NotGiven = NOT_GIVEN,
63
- # n: Optional[int] | NotGiven = NOT_GIVEN,
64
-
65
61
  class ImagesResponse(_ImagesResponse):
66
62
  created: int = Field(default_factory=lambda: int(time.time()))
67
63
 
@@ -155,7 +155,39 @@ class FileTask(BaseModel):
155
155
  url: Optional[str] = None
156
156
 
157
157
 
158
- # pass
158
+ class FluxTaskResponse(BaseModel):
159
+ id: Union[str, int] = Field(default_factory=lambda: shortuuid.random())
160
+
161
+ """Task not found, Pending, Request Moderated, Content Moderated, Ready, Error"""
162
+ status: Optional[Literal["Pending", "Ready", "Error", "Content Moderated"]] = None # Ready, Error, success, failed
163
+
164
+ result: Optional[dict] = None
165
+
166
+ details: Optional[dict] = None # Error才显示, 当做 metadata
167
+ progress: Optional[int] = None
168
+
169
+ def __init__(self, /, **data: Any):
170
+ super().__init__(**data)
171
+
172
+ self.details = self.details or self.result
173
+
174
+ if self.status is None and self.result:
175
+ if status := (
176
+ self.result.get("status")
177
+ or self.result.get("task_status")
178
+ or self.result.get("state")
179
+ or self.result.get("task_state")
180
+ ):
181
+ logger.debug(status)
182
+ if status.lower().startswith(("succ", "ok", "compl")):
183
+ self.status = "Ready"
184
+
185
+ if status.lower().startswith(("fail", "error", "cancel")):
186
+ self.status = "Error"
187
+
188
+ if any(i in status.lower() for i in ("moder",)):
189
+ self.status = "Content Moderated"
190
+
159
191
 
160
192
  if __name__ == '__main__':
161
193
  # print(TaskType("kling").name)
@@ -192,4 +224,15 @@ if __name__ == '__main__':
192
224
 
193
225
  response.user_id = 1
194
226
 
195
- print(response)
227
+ data = {
228
+ "model": "cogvideox-flash",
229
+ "request_id": "20250625182913f3eb016d10844e3a",
230
+ "task_status": "SUCCESS",
231
+ "video_result": [
232
+ {
233
+ "cover_image_url": "https://aigc-files.bigmodel.cn/api/cogvideo/3ce064a4-51af-11f0-8152-8e82dfcce76c_cover_0.jpeg",
234
+ "url": "https://aigc-files.bigmodel.cn/api/cogvideo/3ce064a4-51af-11f0-8152-8e82dfcce76c_0.mp4"
235
+ }
236
+ ]
237
+ }
238
+ print(FluxTaskResponse(result=data))
@@ -20,19 +20,9 @@ http_bearer = HTTPBearer()
20
20
 
21
21
 
22
22
  # 定义获取token的函数
23
+ async def parse_token(token: str) -> Optional[str]:
24
+ if token is None: return None
23
25
 
24
- async def get_bearer_token(
25
- auth: Optional[HTTPAuthorizationCredentials] = Depends(http_bearer)
26
- ) -> Optional[str]:
27
- """
28
- 获取Bearer token
29
- :param auth: HTTP认证凭证
30
- :return: token字符串
31
- """
32
- if auth is None:
33
- return None
34
-
35
- token = auth.credentials
36
26
  if token.startswith('redis:'): # redis里按序轮询
37
27
  if "feishu.cn" in token: # redis:https://xchatllm.feishu.cn/sheets/Bmjtst2f6hfMqFttbhLcdfRJnNf?sheet=Y7HVfo
38
28
  feishu_url = token.removeprefix("redis:")
@@ -59,6 +49,20 @@ async def get_bearer_token(
59
49
  return token
60
50
 
61
51
 
52
+ async def get_bearer_token(
53
+ auth: Optional[HTTPAuthorizationCredentials] = Depends(http_bearer)
54
+ ) -> Optional[str]:
55
+ """
56
+ 获取Bearer token
57
+ :param auth: HTTP认证凭证
58
+ :return: token字符串
59
+ """
60
+ if auth is None:
61
+ return None
62
+
63
+ return await parse_token(auth.credentials)
64
+
65
+
62
66
  # async def get_next_token(redis_key):
63
67
  # """轮询"""
64
68
  # if api_key := await redis_aclient.lpop(redis_key):