Python library for communicating with Yubico YubiKey hardware authentication tokens
—
YubiKey device discovery and connection management, supporting multiple connected devices, automatic device type detection, and device-specific class instantiation.
The main function for locating and connecting to YubiKey devices, with automatic version detection and appropriate class instantiation.
def find_yubikey(debug=False, skip=0):
"""
Locate and connect to a YubiKey device.
This is the primary entry point for YubiKey communication. It automatically
detects the connected YubiKey model and returns the appropriate class instance.
Parameters:
- debug (bool): Enable debug output for troubleshooting
- skip (int): Number of YubiKey devices to skip (for multiple devices)
Returns:
YubiKey: Connected YubiKey instance (YubiKeyUSBHID, YubiKeyNEO_USBHID, or YubiKey4_USBHID)
Raises:
YubiKeyError: If no YubiKey device is found
YubiKeyUSBHIDError: If USB communication fails
"""Usage example:
import yubico
# Connect to first available YubiKey
try:
yk = yubico.find_yubikey()
print(f"Connected to YubiKey version {yk.version()}")
except yubico.yubico_exception.YubiKeyError:
print("No YubiKey found")
# Connect to second YubiKey if multiple are connected
try:
yk2 = yubico.find_yubikey(skip=1)
print(f"Connected to second YubiKey: {yk2.version()}")
except yubico.yubico_exception.YubiKeyError:
print("Second YubiKey not found")
# Enable debug output
yk_debug = yubico.find_yubikey(debug=True)Lower-level device discovery function available in the yubikey module.
def find_key(debug=False, skip=0):
"""
Locate a connected YubiKey (alternative interface).
This function provides the same functionality as find_yubikey() but is
available directly from the yubikey module.
Parameters:
- debug (bool): Enable debug output
- skip (int): Number of YubiKeys to skip
Returns:
YubiKey: Connected YubiKey instance
Raises:
YubiKeyError: If no YubiKey found
YubiKeyUSBHIDError: If USB communication fails
"""Direct USB HID device connection for advanced use cases requiring low-level access.
class YubiKeyHIDDevice:
def __init__(self, debug=False, skip=0):
"""
Connect directly to YubiKey USB HID interface.
This class provides low-level access to the YubiKey USB HID interface
without the higher-level abstractions of the main YubiKey classes.
Parameters:
- debug (bool): Enable debug output
- skip (int): Number of devices to skip
Raises:
YubiKeyUSBHIDError: If device connection fails
"""
def status(self):
"""
Poll YubiKey for status information.
Returns:
YubiKeyUSBHIDStatus: Device status object
"""The discovery system automatically detects YubiKey models and returns the appropriate class:
YubiKeyUSBHID instanceYubiKeyNEO_USBHID instanceYubiKeyNEO_USBHID instanceYubiKey4_USBHID instanceThe discovery system uses firmware version information to determine the appropriate class:
# Internal logic (for reference)
if (2, 1, 4) <= yk_version <= (2, 1, 9):
return YubiKeyNEO_USBHID(debug, skip, hid_device)
if yk_version < (3, 0, 0):
return YubiKeyUSBHID(debug, skip, hid_device)
if yk_version < (4, 0, 0):
return YubiKeyNEO_USBHID(debug, skip, hid_device)
return YubiKey4_USBHID(debug, skip, hid_device)Common connection errors and their meanings:
try:
yk = yubico.find_yubikey()
except yubico.yubico_exception.YubiKeyError as e:
if "No YubiKey found" in str(e):
print("No YubiKey device is connected")
else:
print(f"YubiKey error: {e.reason}")
except yubico.yubikey_usb_hid.YubiKeyUSBHIDError as e:
print(f"USB communication error: {e.reason}")When multiple YubiKeys are connected, use the skip parameter:
# Get all connected YubiKeys
yubikeys = []
skip = 0
while True:
try:
yk = yubico.find_yubikey(skip=skip)
yubikeys.append(yk)
print(f"Found YubiKey {skip + 1}: {yk.version()}")
skip += 1
except yubico.yubico_exception.YubiKeyError:
break
print(f"Total YubiKeys found: {len(yubikeys)}")Install with Tessl CLI
npx tessl i tessl/pypi-python-yubico