dycw-utilities 0.127.0__py3-none-any.whl → 0.129.13__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.
@@ -1,13 +1,18 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.127.0
3
+ Version: 0.129.13
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
7
- Requires-Dist: typing-extensions<4.14,>=4.13.1
7
+ Requires-Dist: typing-extensions<4.15,>=4.14.0
8
+ Provides-Extra: logging
9
+ Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'logging'
10
+ Requires-Dist: coloredlogs<15.1,>=15.0.1; extra == 'logging'
11
+ Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'logging'
12
+ Requires-Dist: whenever<0.9,>=0.8.4; extra == 'logging'
8
13
  Provides-Extra: test
9
14
  Requires-Dist: dycw-pytest-only<2.2,>=2.1.1; extra == 'test'
10
- Requires-Dist: hypothesis<6.134,>=6.133.0; extra == 'test'
15
+ Requires-Dist: hypothesis<6.136,>=6.135.2; extra == 'test'
11
16
  Requires-Dist: pytest-asyncio<1.1,>=1.0.0; extra == 'test'
12
17
  Requires-Dist: pytest-cov<6.2,>=6.1.1; extra == 'test'
13
18
  Requires-Dist: pytest-instafail<0.6,>=0.5.0; extra == 'test'
@@ -19,6 +24,8 @@ Requires-Dist: pytest-rng<1.1,>=1.0.0; extra == 'test'
19
24
  Requires-Dist: pytest-timeout<2.5,>=2.4.0; extra == 'test'
20
25
  Requires-Dist: pytest-xdist<3.8,>=3.7.0; extra == 'test'
21
26
  Requires-Dist: pytest<8.4,>=8.3.5; extra == 'test'
27
+ Provides-Extra: zzz-test-aiolimiter
28
+ Requires-Dist: aiolimiter<1.3,>=1.2.1; extra == 'zzz-test-aiolimiter'
22
29
  Provides-Extra: zzz-test-altair
23
30
  Requires-Dist: altair<5.6,>=5.5.0; extra == 'zzz-test-altair'
24
31
  Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-altair'
@@ -77,9 +84,9 @@ Provides-Extra: zzz-test-hypothesis
77
84
  Requires-Dist: aiosqlite<0.22,>=0.21.0; extra == 'zzz-test-hypothesis'
78
85
  Requires-Dist: asyncpg<0.31,>=0.30.0; extra == 'zzz-test-hypothesis'
79
86
  Requires-Dist: greenlet<3.3,>=3.2.0; extra == 'zzz-test-hypothesis'
80
- Requires-Dist: hypothesis<6.134,>=6.133.0; extra == 'zzz-test-hypothesis'
87
+ Requires-Dist: hypothesis<6.136,>=6.135.2; extra == 'zzz-test-hypothesis'
81
88
  Requires-Dist: luigi<3.7,>=3.6.0; extra == 'zzz-test-hypothesis'
82
- Requires-Dist: numpy<2.3,>=2.2.6; extra == 'zzz-test-hypothesis'
89
+ Requires-Dist: numpy<2.4,>=2.3.0; extra == 'zzz-test-hypothesis'
83
90
  Requires-Dist: pathvalidate<3.3,>=3.2.3; extra == 'zzz-test-hypothesis'
84
91
  Requires-Dist: redis<6.3,>=6.2.0; extra == 'zzz-test-hypothesis'
85
92
  Requires-Dist: sqlalchemy<2.1,>=2.0.41; extra == 'zzz-test-hypothesis'
@@ -93,12 +100,11 @@ Requires-Dist: polars-lts-cpu<1.31,>=1.30.0; extra == 'zzz-test-iterables'
93
100
  Requires-Dist: whenever<0.9,>=0.8.4; extra == 'zzz-test-iterables'
94
101
  Provides-Extra: zzz-test-jupyter
95
102
  Requires-Dist: jupyterlab<4.3,>=4.2.0; extra == 'zzz-test-jupyter'
