Package: aiokeydb
aiokeydbLatest Version:Unified Syncronous and Asyncronous Python client forKeyDBandRedis.It implements the majority ofredis-pyAPI methods and is fully compatible withredis-pyAPI methods, while also providing a unified Client for bothsyncandasyncmethods.Additionally, newer apis such asKeyDBClientare strongly typed to provide a more robust experience.Usageaiokeydbcan be installed frompypiusingpipor from source.Installation# Install from pypipipinstallaiokeydb# Install from sourcepipinstallgit+https://github.com/trisongz/aiokeydb-py.gitExamplesBelow are some examples of how to useaiokeydb. Additional examples can be found in thetestsdirectory.importtimeimportasyncioimportuuidfromaiokeydbimportKeyDBClient# The session can be explicitly initialized, or# will be lazily initialized on first use# through environment variables with all# params being prefixed with `KEYDB_`keydb_uri="keydb://localhost:6379/0"# Initialize the Unified ClientKeyDBClient.init_session(uri=keydb_uri,)# Cache the results of these functions# cachify works for both sync and async functions# and has many params to customize the caching behavior# and supports both `redis` and `keydb` backends# as well as `api` frameworks such as `fastapi` and `starlette`@KeyDBClient.cachify()asyncdefasync_fibonacci(number:int):ifnumber==0:return0elifnumber==1:return1returnawaitasync_fibonacci(number-1)+awaitasync_fibonacci(number-2)@KeyDBClient.cachify()deffibonacci(number:int):ifnumber==0:return0elifnumber==1:return1returnfibonacci(number-1)+fibonacci(number-2)asyncdeftest_fib(n:int=100,runs:int=10):# Test that both results are the same.sync_t,async_t=0.0,0.0foriinrange(runs):t=time.time()print(f'[Async -{i}/{runs}] Fib Result:{awaitasync_fibonacci(n)}')tt=time.time()-tprint(f'[Async -{i}/{runs}] Fib Time:{tt:.2f}s')async_t+=ttt=time.time()print(f'[Sync  -{i}/{runs}] Fib Result:{fibonacci(n)}')tt=time.time()-tprint(f'[Sync  -{i}/{runs}] Fib Time:{tt:.2f}s')sync_t+=ttprint(f'[Async] Cache Average Time:{async_t/runs:.2f}s | Total Time:{async_t:.2f}s')print(f'[Sync ] Cache Average Time:{sync_t/runs:.2f}s | Total Time:{sync_t:.2f}s')asyncdeftest_setget(runs:int=10):# By default, the client utilizes `pickle` to serialize# and deserialize objects. This can be changed by setting# the `serializer`sync_t,async_t=0.0,0.0foriinrange(runs):value=str(uuid.uuid4())key=f'async-test-{i}'t=time.time()awaitKeyDBClient.async_set(key,value)assertawaitKeyDBClient.async_get(key)==valuett=time.time()-tprint(f'[Async -{i}/{runs}] Get/Set:{key}->{value}={tt:.2f}s')async_t+=ttvalue=str(uuid.uuid4())key=f'sync-test-{i}'t=time.time()KeyDBClient.set(key,value)assertKeyDBClient.get(key)==valuett=time.time()-tprint(f'[Sync  -{i}/{runs}] Get/Set:{key}->{value}={tt:.2f}s')sync_t+=ttprint(f'[Async] GetSet Average Time:{async_t/runs:.2f}s | Total Time:{async_t:.2f}s')print(f'[Sync ] GetSet Average Time:{sync_t/runs:.2f}s | Total Time:{sync_t:.2f}s')asyncdefrun_tests(fib_n:int=100,fib_runs:int=10,setget_runs:int=10):# You can explicitly wait for the client to be ready# Sync version# KeyDBClient.wait_for_ready()awaitKeyDBClient.async_wait_for_ready()# Run the testsawaittest_fib(n=fib_n,runs=fib_runs)awaittest_setget(runs=setget_runs)# Utilize the current sessionawaitKeyDBClient.async_set('async_test_0','test')assertawaitKeyDBClient.async_get('async_test_0')=='test'KeyDBClient.set('sync_test_0','test')assertKeyDBClient.get('sync_test_0')=='test'# you can access the `KeyDBSession` object directly# which mirrors the APIs in `KeyDBClient`awaitKeyDBClient.session.async_set('async_test_1','test')assertawaitKeyDBClient.session.async_get('async_test_1')=='test'KeyDBClient.session.set('sync_test_1','test')assertKeyDBClient.session.get('sync_test_1')=='test'# The underlying client can be accessed directly# if the desired api methods aren't mirrored# KeyDBClient.keydb# KeyDBClient.async_keydb# Since encoding / decoding is not handled by the client# you must encode / decode the data yourselfawaitKeyDBClient.async_keydb.set('async_test_2',b'test')assertawaitKeyDBClient.async_keydb.get('async_test_2')==b'test'KeyDBClient.keydb.set('sync_test_2',b'test')assertKeyDBClient.keydb.get('sync_test_2')==b'test'# You can also explicitly close the client# However, this closes the connectionpool and will terminate# all connections. This is not recommended unless you are# explicitly closing the client.# Sync version# KeyDBClient.close()awaitKeyDBClient.aclose()asyncio.run(run_tests())Additionally, you can use the previous APIs that are expected to be presentfromaiokeydbimportKeyDB,AsyncKeyDB,from_urlsync_client=KeyDB()async_client=AsyncKeyDB()# Alternative methodssync_client=from_url('keydb://localhost:6379/0')async_client=from_url('keydb://localhost:6379/0',asyncio=True)Setting the Global Client SettingsThe library is designed to be explict and not have any global state. However, you can set the global client settings by using theKeyDBClient.configuremethod. This is useful if you are using theKeyDBClientclass directly, or if you are using theKeyDBClientclass in a library that you are developing.For example, if you initialize a session with a specificuri, the global client settings will still inherit from the default settings.fromaiokeydbimportKeyDBClientfromlazyops.utilsimportloggerkeydb_uris={'default':'keydb://127.0.0.1:6379/0','cache':'keydb://localhost:6379/1','public':'redis://public.redis.db:6379/0',}sessions={}# these will now be initializedforname,uriinkeydb_uris.items():sessions[name]=KeyDBClient.init_session(name=name,uri=uri,)logger.info(f'Session{name}: uri:{sessions[name].uri}')# however if you initialize another session# it will use the global environment varssessions['test']=KeyDBClient.init_session(name='test',)logger.info(f'Session test: uri:{sessions["test"].uri}')By configuring the global settings, any downstream sessions will inherit the global settings.fromaiokeydbimportKeyDBClientfromlazyops.utilsimportloggerdefault_uri='keydb://public.host.com:6379/0'keydb_dbs={'cache':{'db_id':1,},'db':{'uri':'keydb://127.0.0.1:6379/0',},}KeyDBClient.configure(url=default_uri,debug_enabled=True,queue_db=1,)# now any sessions that are initialized will use the global settingssessions={}# these will now be initialized# Initialize the first default session# which should utilize the `default_uri`KeyDBClient.init_session()forname,configinkeydb_dbs.items():sessions[name]=KeyDBClient.init_session(name=name,**config)logger.info(f'Session{name}: uri:{sessions[name].uri}')KeyDB Worker QueuesReleased sincev0.1.1KeyDB Worker Queues is a simple, fast, and reliable queue system for KeyDB. It is designed to be used in a distributed environment, where multiple KeyDB instances are used to process jobs. It is also designed to be used in a single instance environment, where a single KeyDB instance is used to process jobs.importasynciofromaiokeydbimportKeyDBClientfromaiokeydb.queuesimportTaskQueue,Workerfromlazyops.utilsimportlogger# Configure the KeyDB Client - the default keydb client will use# db = 0, and queue uses 2 so that it doesn't conflict with other# by configuring it here, you can explicitly set the db to usekeydb_uri="keydb://127.0.0.1:6379/0"# Configure the Queue to use db = 1 instead of 2KeyDBClient.configure(url=keydb_uri,debug_enabled=True,queue_db=1,)@Worker.add_cronjob("*/1 * * * *")asyncdeftest_cron_task(*args,**kwargs):logger.info("Cron task ran")awaitasyncio.sleep(5)@Worker.add_function()asyncdeftest_task(*args,**kwargs):logger.info("Task ran")awaitasyncio.sleep(5)asyncdefrun_tests():queue=TaskQueue("test_queue")worker=Worker(queue)awaitworker.start()asyncio.run(run_tests())Requirementsdeprecated>=1.2.3packaging>=20.4importlib-metadata >= 1.0; python_version < "3.8"typing-extensions; python_version<"3.8"async-timeout>=4.0.2pydanticanyiolazyopsMajor Changes:v0.0.8->v0.0.11:Fully Migrates away fromaioredistoredis-py@v4.3.4.This inherits all API methods fromredis-pyto enforce compatability since deprecation ofaioredisgoing forwardThis fork ofredis-pyhas some modified semantics, while attempting to replicate all the API methods ofredis-pyto avoid compatibility issues with underlying libraries that require a pinnedredisversion.Notably, allasyncClasses and methods are prefixed byAsyncto avoid name collisions with thesyncversion.v0.0.11->v0.1.0:Migration ofaiokeydb.client->aiokeydb.coreandaiokeydb.asyncio.client->aiokeydb.asyncio.coreHowever these have been aliased to their original names to avoid breaking changes.Creating a unified API available through newKeyDBClientclass that createssessionswhich areKeyDBSessioninherits fromKeyDBandAsyncKeyDBClientclass that inherits fromAsyncKeyDBclass