{"id":2567,"library":"libvalkey","title":"libvalkey","description":"libvalkey-py is a Python extension that wraps the protocol parsing code from the underlying libvalkey C library. It primarily speeds up the parsing of multi bulk replies from a Valkey server. The library is actively maintained, with its current version being 4.0.1, and releases occurring regularly to introduce new features, improvements, and bug fixes.","status":"active","version":"4.0.1","language":"en","source_language":"en","source_url":"https://github.com/valkey-io/libvalkey-py","tags":["valkey","redis","parser","performance","serialization"],"install":[{"cmd":"pip install libvalkey","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Required for building from source; typically pre-compiled wheels are available.","package":"python3-dev","optional":true},{"reason":"Required for building from source; typically pre-compiled wheels are available.","package":"gcc","optional":true}],"imports":[{"note":"The library was renamed from `hiredis-py` to `libvalkey-py` in version 3.0.0. Direct imports of `hiredis` will fail in `libvalkey-py` versions 3.0.0 and above.","wrong":"import hiredis","symbol":"Reader","correct":"from libvalkey import Reader"}],"quickstart":{"code":"import libvalkey\n\n# The Reader class is responsible for parsing replies from a stream of data.\n# It does not handle I/O itself.\nreader = libvalkey.Reader()\n\n# Feed raw Valkey protocol bytes to the reader\nreader.feed(b\"$5\\r\\nhello\\r\\n\")\n\n# Retrieve the parsed reply\nreply = reader.gets()\nprint(f\"Parsed reply: {reply}\")\n\n# Example with a list reply\nreader.feed(b\"*2\\r\\n$5\\r\\nhello\\r\\n$5\\r\\nworld\\r\\n\")\nlist_reply = reader.gets()\nprint(f\"Parsed list reply: {list_reply}\")\n\n# Example with custom sentinel for 'not enough data'\nreader_ellipsis = libvalkey.Reader(notEnoughData=Ellipsis)\nreader_ellipsis.feed(b\"*2\\r\\n$5\\r\\nhello\\r\\n\")\npartial_reply = reader_ellipsis.gets()\nprint(f\"Partial reply (needs more data): {partial_reply}\")\nreader_ellipsis.feed(b\"$5\\r\\nworld\\r\\n\")\nfull_reply = reader_ellipsis.gets()\nprint(f\"Full reply: {full_reply}\")","lang":"python","description":"The quickstart demonstrates how to initialize the `Reader` class, feed raw Valkey protocol bytes, and retrieve parsed replies. It also shows how to handle cases where insufficient data is fed, using a custom sentinel value."},"warnings":[{"fix":"Change `import hiredis` to `import libvalkey` and update any references to `hiredis.Reader` to `libvalkey.Reader`.","message":"The library was renamed from `hiredis-py` to `libvalkey-py` in version 3.0.0. All `hiredis` imports must be updated to `libvalkey`.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Ensure `python3-dev` and `gcc` (or equivalent build tools for your OS) are installed before attempting `pip install libvalkey` if pre-built wheels are not available. For example, `sudo apt-get install python3-dev gcc` on Debian/Ubuntu.","message":"Building `libvalkey` from source (e.g., if a pre-compiled wheel is not available for your environment) requires Python development headers (e.g., `python3-dev` on Debian/Ubuntu) and a C compiler like `gcc`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Explicitly check the return value of `reader.gets()` for instances of `libvalkey.ReplyError` if you want to handle server-generated errors. For example: `reply = reader.gets(); if isinstance(reply, libvalkey.ReplyError): handle_error(reply)`.","message":"For error handling, `libvalkey.ProtocolError` is raised for invalid protocol states. However, `libvalkey.ReplyError` (for server-side error replies like `-ERR`) is *returned* by `gets()` and not raised as an exception by default.","severity":"gotcha","affected_versions":"All versions"},{"fix":"To handle decoding errors gracefully, initialize the `Reader` with a different `errors` handler, such as 'ignore', 'replace', or 'backslashreplace' (e.g., `libvalkey.Reader(encoding='utf-8', errors='replace')`).","message":"When `libvalkey.Reader` is initialized with an `encoding` (e.g., 'utf-8'), bulk string replies are decoded. If the decoding fails and the `errors` parameter is set to 'strict' (the default), a `UnicodeDecodeError` will be raised.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Thoroughly test existing code relying on `Reader` behavior when upgrading to v4.0.0 or later to ensure parsing logic remains consistent with expectations. Refer to the GitHub releases for specific changes.","message":"Version 4.0.0 included changes to the `Reader`'s behavior, with a subsequent patch (v4.0.0b1) to 'partly restore the previous behaviour'. Users upgrading to or through v4.0.0 should review the changelog carefully for potential subtle changes in parsing logic.","severity":"breaking","affected_versions":"4.0.0, 4.0.0b1+"}],"env_vars":null,"last_verified":"2026-04-10T00:00:00.000Z","next_check":"2026-07-09T00:00:00.000Z"}