{"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":"python","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,"search_vec":"'6.5.1':70 'activ':44 'anyio':35,75 'architectur':62 'async':2,9,72 'asyncio':38,73 'bug':55 'built':30 'client':4,15,76 'cluster':22 'concurr':33 'coredi':1,5 'current':67 'fast':8 'featur':59 'fix':56 'frequent':47 'fulli':12 'fully-typ':11 'librari':42 'maintain':45 'major':61 'minor':58 'modul':27 'month':53 'multipl':50 'offer':18 'often':49 'period':65 'python':17 'redi':3,14,21,26,71 'releas':48,64 'rewrit':63 'sentinel':23 'structur':32 'support':19,36 'time':51 'trio':40,74 'type':13,77 'use':34 'various':25 'version':68","created_at":"2026-04-12T03:34:11.950154+00:00","updated_at":"2026-04-16T03:51:08.893823+00:00","problems":[{"fix":"Ensure you have the latest stable version of coredis installed. Upgrade using `pip install --upgrade coredis`.","cause":"This error typically occurred in older versions of coredis (e.g., v3.0.0) due to a packaging issue where the 'response' directory was missing from the installed package.","error":"ModuleNotFoundError: No module named 'coredis.response'"},{"fix":"Provide the full hostname/endpoint when configuring the SSL connection. For example, `coredis.Redis(host='your-endpoint.redis.cache.amazonaws.com', port=6380, ssl=True, server_hostname='your-endpoint.redis.cache.amazonaws.com', password='your_password')`. Ensure no unescaped special characters like '#' are in the password if using a URI.","cause":"This error occurs when attempting to establish an SSL/TLS connection to Redis using coredis without specifying the `server_hostname` in the connection parameters, often with services like AWS ElastiCache. It can also be caused by incorrect connection string parsing due to special characters in the password.","error":"coredis.exceptions.ConnectionError: You must set server_hostname when using ssl without a host"},{"fix":"Verify that the Redis Cluster nodes are running and reachable from the client, and that the provided host/port configurations are correct. Ensure your Redis Cluster version is 6.x or newer, or explicitly configure `protocol_version=2` if using Redis 5.x. Check firewall rules and network connectivity. For `coredis` v6.2.0 and later, the base exception name is `coredis.exceptions.RedisClusterError` (an alias for older `RedisClusterException` is maintained).","cause":"This exception is raised when the coredis `RedisCluster` client cannot discover or connect to any of the provided startup nodes, or if the Redis Cluster is not healthy (e.g., 'CLUSTERDOWN'). It can also occur if the Redis cluster version is too old and does not support the HELLO command (e.g., Redis 5.x with coredis defaults).","error":"coredis.exceptions.RedisClusterError: Redis Cluster cannot be connected. Please provide at least one reachable node."},{"fix":"Ensure the `password` (and `username` if using Redis ACLs) provided during client initialization matches the configuration of your Redis server. Example: `client = coredis.Redis(host='localhost', port=6379, password='correct_password')`.","cause":"This error is raised when authentication parameters were provided to the Redis client but they were invalid, such as an incorrect password or ACL user.","error":"coredis.exceptions.AuthenticationFailureError"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"6.8.0","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/alisaifee/coredis","docs":"https://coredis.readthedocs.org","changelog":"https://github.com/alisaifee/coredis/releases","pypi":"https://pypi.org/project/coredis/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["database","http-networking","serialization"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-29","next_check":"2026-07-28","install_tag":null}}