96
- Requires-Dist: pandas<2.3,>=2.2.2; extra == 'zzz-test-jupyter'
103
+ Requires-Dist: pandas<2.4,>=2.3.0; extra == 'zzz-test-jupyter'
97
104
  Requires-Dist: polars-lts-cpu<1.31,>=1.30.0; extra == 'zzz-test-jupyter'
98
105
  Provides-Extra: zzz-test-logging
99
106
  Requires-Dist: atomicwrites<1.5,>=1.4.1; extra == 'zzz-test-logging'
100
107
  Requires-Dist: coloredlogs<15.1,>=15.0.1; extra == 'zzz-test-logging'
101
- Requires-Dist: concurrent-log-handler<0.10,>=0.9.26; extra == 'zzz-test-logging'
102
108
  Requires-Dist: rich<14.1,>=14.0.0; extra == 'zzz-test-logging'
103
109
  Requires-Dist: tomlkit<0.14,>=0.13.2; extra == 'zzz-test-logging'
104
110
  Requires-Dist: tzlocal<5.4,>=5.3.1; extra == 'zzz-test-logging'
@@ -109,14 +115,14 @@ Provides-Extra: zzz-test-luigi
109
115
  Requires-Dist: luigi<3.7,>=3.6.0; extra == 'zzz-test-luigi'
110
116
  Requires-Dist: whenever<0.9,>=0.8.4; extra == 'zzz-test-luigi'
111
117
  Provides-Extra: zzz-test-math
112
- Requires-Dist: numpy<2.3,>=2.2.6; extra == 'zzz-test-math'
118
+ Requires-Dist: numpy<2.4,>=2.3.0; extra == 'zzz-test-math'
113
119
  Provides-Extra: zzz-test-memory-profiler
114
120
  Requires-Dist: memory-profiler<0.62,>=0.61.0; extra == 'zzz-test-memory-profiler'
115
121
  Provides-Extra: zzz-test-modules
116
122
  Provides-Extra: zzz-test-more-itertools
117
123
  Requires-Dist: more-itertools<10.8,>=10.7.0; extra == 'zzz-test-more-itertools'
118
124
  Provides-Extra: zzz-test-numpy
119
- Requires-Dist: numpy<2.3,>=2.2.6; extra == 'zzz-test-numpy'
125
+ Requires-Dist: numpy<2.4,>=2.3.0; extra == 'zzz-test-numpy'
120
126
  Provides-Extra: zzz-test-operator
121
127
  Requires-Dist: polars-lts-cpu<1.31,>=1.30.0; extra == 'zzz-test-operator'
122
128
  Requires-Dist: whenever<0.9,>=0.8.4; extra == 'zzz-test-operator'
@@ -173,7 +179,7 @@ Requires-Dist: scipy<1.16,>=1.15.3; extra == 'zzz-test-scipy'
173
179
  Provides-Extra: zzz-test-sentinel
174
180
  Provides-Extra: zzz-test-shelve
175
181
  Provides-Extra: zzz-test-slack-sdk
176
- Requires-Dist: aiohttp<3.12.8,>=3.12.7; extra == 'zzz-test-slack-sdk'
182
+ Requires-Dist: aiohttp<3.13,>=3.12.11; extra == 'zzz-test-slack-sdk'
177
183
  Requires-Dist: slack-sdk<3.36,>=3.35.0; extra == 'zzz-test-slack-sdk'
178
184
  Provides-Extra: zzz-test-socket
179
185
  Provides-Extra: zzz-test-sqlalchemy
@@ -1,6 +1,7 @@
1
- utilities/__init__.py,sha256=9_7tk0nJkuN-6qR4z_kQd3QZb3ioRi15dhZGN0m-284,60
1
+ utilities/__init__.py,sha256=ElRBaMkO-9DZu6rm3wsFKiL8NMQBIr7WdSl9DULRoT0,61
2
+ utilities/aiolimiter.py,sha256=mD0wEiqMgwpty4XTbawFpnkkmJS6R4JRsVXFUaoitSU,628
2
3
  utilities/altair.py,sha256=Gpja-flOo-Db0PIPJLJsgzAlXWoKUjPU1qY-DQ829ek,9156
