Project History¶
coredis is a fork of the excellent aredis client developed and maintained by Jason Chen.
aredis already had support for cluster & sentinel and was one of the best
performing async python clients. Since it had become unmaintained as of October 2020
The initial intention of the fork was add python 3.10 compatibility and
v2.0.0 was drop-in backward compatible
with aredis and addd support up to python 3.10.
Version v6.0.0rc1 was a large scale refactor that replaced all internal async task
management and io with anyio (contributed by Graeme Holliday) This essentially
enables the library to be used with trio.
Divergence from aredis & redis-py¶
Versions v3.0.0 and above no longer maintain compatibility with aredis. Since aredis mostly mirrored the redis client, this inherently means that coredis diverges from both, most notable (at the time of writing) in the following general categories:
API signatures for redis commands that take variable length arguments are only variadic if they are optional, for example
coredis.Redis.delete()takes a variable number of keys however, they are not optional. Thus the signature expects a collection of keys as the only positional argument- Redis.delete(keys: Parameters[KeyT]) CommandRequest[int]
Delete one or more keys.
- Parameters:
keys¶ – One or more key names to delete.
- Returns:
The number of keys that were removed.
Redis command documentation: CommandName.DEL
Redis commands that accept tokens for controlling behavior now use
PureTokenand the coredis methods mirroring the commands useLiteralto document the acceptable values. An example of this iscoredis.Redis.expire().- Redis.expire(key: KeyT, seconds: int | timedelta, condition: Literal[PureToken.NX, PureToken.XX, PureToken.GT, PureToken.LT] | None = None) CommandRequest[bool]
Set a key’s time to live in seconds.
- Parameters:
- Returns:
Trueif the timeout was set,Falseotherwise (e.g. key does not exist).
Redis command documentation: CommandName.EXPIRE
Compatibility:
condition: New in Redis version: 7.0.0
Since v3.0.0 building an async redis client with strict type hints for all APIs has been one of the primary goals of the project. As of v5.0.0 all clients (including pipelines) were correctly statically typed and the use of type stubs was completely eliminated.
As of v5.0.0 all core redis command methods exposed by the Clients were changed from coroutines to regular methods that return
CommandRequestobjects which are of typeAwaitable.coredis takes a significantly different approach to connection pooling than redis &
aredisto optimize performance in an async context. In the simplest terms, the connection pool will only grow beyond1connection per target server (cluster connection pools maintain sub pools for every node in the cluster) if the connection has been acquired in a blocking request. For all non blocking requests coredis will pipeline concurrent requests on the same connection which will get resolved asynchronously. This significantly reduces the connection cost and inherently improves performance.coredis almost always tries to provide a simply pythonic
1:1mapping of command parameters from the redis specification which means that higher level abstractions are rarely provided. This is signficantly different from the approach redis takes, especially with respect to Redis Modules support. See the RediSearchsearch()method as an example. For complex patterns such as Pub/Sub, Pipelining and Streams however, light abstractions are provided. See Handbook for more details.
Default RESP3¶
v3.0.0 supported selecting the protocol version to use when parsing responses
from the redis server and defaulted to the legacy RESP protocol. Since coredis has dropped
support for redis server versions below 6.0 the default protocol version is now RESP3.
Parsers¶
coredis versions 2.x and 3.x would default to a hiredis based parser if the
dependency was available. This behavior was inherited from aredis which inherited it from
redis. Though hiredis does provide a significant speedup when parsing responses
for large nested bulk responses, coredis has made sufficient improvements in performance
including using mypyc to provide a native speedup when possible and therefore
no longer supports multiple parser implementations and always uses coredis.parser.Parser.