{"id":156,"library":"redis","title":"redis-py","description":"Official Python client for Redis. Install is 'redis', import is 'redis'. Current version: 7.4.0 (Mar 2026). aioredis was merged into redis-py 4.2+ — use 'redis.asyncio' for async, not separate aioredis package. By default all responses are bytes — set decode_responses=True for strings. StrictRedis renamed to Redis in v3 but alias still works.","status":"active","version":"7.4.0","language":"python","source_language":"en","source_url":"https://github.com/redis/redis-py","tags":["redis","python","cache","database","async","aioredis"],"install":[{"cmd":"pip install redis","lang":"bash","label":"Python (sync + async)"},{"cmd":"pip install 'redis[hiredis]'","lang":"bash","label":"Python (with hiredis parser — faster)"}],"dependencies":[{"reason":"Optional C parser for better performance. Install via redis[hiredis].","package":"hiredis","optional":true}],"imports":[{"note":"decode_responses defaults to False. Without it get() returns bytes (b'value') not str ('value'). This silently breaks string comparisons throughout your code.","wrong":"import redis\nr = redis.Redis(host='localhost')\nprint(r.get('key'))  # returns b'value' — bytes not str","symbol":"Redis (sync)","correct":"import redis\n\nr = redis.Redis(\n    host='localhost',\n    port=6379,\n    db=0,\n    decode_responses=True  # returns str not bytes\n)\nr.set('key', 'value')\nprint(r.get('key'))  # 'value' not b'value'"},{"note":"aioredis separate package is abandoned. Use 'import redis.asyncio as aioredis' from redis >= 4.2. aioredis PyPI package last release 2021.","wrong":"import aioredis  # separate package — abandoned\nr = await aioredis.create_redis_pool('redis://localhost')","symbol":"redis.asyncio (async)","correct":"import redis.asyncio as aioredis\nimport asyncio\n\nasync def main():\n    r = aioredis.Redis(\n        host='localhost',\n        port=6379,\n        decode_responses=True\n    )\n    await r.set('key', 'value')\n    print(await r.get('key'))\n    await r.aclose()\n\nasyncio.run(main())"},{"note":"SSL connections use 'rediss://' (double s) not 'redis://'. from_url also defaults to decode_responses=False.","wrong":"import redis\nr = redis.from_url('redis://localhost')  # missing decode_responses","symbol":"from_url","correct":"import redis\n\n# Standard Redis URL\nr = redis.from_url('redis://localhost:6379/0', decode_responses=True)\n\n# Redis with password\nr = redis.from_url('redis://:password@localhost:6379/0')\n\n# SSL/TLS (Upstash, Redis Cloud)\nr = redis.from_url('rediss://user:pass@host:6380/0')"}],"quickstart":{"code":"# pip install redis\nimport redis\n\nr = redis.Redis(\n    host='localhost',\n    port=6379,\n    db=0,\n    decode_responses=True  # str not bytes\n)\n\n# Basic operations\nr.set('name', 'Alice')\nprint(r.get('name'))  # 'Alice'\n\n# Expiry\nr.setex('session', 3600, 'token123')  # TTL 1 hour\n\n# Hash\nr.hset('user:1', mapping={'name': 'Alice', 'age': '30'})\nprint(r.hgetall('user:1'))  # {'name': 'Alice', 'age': '30'}\n\n# List\nr.lpush('queue', 'task1', 'task2')\nprint(r.lrange('queue', 0, -1))\n\nr.close()","lang":"python","description":"Minimal redis-py 7.x sync operations with decode_responses."},"warnings":[{"fix":"Always pass decode_responses=True unless you specifically need bytes: Redis(host='localhost', decode_responses=True)","message":"decode_responses defaults to False. All values returned as bytes (b'value') not strings. Silently breaks string comparisons, JSON parsing, and any code expecting str.","severity":"gotcha","affected_versions":"all"},{"fix":"Replace 'import aioredis' with 'import redis.asyncio as aioredis'. API is compatible.","message":"aioredis separate package is abandoned (last release 2021). 'import aioredis' still installs but is dead. Use 'import redis.asyncio as aioredis' from redis >= 4.2.","severity":"breaking","affected_versions":">= 4.2"},{"fix":"redis.from_url('rediss://host:6380') for TLS. 'redis://' is plaintext.","message":"SSL connections require 'rediss://' (double s) URL scheme, not 'redis://'. Using wrong scheme silently connects without TLS or raises ConnectionError.","severity":"gotcha","affected_versions":"all"},{"fix":"r = redis.from_url(os.environ['UPSTASH_REDIS_URL'], decode_responses=True) — Upstash provides rediss:// URLs automatically.","message":"Upstash Redis requires TLS — always use rediss:// with Upstash URLs. Using redis:// with Upstash raises ConnectionError.","severity":"gotcha","affected_versions":"all"},{"fix":"from redis import Redis not StrictRedis","message":"StrictRedis renamed to Redis in v3. StrictRedis still works as an alias but generates confusion in docs. Use Redis directly.","severity":"gotcha","affected_versions":">= 3.0"},{"fix":"Create one Redis client at app startup and reuse it. Only close on app shutdown.","message":"Connection pool is shared by default. Do not call r.close() in web request handlers — it closes the pool. Use aclose() in async or let the pool manage connections.","severity":"gotcha","affected_versions":"all"},{"fix":"r.zadd('leaderboard', {'player1': 100.0})","message":"ZADD argument order changed in v3. Old: zadd(name, member, score). New: zadd(name, {member: score}). Old order raises TypeError silently or produces wrong results.","severity":"gotcha","affected_versions":">= 3.0"},{"fix":"Ensure the Redis server is running and accessible from where the client is executing. Check firewall rules, network configuration, and that the Redis server is listening on the expected host/port.","message":"Connection refused. This usually means the Redis server is not running or is not accessible at the specified host and port.","severity":"breaking","affected_versions":"all"},{"fix":"Ensure the Redis server is running and accessible at the specified host and port (default: localhost:6379). Check firewall rules if connecting remotely.","message":"The client failed to connect to the Redis server because the connection was refused. This typically means the Redis server is not running, is not listening on the specified host/port, or a firewall is blocking the connection.","severity":"breaking","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T09:06:48.001Z","next_check":"2026-06-24T00:00:00.000Z","problems":[{"fix":"Ensure you have 'redis' version 4.2.0 or higher installed and import using 'import redis.asyncio as redis'.","cause":"The 'redis.asyncio' module is not found, possibly due to an outdated 'redis' package or incorrect import.","error":"ModuleNotFoundError: No module named 'redis.asyncio'"},{"fix":"Upgrade the 'redis' package to version 4.2.0 or higher using 'pip install --upgrade redis'.","cause":"The 'redis' package version is below 4.2.0, which does not include the 'asyncio' module.","error":"AttributeError: module 'redis' has no attribute 'asyncio'"},{"fix":"Use 'aioredis.from_url' instead of 'create_redis' to establish a connection.","cause":"The 'create_redis' method was removed in 'aioredis' version 2.0.0.","error":"AttributeError: module 'aioredis' has no attribute 'create_redis'"},{"fix":"Ensure you are using the correct version of 'aioredis' and refer to the updated documentation for the correct usage of 'pubsub'.","cause":"The 'pubsub' method is not available in the 'Redis' object due to incorrect usage or version incompatibility.","error":"AttributeError: 'Redis' object has no attribute 'pubsub'"},{"fix":"Update your code to use 'from redis import Redis' instead of accessing 'redis.client' directly.","cause":"The 'redis' package structure has changed, and the 'client' module is no longer directly accessible.","error":"AttributeError: module 'redis' has no attribute 'client'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"hiredis","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.32,"mem_mb":10.3,"disk_size":"22.0M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.32,"mem_mb":10.3,"disk_size":"21.6M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"hiredis","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.23,"mem_mb":10.3,"disk_size":"23M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.22,"mem_mb":10.3,"disk_size":"22M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"hiredis","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.43,"mem_mb":11.9,"disk_size":"24.5M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.43,"mem_mb":11.9,"disk_size":"24.1M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"hiredis","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.35,"mem_mb":11.9,"disk_size":"25M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.38,"mem_mb":11.9,"disk_size":"25M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"hiredis","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.63,"mem_mb":11.9,"disk_size":"16.2M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.6,"mem_mb":11.9,"disk_size":"15.8M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"hiredis","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.59,"mem_mb":11.9,"disk_size":"17M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.63,"mem_mb":11.9,"disk_size":"16M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"hiredis","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.58,"mem_mb":12,"disk_size":"15.8M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.62,"mem_mb":12,"disk_size":"15.4M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"hiredis","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.55,"mem_mb":12,"disk_size":"16M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.55,"mem_mb":12,"disk_size":"16M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"hiredis","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.28,"mem_mb":9.7,"disk_size":"20.9M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.27,"mem_mb":9.7,"disk_size":"20.5M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"hiredis","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.23,"mem_mb":9.7,"disk_size":"21M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.23,"mem_mb":9.7,"disk_size":"21M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}