CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyscard

Smartcard library for Python providing PC/SC interface for smart card communication

Pending
Overview
Eval results
Files

reader-management.mddocs/

Reader Management

Functions for discovering and managing smart card readers, including reader groups and system-level reader operations. This module provides the foundation for all smart card reader interactions.

Capabilities

System Reader Functions

Core functions for listing and managing smart card readers at the system level.

def readers(groups=None):
    """
    Get list of smart card readers as Reader objects.
    
    Args:
        groups (list[str], optional): Reader groups to search. If None, searches all groups.
    
    Returns:
        list[Reader]: List of available readers
    
    Example groups: ['SCard$DefaultReaders', 'MyReaderGroup']
    """

def readergroups():
    """
    Get list of all reader groups in the system.
    
    Returns:
        list[str]: List of reader group names
    """

Reader Class

The Reader class represents individual smart card readers and provides methods for connection management.

class Reader:
    def __init__(self, readername):
        """
        Create a reader object.
        
        Args:
            readername (str): Name of the smart card reader
        """
    
    def createConnection(self):
        """
        Create a connection to this reader for card communication.
        
        Returns:
            CardConnection: New connection object for this reader
        
        Raises:
            ReaderException: If connection creation fails
        """
    
    def addtoreadergroup(self, groupname):
        """
        Add this reader to a reader group.
        
        Args:
            groupname (str): Name of the reader group
        """
    
    def removefromreadergroup(self, groupname):
        """
        Remove this reader from a reader group.
        
        Args:
            groupname (str): Name of the reader group
        """
    
    def __eq__(self, other):
        """
        Check reader equality based on name.
        
        Args:
            other (Reader): Other reader to compare
        
        Returns:
            bool: True if readers have the same name
        """
    
    def __hash__(self):
        """
        Get hash value based on reader name.
        
        Returns:
            int: Hash value for use in sets and dictionaries
        """
    
    def __repr__(self):
        """
        Get detailed string representation.
        
        Returns:
            str: Detailed reader representation
        """
    
    def __str__(self):
        """
        Get reader name string.
        
        Returns:
            str: Reader name
        """

Reader Factory

Factory functions for creating and managing reader instances.

def createReader(clazz, readername):
    """
    Create a reader instance from a class name.
    
    Args:
        clazz (str): Reader class name
        readername (str): Name of the reader
    
    Returns:
        Reader: New reader instance
    """

Usage Examples

Basic Reader Discovery

from smartcard.System import readers, readergroups

# List all available readers
reader_list = readers()
print(f"Found {len(reader_list)} readers:")
for i, reader in enumerate(reader_list):
    print(f"  {i}: {reader}")

# List reader groups
groups = readergroups()
print(f"\nReader groups: {groups}")

# Get readers from specific groups
if groups:
    group_readers = readers([groups[0]])
    print(f"\nReaders in '{groups[0]}': {len(group_readers)}")

Reader Information and Management

from smartcard.System import readers

reader_list = readers()
if reader_list:
    reader = reader_list[0]
    
    print(f"Reader name: {reader}")
    print(f"Reader repr: {repr(reader)}")
    print(f"Reader type: {type(reader)}")
    
    # Reader comparison
    same_reader = readers()[0]
    print(f"Same reader: {reader == same_reader}")  # True
    
    # Use reader in a set (requires __hash__)
    reader_set = {reader}
    print(f"Reader in set: {reader in reader_set}")  # True

Connection Creation and Management

from smartcard.System import readers
from smartcard.Exceptions import CardConnectionException

def test_reader_connection(reader):
    """Test connection capabilities of a reader."""
    try:
        print(f"Testing reader: {reader}")
        
        # Create connection
        connection = reader.createConnection()
        print("✓ Connection created successfully")
        
        # Test connection properties
        print(f"Connection type: {type(connection)}")
        print(f"Reader from connection: {connection.getReader()}")
        
        # Try to connect (may fail if no card present)
        try:
            connection.connect()
            print("✓ Connected to card")
            
            # Get card information
            atr = connection.getATR()
            protocol = connection.getProtocol()
            
            print(f"ATR: {' '.join(f'{b:02X}' for b in atr)}")
            print(f"Protocol: {protocol}")
            
            connection.disconnect()
            print("✓ Disconnected successfully")
            
        except CardConnectionException as e:
            print(f"ⓘ No card present or connection failed: {e}")
            
    except Exception as e:
        print(f"✗ Reader test failed: {e}")
    
    print()

