{"id":513,"library":"hyperframe","title":"Pure-Python HTTP/2 framing","description":"hyperframe is a pure-Python library providing the HTTP/2 framing code used in the hyper project. It allows for creating, serializing, and parsing HTTP/2 frames from a binary stream. The current version is 6.1.0, and it is actively maintained as part of the python-hyper organization.","status":"active","version":"6.1.0","language":"python","source_language":"en","source_url":"https://github.com/python-hyper/hyperframe/","tags":["http/2","framing","networking","pure-python","binary-protocol"],"install":[{"cmd":"pip install hyperframe","lang":"bash","label":"Install hyperframe"}],"dependencies":[{"reason":"hyperframe is explicitly designed to have no external dependencies.","package":"None","optional":false}],"imports":[{"note":"The primary classes for frames are within the 'hyperframe.frame' submodule.","symbol":"Frame","correct":"from hyperframe.frame import Frame"},{"note":"Specific frame types like DataFrame are directly importable from 'hyperframe.frame'.","symbol":"DataFrame","correct":"from hyperframe.frame import DataFrame"},{"note":"Custom exceptions are located in the 'hyperframe.exceptions' submodule.","symbol":"HyperframeError","correct":"from hyperframe.exceptions import HyperframeError"}],"quickstart":{"code":"from hyperframe.frame import DataFrame, Frame\n\n# Create a DATA frame\nf = DataFrame(stream_id=5)\nf.data = b'some binary data'\nf.flags.add('END_STREAM')\nf.flags.add('PADDED')\nf.padding_length = 30\n\n# Serialize the frame\ndata = f.serialize()\nprint(f\"Serialized frame: {data.hex()}\")\n\n# Parse a frame header from binary data\nheader_bytes = data[:9] # HTTP/2 frame headers are 9 bytes\nparsed_frame_header, length = Frame.parse_frame_header(memoryview(header_bytes))\nprint(f\"Parsed frame type: {type(parsed_frame_header).__name__}, Stream ID: {parsed_frame_header.stream_id}, Length to read: {length}\")\n\n# Parse the frame body\nbody_bytes = data[9:9 + length]\nparsed_frame_header.parse_body(memoryview(body_bytes))\nprint(f\"Parsed frame flags: {parsed_frame_header.flags}, Data: {parsed_frame_header.data}\")\n","lang":"python","description":"This example demonstrates creating a `DataFrame`, adding data and flags, serializing it, and then parsing the header and body of a frame from raw bytes. It showcases the basic workflow for working with HTTP/2 frames. Note the use of `memoryview` for efficient binary data handling during parsing."},"warnings":[{"fix":"Catch `HyperframeError` or more specific `hyperframe.exceptions` instead of `ValueError` for frame-related errors.","message":"In version 6.0.0, the base class for `InvalidPaddingError` and `InvalidFrameError` exceptions changed from `ValueError` to `HyperframeError`. `HyperframeError` was introduced as the new base class for all exceptions in the module.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"Inspect the type of the parsed frame; if it's an `ExtensionFrame`, process its `frame_type` and `data` attributes or ignore it as appropriate.","message":"Starting with version 5.0.0, `hyperframe` no longer raises an exception for unknown frame types. Instead, it wraps them in an `ExtensionFrame` object. This means code expecting exceptions for unknown frames will need to handle `ExtensionFrame` instead.","severity":"gotcha","affected_versions":">=5.0.0"},{"fix":"Always convert binary data to `memoryview` before passing it to parsing methods, e.g., `memoryview(my_bytes_object)`.","message":"The `parse_body` and `parse_frame_header` methods expect `memoryview` objects for performance reasons. Passing raw `bytes` or `bytearray` directly might work in some contexts but is not the intended or most efficient usage.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-12T14:32:00.528Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Install the 'hyperframe' package using pip: `pip install hyperframe`","cause":"The 'hyperframe' library is not installed in your Python environment or the environment where your code is being executed.","error":"ModuleNotFoundError: No module named 'hyperframe'"},{"fix":"Ensure the input data stream contains valid HTTP/2 frames. If you are intentionally working with extension frames, handle them using `hyperframe.frame.ExtensionFrame` or by passing `strict=False` to parsing functions if applicable, and then inspect the `frame.type` attribute.","cause":"This error occurs when the 'hyperframe' library receives or attempts to parse an HTTP/2 frame with a type byte that it does not recognize, which can happen with custom frames or malformed data.","error":"hyperframe.exceptions.UnknownFrameError"},{"fix":"Verify that the incoming HTTP/2 frame data is correctly formed according to the HTTP/2 specification, especially regarding padding length. If you are creating frames, ensure the `pad_length` (or deprecated `total_padding`) parameter is valid for the frame's body size.","cause":"This exception is raised when parsing a padded HTTP/2 frame (like DATA, HEADERS, or PUSH_PROMISE) where the padding length specified in the frame header is invalid or exceeds the frame's body length.","error":"hyperframe.exceptions.InvalidPaddingError"},{"fix":"Inspect the specific frame and its attributes that triggered the `InvalidDataError`. Correct the stream ID, flag combinations, or data fields to conform to the HTTP/2 specification for that frame type. For example, DATA frames cannot have a stream ID of 0.","cause":"This error, introduced in hyperframe 6.0.0, indicates that a frame's data content or specific fields violate HTTP/2 specification rules, such as an invalid stream ID for a frame type (e.g., DATA frame with stream ID 0) or malformed SETTINGS/ALTSVC frames.","error":"hyperframe.exceptions.InvalidDataError"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"cli_name":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":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"17.9M"},{"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.01,"mem_mb":0.6,"disk_size":"18M"},{"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.03,"mem_mb":0.8,"disk_size":"19.7M"},{"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.02,"mem_mb":0.8,"disk_size":"20M"},{"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.03,"mem_mb":0.7,"disk_size":"11.6M"},{"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.03,"mem_mb":0.7,"disk_size":"12M"},{"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.01,"mem_mb":0.8,"disk_size":"11.2M"},{"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.01,"mem_mb":0.6,"disk_size":"12M"},{"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.01,"mem_mb":0.6,"disk_size":"17.4M"},{"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.01,"mem_mb":0.6,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}