{"id":3941,"library":"coredis","title":"coredis: Async Redis Client","description":"coredis is a fast, async, and fully-typed Redis client for Python, offering support for Redis Cluster, Sentinel, and various Redis modules. It is built with structured concurrency using `anyio`, supporting both `asyncio` and `trio`. The library is actively maintained with frequent releases, often multiple times a month for bug fixes and minor features, with major architectural rewrites released periodically. The current version is 6.5.1.","status":"active","version":"6.5.1","language":"en","source_language":"en","source_url":"https://github.com/alisaifee/coredis","tags":["redis","async","asyncio","trio","anyio","client","typed"],"install":[{"cmd":"pip install coredis","lang":"bash","label":"Install coredis"}],"dependencies":[{"reason":"Core dependency for structured concurrency and async backend support (asyncio/trio).","package":"anyio","optional":false},{"reason":"Optional dependency for runtime type validation, enabled via COREDIS_RUNTIME_CHECKS environment variable.","package":"beartype","optional":true}],"imports":[{"symbol":"Redis","correct":"from coredis import Redis"},{"symbol":"RedisCluster","correct":"from coredis import RedisCluster"},{"symbol":"Sentinel","correct":"from coredis import Sentinel"},{"note":"Used for specifying startup nodes for RedisCluster.","symbol":"TCPLocation","correct":"from coredis.connection import TCPLocation"},{"note":"Prior to v6.0.0rc3, these patterns were directly under `coredis` or `coredis.commands`. They were moved to `coredis.patterns`.","wrong":"from coredis import Pipeline","symbol":"Pipeline, PubSub, Lock, Streams, Cache","correct":"from coredis.patterns import Pipeline, PubSub"}],"quickstart":{"code":"import anyio\nimport coredis\nimport os\n\nasync def main() -> None:\n    # Connect to Redis. Use a URL from an environment variable or default to localhost\n    redis_url = os.environ.get('COREDIS_URL', 'redis://localhost:6379/0')\n    # Optionally, decode responses to get Python strings instead of bytes\n    client = coredis.Redis.from_url(redis_url, decode_responses=True)\n\n    async with client:\n        # Clear the database (use with caution in production!)\n        print(f\"Flushing database...\")\n        await client.flushdb()\n\n        # Basic SET and GET operations\n        print(f\"Setting 'mykey' to 'hello'\")\n        await client.set(\"mykey\", \"hello\")\n        value = await client.get(\"mykey\")\n        print(f\"Value of 'mykey': {value}\")\n        assert value == \"hello\"\n\n        # Increment a numerical value\n        print(f\"Incrementing 'counter'\")\n        await client.set(\"counter\", 1)\n        assert await client.incr(\"counter\") == 2\n        print(f\"Value of 'counter' after increment: {await client.get('counter')}\")\n\n        # Using a pipeline for multiple commands in a single round trip\n        print(\"Running a pipeline...\")\n        async with client.pipeline() as pipeline:\n            pipeline.incr(\"pipeline_counter\")\n            pipeline.get(\"pipeline_counter\")\n            pipeline.delete([\"pipeline_counter\"])\n            results = await pipeline.execute()\n            print(f\"Pipeline results: {results}\") # Expected: [1, '1', 1] (if decode_responses=True)\n\nif __name__ == \"__main__\":\n    # coredis uses anyio, supporting asyncio and trio. Specify your preferred backend.\n    anyio.run(main, backend=\"asyncio\")\n","lang":"python","description":"This quickstart demonstrates connecting to a single Redis instance, performing basic `SET`, `GET`, `INCR` operations, and using a command pipeline. It leverages `anyio.run` to execute the asynchronous code and uses `os.environ.get` for flexible Redis URL configuration."},"warnings":[{"fix":"Refer to the official 'Migrating from 5.x to 6.0' guide in the coredis documentation for detailed upgrade instructions. Update your async code to follow `anyio`'s structured concurrency patterns, typically using `async with client:` for resource management.","message":"Version 6.0.0 introduced a major architectural rewrite, migrating the entire library to `anyio` for structured concurrency, supporting both `asyncio` and `trio`. This requires significant changes to existing applications built on 5.x, especially regarding connection management and asynchronous patterns.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"Update your import statements to reflect the new `coredis.patterns` module path. For example, `from coredis.pipeline import Pipeline` becomes `from coredis.patterns import Pipeline`.","message":"Several submodules for application patterns (e.g., Pub/Sub, Pipeline, Stream, Cache, Lock) were moved from `coredis.commands.*` or directly under `coredis` to `coredis.patterns` in version 6.0.0rc3.","severity":"breaking","affected_versions":">=6.0.0rc3"},{"fix":"Upgrade to coredis version 6.5.1 or newer to fix this regression.","message":"Version 6.5.0 introduced a regression where batch request cancellations were suppressed, potentially leading to unexpected behavior in certain scenarios.","severity":"gotcha","affected_versions":"6.5.0"},{"fix":"Upgrade to coredis version 6.2.0 or newer to ensure proper connection pool task group cleanup and recovery from initialization errors.","message":"In versions prior to 6.2.0, if `__aenter__` failed during connection pool initialization, the connection pool could become unusable as its counter would be stuck.","severity":"gotcha","affected_versions":"<6.2.0"},{"fix":"Upgrade to coredis version 6.1.0 or newer to resolve this issue and ensure correct connection capacity limiting.","message":"In versions prior to 6.1.0, there was an incorrect initialization of the connection capacity limiter, leading to a module-level shared capacity limiter instead of an instance-specific one.","severity":"gotcha","affected_versions":"<6.1.0"},{"fix":"Upgrade to coredis version 5.7.0 or newer. Ensure the URL contains credentials (e.g., `redis://user:password@host:port`) or pass them explicitly and correctly.","message":"In versions prior to 5.7.0, username and password provided as keyword arguments to `from_url` might not have been correctly used if no credentials were found within the URL string itself.","severity":"gotcha","affected_versions":"<5.7.0"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}