Install & Compatibility
Where this runs
No compatibility data collected yet for this library.
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Cdm
✓ from pywidevine import Cdm
✗ from pywidevine.cdm import Cdm
Since 1.5.1 Cdm is exported from base package; direct import from submodule also works but is less stable.
PSSH
✓ from pywidevine import PSSH
✗ from pywidevine.pssh import PSSH
Direct import from submodule also works, but base package import is preferred.
Device
✓ from pywidevine import Device
✗ from pywidevine.device import Device
Same as above.
Basic usage: load a device, open session, get license challenge, parse response, print keys.
from pywidevine import Cdm, Device, PSSH
# Load a Widevine device (WVD file)
device = Device.load('path/to/device.wvd')
# Create a CDM session
cdm = Cdm()
session = cdm.open(device)
# Set a service certificate (optional, for privacy mode)
cert_data = b'...' # your service certificate bytes
cdm.set_service_certificate(session, cert_data)
# Obtain a license challenge from a PSSH box
pssh = PSSH(pssh='AAAAWnBzc2gAAAAA...')
challenge = cdm.get_license_challenge(session, pssh)
# Send the challenge to your license server, get license response
license_response = b'...' # bytes from server
cdm.parse_license(session, license_response)
# Extract content keys
for key in cdm.get_keys(session):
print(f'{key.type}: {key.kid.hex} -> {key.key.hex()}')
cdm.close(session)
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'yaml'
yaml dependency was not installed unless the 'serve' extras were used. Fixed in v1.8.0.
fixUpgrade to v1.8.0+ or install yaml separately: pip install pyyaml
AttributeError: module 'pywidevine' has no attribute 'Cdm'
Importing incorrectly; Cdm is only available in top-level since v1.5.1. Older versions or wrong import path.
fixUse correct import: from pywidevine import Cdm. Or upgrade to v1.5.1+. Alternatively use: from pywidevine.cdm import Cdm
pywidevine.exceptions.InvalidInitData: Failed to parse PSSH data
PSSH data is malformed or not base64 encoded correctly.
fixEnsure PSSH string is a valid base64-encoded Widevine PSSH box. Use PSSH() with raw bytes or a valid base64 string.
Upgrade
Version history
1.9.0latest on PyPI · released Oct 27, 2025
Audit
Dependencies
protobufrequiredRequired for protobuf serialization
pyyamlrequiredRequired for YAML config; was missing before 1.8.0 without 'serve' extras
requestsrequiredHTTP requests for license challenges
flaskoptionalOnly needed for the 'serve' CLI command