3
- utilities/asyncio.py,sha256=wKxwNnxdWxsiy5U0b1F3UgpWRHlPKM0y_OcmURzqxR8,51396
4
+ utilities/asyncio.py,sha256=3n5EIcSq2xtEF1i4oR0oY2JmBq3NyugeHKFK39Mt22s,37987
4
5
  utilities/atomicwrites.py,sha256=geFjn9Pwn-tTrtoGjDDxWli9NqbYfy3gGL6ZBctiqSo,5393
5
6
  utilities/atools.py,sha256=IYMuFSFGSKyuQmqD6v5IUtDlz8PPw0Sr87Cub_gRU3M,1168
6
7
  utilities/cachetools.py,sha256=C1zqOg7BYz0IfQFK8e3qaDDgEZxDpo47F15RTfJM37Q,2910
@@ -11,26 +12,26 @@ utilities/contextvars.py,sha256=RsSGGrbQqqZ67rOydnM7WWIsM2lIE31UHJLejnHJPWY,505
11
12
  utilities/cryptography.py,sha256=_CiK_K6c_-uQuUhsUNjNjTL-nqxAh4_1zTfS11Xe120,972
12
13
  utilities/cvxpy.py,sha256=Rv1-fD-XYerosCavRF8Pohop2DBkU3AlFaGTfD8AEAA,13776
13
14
  utilities/dataclasses.py,sha256=iiC1wpGXWhaocIikzwBt8bbLWyImoUlOlcDZJGejaIg,33011
14
- utilities/datetime.py,sha256=uYoaOi_C1YtNXGfTN9xlTrW62Re2b1_4Skuv14_MeYQ,38985
15
+ utilities/datetime.py,sha256=aiPh2OZK2g9gn4yEeSO0lODOmvx8U_rGn6XeSzyk4VY,38738
15
16
  utilities/enum.py,sha256=HoRwVCWzsnH0vpO9ZEcAAIZLMv0Sn2vJxxA4sYMQgDs,5793
16
17
  utilities/errors.py,sha256=nC7ZYtxxDBMfrTHtT_MByBfup_wfGQFRo3eDt-0ZPe8,1045
17
18
  utilities/eventkit.py,sha256=6M5Xu1SzN-juk9PqBHwy5dS-ta7T0qA6SMpDsakOJ0E,13039
18
- utilities/fastapi.py,sha256=LG1-Q8RDi7wsyVN6v74qptPYX8WGXPkFOQFniMvtzjc,2439
19
+ utilities/fastapi.py,sha256=gZrXYxKAc7ZEAL_tDmkcbqebkm-KfMCY0X8r-1HF5dI,2962
19
20
  utilities/fpdf2.py,sha256=y1NGXR5chWqLXWpewGV3hlRGMr_5yV1lVRkPBhPEgJI,1843
20
21
  utilities/functions.py,sha256=jgt592voaHNtX56qX0SRvFveVCRmSIxCZmqvpLZCnY8,27305
21
22
  utilities/functools.py,sha256=WrpHt7NLNWSUn9A1Q_ZIWlNaYZOEI4IFKyBG9HO3BC4,1643
22
23
  utilities/getpass.py,sha256=DfN5UgMAtFCqS3dSfFHUfqIMZX2shXvwphOz_6J6f6A,103
23
- utilities/git.py,sha256=wpt5dZ5Oi5931pN24_VLZYaQOvmR0OcQuVtgHzFUN1k,2359
24
+ utilities/git.py,sha256=oi7-_l5e9haSANSCvQw25ufYGoNahuUPHAZ6114s3JQ,1191
24
25
  utilities/hashlib.py,sha256=SVTgtguur0P4elppvzOBbLEjVM3Pea0eWB61yg2ilxo,309
25
26
  utilities/http.py,sha256=WcahTcKYRtZ04WXQoWt5EGCgFPcyHD3EJdlMfxvDt-0,946