# Test all readers
reader_list = readers()
for reader in reader_list:
    test_reader_connection(reader)

Reader Group Management

from smartcard.System import readers, readergroups

def manage_reader_groups():
    """Demonstrate reader group management."""
    reader_list = readers()
    if not reader_list:
        print("No readers available")
        return
    
    reader = reader_list[0]
    print(f"Working with reader: {reader}")
    
    # Show current groups
    current_groups = readergroups()
    print(f"Current groups: {current_groups}")
    
    # Add reader to a custom group (may require admin privileges)
    custom_group = "MyApplicationGroup"
    try:
        reader.addtoreadergroup(custom_group)
        print(f"✓ Added reader to '{custom_group}'")
        
        # Check if group was created
        updated_groups = readergroups()
        if custom_group in updated_groups:
            print(f"✓ Group '{custom_group}' is now available")
        
        # Remove reader from group
        reader.removefromreadergroup(custom_group)
        print(f"✓ Removed reader from '{custom_group}'")
        
    except Exception as e:
        print(f"ⓘ Group management failed (may require admin privileges): {e}")

manage_reader_groups()

Reader Monitoring with System Functions

import time
from smartcard.System import readers

def monitor_reader_changes(duration=30):
    """Monitor for reader connection/disconnection events."""
    print(f"Monitoring readers for {duration} seconds...")
    print("Connect or disconnect readers to see changes")
    
    last_readers = set(str(r) for r in readers())
    print(f"Initial readers: {len(last_readers)}")
    for reader in last_readers:
        print(f"  {reader}")
    print()
    
    start_time = time.time()
    while time.time() - start_time < duration:
        current_readers = set(str(r) for r in readers())
        
        # Check for changes
        added = current_readers - last_readers
        removed = last_readers - current_readers
        
        if added:
            print(f"✓ Readers connected: {added}")
        if removed:
            print(f"✗ Readers disconnected: {removed}")
            
        if added or removed:
            print(f"Current reader count: {len(current_readers)}")
            last_readers = current_readers
            print()
        
        time.sleep(1)
    
    print("Monitoring completed")

# Run monitoring
monitor_reader_changes(10)

Cross-Platform Reader Handling

import platform
from smartcard.System import readers

def analyze_system_readers():
    """Analyze readers based on operating system."""
    system = platform.system()
    reader_list = readers()
    
    print(f"Operating System: {system}")
    print(f"Total readers: {len(reader_list)}")
    print()
    
    for i, reader in enumerate(reader_list):
        reader_name = str(reader)
        print(f"Reader {i+1}: {reader_name}")
        
        # Identify reader types based on naming patterns
        if system == "Windows":
            if "CCID" in reader_name:
                print("  Type: CCID (Generic)")
            elif "PICC" in reader_name:
                print("  Type: Contactless")
            elif "Microsoft" in reader_name:
                print("  Type: Windows built-in")
        
        elif system == "Darwin":  # macOS
            if "CCID" in reader_name:
                print("  Type: CCID")
            elif "PICC" in reader_name:
                print("  Type: Contactless")
        
        elif system == "Linux":
            if "CCID" in reader_name:
                print("  Type: CCID")
            elif "pc/sc" in reader_name.lower():
                print("  Type: PC/SC")
        
        # Test connection capability
        try:
            connection = reader.createConnection()
            print("  Status: Connection OK")
        except Exception as e:
            print(f"  Status: Connection failed - {e}")
        
        print()

analyze_system_readers()

Related Types

# Type aliases
ReaderName = str
ReaderGroupName = str
ReaderList = list[Reader]

# Exception types for reader operations
class ReaderException(SmartcardException):
    """Base exception for reader operations."""

class ListReadersException(SmartcardException):
    """Raised when reader listing fails."""

class InvalidReaderException(SmartcardException):
    """Raised when specified reader is invalid."""

Install with Tessl CLI

npx tessl i tessl/pypi-pyscard

docs

atr-card-types.md

card-connections.md

gui-components.md

index.md

monitoring.md

pcsc-interface.md

reader-management.md

session-api.md

status-word-handling.md

utilities.md

tile.json