A bucket is a client aimed utility to aid concurrency and
ratelimit combinations, it is also async context manager
syntatic sugar over
- class uprate.bucket.Bucket(rate: Rate | RateGroup, store: BaseStore[T] = None, concurrency: int = 0)¶
A high level ratelimit construct to obey both ratelimits and concurrency.
Unlike other constructs in uprate,
Bucketdoes not have a sync counterpart for threaded applications, a sync counterpart maybe added with enough interest.
int) – The number of concurrently executing acquires/context managers. If
0or lower then only the ratelimit is enforced. By default,
- classmethod from_limit(limit: uprate.ratelimit.RateLimit[uprate.bucket.T]) uprate.bucket.Bucket[uprate.bucket.T] ¶
Create a bucket from a
- acquire(key: uprate.bucket.T) uprate.bucket.BucketCM[uprate.bucket.T] ¶
Return an async context manager which tries to acquire a usage token upon entering while respecting the concurrency limit.
T) – The key to acquire.
The async context manager for the key.
- Return type
bucket: Bucket[str] = Bucket(30 / Seconds(1), concurrency=1) ... # Wait until concurrency and ratelimit are satisfied. async with bucket.acquire("key"): ...
- async reset(key: Optional[uprate.bucket.T] = None) None ¶
Reset the given key.
import uprate as up import asyncio async def worker(id: int, bucket: up.Bucket[str]): async with bucket.acquire("GLOBAL_KEY"): # Lower the id longer the sleep await asyncio.sleep(0.4 + (4 - id)/100) print("hello from ", id) async def main(): # Bucket uses a queue so during creation a running loop must be present. bucket = up.Bucket[str](2 / up.Seconds(1), concurrency=2) await asyncio.gather(*(asyncio.create_task(worker(i, bucket)) for i in range(5))) asyncio.run(main()) # Output: # hello from 1 # hello from 0 # hello from 3 # hello from 2 # hello from 4