26
- utilities/hypothesis.py,sha256=snJ35u9-dXKn3Unac4IPW2V4JtRUg5B7SsDBrQHIx9g,44834
27
+ utilities/hypothesis.py,sha256=UnUMJmeqwJuK7uyUqw_i3opUYzVKud4RMG0RMOSRBQY,44463
27
28
  utilities/importlib.py,sha256=mV1xT_O_zt_GnZZ36tl3xOmMaN_3jErDWY54fX39F6Y,429
28
29
  utilities/ipython.py,sha256=V2oMYHvEKvlNBzxDXdLvKi48oUq2SclRg5xasjaXStw,763
29
30
  utilities/iterables.py,sha256=mDqw2_0MUVp-P8FklgcaVTi2TXduH0MxbhTDzzhSBho,44915
30
31
  utilities/jupyter.py,sha256=ft5JA7fBxXKzP-L9W8f2-wbF0QeYc_2uLQNFDVk4Z-M,2917
31
32
  utilities/libcst.py,sha256=Jto5ppzRzsxn4AD32IS8n0lbgLYXwsVJB6EY8giNZyY,4974
32
33
  utilities/lightweight_charts.py,sha256=0xNfcsrgFI0R9xL25LtSm-W5yhfBI93qQNT6HyaXAhg,2769
33
- utilities/logging.py,sha256=gwo3pusPjnWO1ollrtn1VKYyRAQJTue4SkCbMeNvec4,25715
34
+ utilities/logging.py,sha256=GvSjMcjjHehbGeFGLQDiNvDteKym3-M-WF8tPlVDIQY,26228
34
35
  utilities/loguru.py,sha256=MEMQVWrdECxk1e3FxGzmOf21vWT9j8CAir98SEXFKPA,3809
35
36
  utilities/luigi.py,sha256=fpH9MbxJDuo6-k9iCXRayFRtiVbUtibCJKugf7ygpv0,5988
36
37
  utilities/math.py,sha256=-mQgbah-dPJwOEWf3SonrFoVZ2AVxMgpeQ3dfVa-oJA,26764
@@ -43,7 +44,7 @@ utilities/optuna.py,sha256=loyJGWTzljgdJaoLhP09PT8Jz6o_pwBOwehY33lHkhw,1923
43
44
  utilities/orjson.py,sha256=AvPFxzJdxC-3PBID3cqdiMyN8FeC7aW9QUgGwbvKuAM,36948
44
45
  utilities/os.py,sha256=D_FyyT-6TtqiN9KSS7c9g1fnUtgxmyMtzAjmYLkk46A,3587
45
46
  utilities/parse.py,sha256=vsZ2jf_ceSI_Kta9titixufysJaVXh0Whjz1T4awJZw,18938
46
- utilities/pathlib.py,sha256=31WPMXdLIyXgYOMMl_HOI2wlo66MGSE-cgeelk-Lias,1410
47
+ utilities/pathlib.py,sha256=PK41rf1c9Wqv7h8f5R7H3_Lhq_gQZTUJD5tu3gMHVaU,3247
47
48
  utilities/period.py,sha256=o4wXYEXVlFomop4-Ra4L0yRP4i99NZFjIe_fa7NdZck,11024
48
49
  utilities/pickle.py,sha256=Bhvd7cZl-zQKQDFjUerqGuSKlHvnW1K2QXeU5UZibtg,657
49
50
  utilities/platform.py,sha256=48IOKx1IC6ZJXWG-b56ZQptITcNFhWRjELW72o2dGTA,2398
@@ -54,21 +55,21 @@ utilities/pqdm.py,sha256=foRytQybmOQ05pjt5LF7ANyzrIa--4ScDE3T2wd31a4,3118
54
55
  utilities/psutil.py,sha256=RtbLKOoIJhqrJmEoHDBVeSD-KPzshtS0FtRXBP9_w2s,3751
55
56
  utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
57
  utilities/pydantic.py,sha256=f6qtR5mO2YMuyvNmbaEj5YeD9eGA4YYfb7Bjzh9jUs0,1845
57
- utilities/pyinstrument.py,sha256=OJFDh4o1CWIa4aYPYURdQjgap_nvP45KUsCEe94rQHY,829
58
+ utilities/pyinstrument.py,sha256=O2dngLsmUUnpMtW1eN3OiM0rGQNBIlXSvZmym_jAsvU,904
58
59
  utilities/pyrsistent.py,sha256=wVOVIe_68AAaa-lUE9y-TEzDawVp1uEIc_zfoDgr5ww,2287
