usbpdpy
Python bindings for USB Power Delivery message parsing using the usbpd Rust crate.
Features
- Parse USB PD messages with full specification compliance
- Support for Source Capabilities and Request message parsing
- All PDO types: Fixed Supply, Battery, Variable Supply, PPS, EPR
- Complete RDO (Request Data Object) parsing with PDO state management
- Message header parsing with proper control/data message classification
- Python type hints and error handling
Installation
pip install usbpdpy
Wheels are built against the stable ABI for Linux, macOS and Windows on x86-64 and arm64, so one wheel per platform covers CPython 3.8 and newer.
Quick Start
Parse Source Capabilities
import usbpdpy
# Parse a Source Capabilities message
source_caps_hex = "a1612c9101082cd102002cc103002cb10400454106003c21dcc0"
source_caps_bytes = bytes.fromhex(source_caps_hex)
message = usbpdpy.parse_pd_message(source_caps_bytes)
print(f"Message: {message.header.message_type}")
print(f"Power role: {message.header.port_power_role}")
print(f"Available PDOs: {len(message.data_objects)}")
for i, pdo in enumerate(message.data_objects):
print(f" PDO {i+1}: {pdo}")
# Output: PDO 1: PowerDataObj(FixedSupply: 5V @ 3A = 15W)
# PDO 2: PowerDataObj(FixedSupply: 9V @ 3A = 27W)
# ...
Parse Request Messages
# First, parse Source Capabilities to get PDO state
source_msg = usbpdpy.parse_pd_message(source_caps_bytes)
# Parse Request message with PDO context
request_hex = "8210dc700323"
request_bytes = bytes.fromhex(request_hex)
request_msg = usbpdpy.parse_pd_message_with_state(request_bytes, source_msg.data_objects)
print(f"Request type: {request_msg.header.message_type}")
for rdo in request_msg.request_objects:
print(f" Requesting PDO #{rdo.object_position}: {rdo.rdo_type}")
# Output: Requesting PDO #2: FixedVariableSupply
API Reference
Core Functions
parse_pd_message(data: bytes) -> PdMessage- Parse a USB PD messageparse_pd_message_with_state(data: bytes, pdo_state: List[PowerDataObj]) -> PdMessage- Parse with PDO context for Request messagesparse_messages(messages: List[bytes]) -> List[PdMessage]- Parse multiple messagesget_message_type_name(msg_type: int, num_objects: int) -> str- Get human-readable message typehex_to_bytes(hex_str: str) -> List[int]- Convert hex string to byte listbytes_to_hex(data: bytes) -> str- Convert bytes to hex string
Message Structure
PdMessage
header: PdHeader- Message header informationdata_objects: List[PowerDataObj]- Power Data Objects (PDOs) for Source/Sink Capabilitiesrequest_objects: List[RequestDataObj]- Request Data Objects (RDOs) for Request messagesraw_bytes: bytes- Original message bytesis_control_message() -> bool- Check if control messageis_data_message() -> bool- Check if data messageis_source_capabilities() -> bool- Check if Source Capabilitieshex() -> str- Get message as hex string
PdHeader
message_type: str- Human-readable type (e.g., "Source_Capabilities", "GoodCRC")message_type_raw: int- Raw type code (0–31)port_data_role: str- "Ufp" or "Dfp"port_power_role: str- "Sink" or "Source"message_id: int- Message ID (0–7)num_data_objects: int- Number of 32-bit data objects (0–7)spec_revision: int- PD spec rev (0=R1.0, 1=R2.0, 2=R3.0)extended: bool- Extended message flag
PowerDataObj
pdo_type: str- "FixedSupply", "Battery", "VariableSupply", "PPS", "EPR_AVS", "Unknown"raw: int- Raw 32-bit PDO valuevoltage_v: Optional[float]- Voltage in volts (fixed supply)max_current_a: Optional[float]- Maximum current in amperesmax_power_w: Optional[float]- Maximum power in watts (calculated or battery)min_voltage_v: Optional[float]- Minimum voltage in volts (variable/PPS)max_voltage_v: Optional[float]- Maximum voltage in volts (variable/PPS)dual_role_power: Optional[bool]- Dual role power capabilityusb_communications_capable: Optional[bool]- USB communications capabilityunconstrained_power: Optional[bool]- Unconstrained power flag
RequestDataObj
rdo_type: str- "FixedVariableSupply", "Battery", "PPS", "AVS", "Unknown", or the same names prefixed withEPR_for an EPR_Request (e.g. "EPR_FixedVariableSupply")raw: int- Raw 32-bit RDO valueobject_position: int- PDO position being requested (1-7, up to 13 in EPR mode)operating_current_a: Optional[float]- Operating current in amperesmax_operating_current_a: Optional[float]- Maximum operating current in amperesoperating_voltage_v: Optional[float]- Operating voltage in volts (PPS/AVS)operating_power_w: Optional[float]- Operating power in watts (battery)max_operating_power_w: Optional[float]- Maximum operating power in watts (battery)capability_mismatch: bool- Capability mismatch flagusb_communications_capable: bool- USB communications capabilityno_usb_suspend: bool- No USB suspend flaggiveback_flag: Optional[bool]- GiveBack flag (fixed/variable supply)
Message Types
The library correctly distinguishes between control and data messages:
- Control Messages (
num_data_objects = 0): GoodCRC, Accept, Reject, PS_RDY, etc. - Data Messages (
num_data_objects > 0): Source_Capabilities, Request, Sink_Capabilities, etc.
Supported Data Messages
- Source_Capabilities: Parsed into
data_objects(PDOs) - Request: Parsed into
request_objects(RDOs) when PDO state is provided - EPR_Request: Parsed into
request_objectseven without PDO state, because the message carries a copy of the PDO it selects - Sink_Capabilities: Header parsed, data objects pending
- Other data messages: Header parsed, data objects pending
Real-World Usage
This library has been tested with real USB PD captures from KM003C hardware, including complete negotiation sequences:
# Parse a complete USB PD negotiation sequence
messages = [
"a1612c9101082cd102002cc103002cb10400454106003c21dcc0", # Source_Capabilities
"8210dc700323", # Request (9V)
"a305", # Accept
"a607", # PS_RDY
]
source_msg = usbpdpy.parse_pd_message(bytes.fromhex(messages[0]))
request_msg = usbpdpy.parse_pd_message_with_state(
bytes.fromhex(messages[1]),
source_msg.data_objects
)
print(f"Sink requested PDO #{request_msg.request_objects[0].object_position}")
# Output: Sink requested PDO #2 (9V from the source capabilities)
Development
# Install development dependencies
uv sync --dev
# Build the extension
uv run maturin develop
# Run tests
uv run pytest
# Lint and format
uv run ruff check .
uv run ruff format .
Requirements
- Python 3.8+
- No runtime dependencies
License
MIT
Metadata
Release files for usbpdpy 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| usbpdpy-0.3.0.tar.gz | 32.4 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| usbpdpy-0.3.0-cp38-abi3-win_amd64.whl | CPython 3.8 | abi3 | Windows x86-64 | Details |
| usbpdpy-0.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| usbpdpy-0.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| usbpdpy-0.3.0-cp38-abi3-macosx_11_0_arm64.whl | CPython 3.8 | abi3 | macOS 11.0+ ARM64 | Details |
| usbpdpy-0.3.0-cp38-abi3-macosx_10_12_x86_64.whl | CPython 3.8 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 1.5 MB
Release files / usbpdpy-0.3.0.tar.gz
| Download URL | usbpdpy-0.3.0.tar.gz |
|---|---|
| Size | 32.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9537e923bc5dacfd53a883fa63566ee8746edc021f78eca07df6828d7406de5d
|
|
BLAKE2b-256 checksum How to use checksums |
9307fd5dc752f68327665817e3b363b71f66b8dfa27a19a731685d12e184270a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.
Transparency logRelease files / usbpdpy-0.3.0-cp38-abi3-win_amd64.whl
| Download URL | usbpdpy-0.3.0-cp38-abi3-win_amd64.whl |
|---|---|
| Size | 186.6 kB |
| Tags | CPython 3.8 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
0555484ce4168afaf6fc7c975e4d5a0faf58f8dee4583728235383920e7ad6d0
|
|
BLAKE2b-256 checksum How to use checksums |
5c9f21c744e663083cabfbdaae10e6b705b270614234b552183deee458478c87
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.
Transparency logRelease files / usbpdpy-0.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | usbpdpy-0.3.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 338.4 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
4e3e0cb60b0ab80fb01cd45aa39b6811d33eb369f712872e7e544db50e41ad34
|
|
BLAKE2b-256 checksum How to use checksums |
a30c350fbc3cd09b863b55ef291c8c3311fe09136ce70a8c07648b62433173fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.
Transparency logRelease files / usbpdpy-0.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | usbpdpy-0.3.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 336.0 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
f0bcd26c15e38a1c62053056a94a66d20a7caab306826d4f32bcd66ed2adb59c
|
|
BLAKE2b-256 checksum How to use checksums |
1b94944798fe7c6b362011d9cc0a853380a0f120409ae273e9bb0802227bf001
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.
Transparency logRelease files / usbpdpy-0.3.0-cp38-abi3-macosx_11_0_arm64.whl
| Download URL | usbpdpy-0.3.0-cp38-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 295.7 kB |
| Tags | CPython 3.8 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
8b91ae09e0f29d5e5a6b802db2c36beb57c6f949a540b4f80e8e699da530a365
|
|
BLAKE2b-256 checksum How to use checksums |
28d83bf894876351c77f1f7f6a4c99064ed8f70fd900f81b0963b07e0dac3436
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.
Transparency logRelease files / usbpdpy-0.3.0-cp38-abi3-macosx_10_12_x86_64.whl
| Download URL | usbpdpy-0.3.0-cp38-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 294.6 kB |
| Tags | CPython 3.8 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
118f346a28470d4eeddb84f38ae4273daf87c7aae67b0e31356ee9d99b5de405
|
|
BLAKE2b-256 checksum How to use checksums |
62ef381a8a99fdcf04599fa64ac0d84ec6d900269600dcab9b87d1e72a6dd4d1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.
Transparency log