59
60
  utilities/pytest.py,sha256=KoHSwJbIY2CHtFUlUr_gnEk7z1DVTaldl8RDQ4tDkG4,7837
60
- utilities/pytest_regressions.py,sha256=-SVT9647Dg6-JcdsiaDKXe3NdOmmrvGevLKWwGjxq3c,5088
61
- utilities/python_dotenv.py,sha256=iWcnpXbH7S6RoXHiLlGgyuH6udCupAcPd_gQ0eAenQ0,3190
61
+ utilities/pytest_regressions.py,sha256=YI55B7EtLjhz7zPJZ6NK9bWrxrKCKabWZJe1cwcbA5o,5082
62
+ utilities/python_dotenv.py,sha256=edXsvHZhZnYeqfMfrsRRpj7_9eJI6uizh3xLx8Q9B3w,3228
62
63
  utilities/random.py,sha256=lYdjgxB7GCfU_fwFVl5U-BIM_HV3q6_urL9byjrwDM8,4157
63
64
  utilities/re.py,sha256=5J4d8VwIPFVrX2Eb8zfoxImDv7IwiN_U7mJ07wR2Wvs,3958
64
- utilities/redis.py,sha256=EZgqWeoGpvN-BfCQL93F3rYlfB4U_zhzHCBuZpDmKpo,37157
65
+ utilities/redis.py,sha256=7Sc-G43VXVzFQU7MHKyI1y3u7My3oT1UoWXPGcKM_-0,36008
65
66
  utilities/reprlib.py,sha256=ssYTcBW-TeRh3fhCJv57sopTZHF5FrPyyUg9yp5XBlo,3953
66
- utilities/scipy.py,sha256=X6ROnHwiUhAmPhM0jkfEh0-Fd9iRvwiqtCQMOLmOQF8,945
67
+ utilities/scipy.py,sha256=wZJM7fEgBAkLSYYvSmsg5ac-QuwAI0BGqHVetw1_Hb0,947
67
68
  utilities/sentinel.py,sha256=3jIwgpMekWgDAxPDA_hXMP2St43cPhciKN3LWiZ7kv0,1248
68
69
  utilities/shelve.py,sha256=HZsMwK4tcIfg3sh0gApx4-yjQnrY4o3V3ZRimvRhoW0,738
69
- utilities/slack_sdk.py,sha256=jqQyiYSKseZNdg2lCkvPzrAows9p7kVDDjvEnatioKo,5702
70
+ utilities/slack_sdk.py,sha256=ltmzv68aa73CJGqTDvt8L9vDm22YU9iOCo3NCiNd3vA,4347
70
71
  utilities/socket.py,sha256=K77vfREvzoVTrpYKo6MZakol0EYu2q1sWJnnZqL0So0,118
71
- utilities/sqlalchemy.py,sha256=XTZmNKXD9SUbZ7V1xNNxok-0Ej0Cf4ya5pjuIeH-kdg,39388
72
+ utilities/sqlalchemy.py,sha256=I81qR7JtS-q1sLnw42p7L0FC0imT98gJHGte_KOjpAA,37890
72
73
  utilities/sqlalchemy_polars.py,sha256=s7hQNep2O5DTgIRXyN_JRQma7a4DAtNd25tshaZW8iw,15490
73
74
  utilities/statsmodels.py,sha256=koyiBHvpMcSiBfh99wFUfSggLNx7cuAw3rwyfAhoKpQ,3410
74
75
  utilities/streamlit.py,sha256=U9PJBaKP1IdSykKhPZhIzSPTZsmLsnwbEPZWzNhJPKk,2955
@@ -79,18 +80,18 @@ utilities/tenacity.py,sha256=1PUvODiBVgeqIh7G5TRt5WWMSqjLYkEqP53itT97WQc,4914
79
80
  utilities/text.py,sha256=ymBFlP_cA8OgNnZRVNs7FAh7OG8HxE6YkiLEMZv5g_A,11297
80
81
  utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
81
82
  utilities/timer.py,sha256=Rkc49KSpHuC8s7vUxGO9DU55U9I6yDKnchsQqrUCVBs,4075
82
- utilities/traceback.py,sha256=Jg7HS3AwQ-W-msdwHp22_PSHZcR54PbmsSf115B6TSM,27435
83
- utilities/types.py,sha256=2f1DqTZTMRlpCPWPd9-rh_uwmRPv9UdBoi_Bfv7Ccmo,18374
83
+ utilities/traceback.py,sha256=EUm-5jhH1RICBmsG_H77-CXvD-IVErfkzGRSqnvR0dI,35782
84
+ utilities/types.py,sha256=gP04CcCOyFrG7BgblVCsrrChiuO2x842NDVW-GF7odo,18370
84
85
  utilities/typing.py,sha256=H6ysJkI830aRwLsMKz0SZIw4cpcsm7d6KhQOwr-SDh0,13817
85
86
  utilities/tzdata.py,sha256=yCf70NICwAeazN3_JcXhWvRqCy06XJNQ42j7r6gw3HY,1217
86
87
  utilities/tzlocal.py,sha256=3upDNFBvGh1l9njmLR2z2S6K6VxQSb7QizYGUbAH3JU,960
87
88
  utilities/uuid.py,sha256=jJTFxz-CWgltqNuzmythB7iEQ-Q1mCwPevUfKthZT3c,611
88
- utilities/version.py,sha256=QFuyEeQA6jI0ruBEcmhqG36f-etg1AEiD1drBBqhQrs,5358
89
+ utilities/version.py,sha256=ufhJMmI6KPs1-3wBI71aj5wCukd3sP_m11usLe88DNA,5117
89
90
  utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
90
- utilities/whenever.py,sha256=jS31ZAY5OMxFxLja_Yo5Fidi87Pd-GoVZ7Vi_teqVDA,16743
91
+ utilities/whenever.py,sha256=QbXgFAPuUL7PCp2hajmIP-FFIfIR1J6Y0TxJbeoj60I,18434
91
92
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
92
93
  utilities/zoneinfo.py,sha256=-5j7IQ9nb7gR43rdgA7ms05im-XuqhAk9EJnQBXxCoQ,1874
93
- dycw_utilities-0.127.0.dist-info/METADATA,sha256=bbY-L7Ck2mkOycI3XCTxhqptadPeM716AJz69ryeIXw,12803
94
- dycw_utilities-0.127.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
95
- dycw_utilities-0.127.0.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
96
- dycw_utilities-0.127.0.dist-info/RECORD,,
94
+ dycw_utilities-0.129.13.dist-info/METADATA,sha256=ABmFkSoWZUCu2bogLW3aUqVc6ngY-E-gnSl6MH4mBqQ,13084
95
+ dycw_utilities-0.129.13.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
96
+ dycw_utilities-0.129.13.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
97
+ dycw_utilities-0.129.13.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.127.0"
3
+ __version__ = "0.129.13"
@@ -0,0 +1,25 @@
1
+ from __future__ import annotations
2
+
3
+ from asyncio import get_running_loop
4
+ from typing import TYPE_CHECKING
5
+
6
+ from aiolimiter import AsyncLimiter
7
+
8
+ if TYPE_CHECKING:
9
+ from collections.abc import Hashable
10
+
11
+ _LIMITERS: dict[tuple[int, Hashable], AsyncLimiter] = {}
12
+
13
+
14
+ def get_async_limiter(key: Hashable, /, *, rate: float = 1.0) -> AsyncLimiter:
15
+ """Get a loop-aware rate limiter."""
16
+ id_ = id(get_running_loop())
17
+ full = (id_, key)
18
+ try:
19
+ return _LIMITERS[full]
20
+ except KeyError:
21
+ limiter = _LIMITERS[full] = AsyncLimiter(1.0, time_period=rate)
22
+ return limiter
23
+
24
+
25
+ __all__ = ["get_async_limiter"]