API Reference
This page provides detailed API documentation for PadRelay’s modules and classes. The documentation is automatically generated from source code docstrings.
Client Module
Client Application
Client application
- class padrelay.client.client_app.UDPClientProtocol[source]
Bases:
DatagramProtocolDatagram protocol that queues incoming packets
- class padrelay.client.client_app.VirtualGamepadClient(server_ip: str, server_port: int, protocol: str, gamepad: GamepadInput, update_rate: int = 60, password: str | None = None, config: object | None = None, enable_tls: bool = False)[source]
Bases:
objectClient controller
Input Handling
Gamepad input helpers for the PadRelay
Client Constants
Constants used by the client portion of the bridge
Server Module
Server Application
Server application for the PadRelay
- class padrelay.server.server_app.VirtualGamepadServer(host, port, password, gamepad_type='xbox360', config=None, rate_limit_window=60, max_requests=100, block_duration=2, protocol='tcp', enable_tls=False, cert_path: Path | None = None, key_path: Path | None = None)[source]
Bases:
objectServer controller
- __init__(host, port, password, gamepad_type='xbox360', config=None, rate_limit_window=60, max_requests=100, block_duration=2, protocol='tcp', enable_tls=False, cert_path: Path | None = None, key_path: Path | None = None)[source]
Construct the server instance
- Parameters:
host – Host to bind to
port – Port to listen on
password – Authentication password
gamepad_type – Type of virtual gamepad to create
config – Configuration object (optional)
rate_limit_window – Time window for rate limiting in seconds
max_requests – Maximum number of requests per window
block_duration – How long to block clients that exceed the rate limit
protocol – Transport protocol (‘tcp’ or ‘udp’)
enable_tls – Enable TLS/SSL encryption for TCP connections
cert_path – Path to TLS certificate (optional)
key_path – Path to TLS private key (optional)
Input Processor
Utilities that translate input messages into virtual gamepad actions
Virtual Gamepad
Virtual gamepad wrapper for the server.
Server Constants
Constants used by the server
Protocol Module
TCP Protocol
TCP protocol utilities for the PadRelay
UDP Protocol
UDP protocol utilities for the PadRelay
- class padrelay.protocol.udp.UDPProtocolHandler(transport=None, remote_addr=None)[source]
Bases:
objectHandle UDP communication on the client
Messages
Message types and validators for the PadRelay
- class padrelay.protocol.messages.InputMessage(buttons=None, axes=None, hats=None, triggers=None)[source]
Bases:
BaseMessageGamepad state message
- class padrelay.protocol.messages.HeartbeatMessage[source]
Bases:
BaseMessageHeartbeat ping
- class padrelay.protocol.messages.HeartbeatAckMessage[source]
Bases:
BaseMessageHeartbeat acknowledgment
- class padrelay.protocol.messages.AuthChallengeMessage(challenge)[source]
Bases:
BaseMessageAuthentication challenge
- class padrelay.protocol.messages.AuthResponseMessage(response)[source]
Bases:
BaseMessageAuthentication response
- class padrelay.protocol.messages.AuthSuccessMessage[source]
Bases:
BaseMessageAuthentication success
- class padrelay.protocol.messages.AuthFailedMessage(message='Authentication failed')[source]
Bases:
BaseMessageAuthentication failed
- class padrelay.protocol.messages.AuthParamsRequestMessage[source]
Bases:
BaseMessageClient request for hashing parameters
- class padrelay.protocol.messages.AuthParamsMessage(salt: str, iterations: int)[source]
Bases:
BaseMessageServer reply with salt and iterations
- class padrelay.protocol.messages.ErrorMessage(message='Unknown error')[source]
Bases:
BaseMessageRepresents an error
Protocol Constants
Constants shared by client and server.
Security Module
Authentication
Authentication utilities for the PadRelay
- class padrelay.security.auth.Authenticator(password: str | None = None)[source]
Bases:
objectAuthentication handler for both client and server
- PBKDF2_PREFIX = 'pbkdf2_sha256'
- DEFAULT_ITERATIONS = 100000
- UDP_TOKEN_TTL = 60
- __init__(password: str | None = None) None[source]
Initialize an authenticator
- Parameters:
password – Plain text password (optional)
salt – Salt for password hashing (optional)
- set_parameters(salt: str, iterations: int) None[source]
Set hashing parameters and recompute derived key if needed
- static hash_password(password: str, iterations: int = 100000) str[source]
Return a PBKDF2 hash string for a password
- generate_tcp_challenge() str[source]
Generate a challenge for TCP authentication
- Returns:
Random challenge string
- Return type:
- verify_tcp_response(challenge: str, response: str) bool[source]
Verify a TCP authentication response
- Parameters:
challenge – Challenge string
response – HMAC response to verify
- Returns:
True if response is valid, False otherwise
- Return type:
- generate_udp_token(current_time: int | None = None) str | None[source]
Generate a token for UDP authentication
- Returns:
Authentication token
- Return type:
Rate Limiting
Rate limiting utilities for the PadRelay
- class padrelay.security.rate_limiting.ConnectionTracker(max_connections: int = 1, rate_limit_window: int = 60, max_requests: int = 100, block_duration: int = 2)[source]
Bases:
objectTrack active connections and implement rate limiting
- __init__(max_connections: int = 1, rate_limit_window: int = 60, max_requests: int = 100, block_duration: int = 2) None[source]
Initialize connection tracker
- Parameters:
max_connections – Maximum number of simultaneous connections
rate_limit_window – Time window for rate limiting in seconds
max_requests – Maximum number of requests per window
- can_connect(addr: Tuple[str, int]) bool[source]
Check if a new connection is allowed
- Parameters:
addr – Client address tuple
- Returns:
True if connection is allowed, False otherwise
- Return type:
- is_rate_limited(addr: Tuple[str, int]) bool[source]
Check if client is being rate limited or blocked.
TLS Utilities
TLS/SSL utilities for secure communication
- padrelay.security.tls_utils.get_default_cert_paths() Tuple[Path, Path][source]
Get default paths for certificate and key files
- Returns:
Tuple of (cert_path, key_path)
- padrelay.security.tls_utils.ensure_cert_dir_exists() Path[source]
Ensure certificate directory exists with proper permissions
- Returns:
Path to certificate directory
- padrelay.security.tls_utils.generate_self_signed_cert(cert_path: Path | None = None, key_path: Path | None = None, days_valid: int = 365, country: str = 'US', state: str = 'State', locality: str = 'City', organization: str = 'PadRelay', common_name: str = 'localhost') Tuple[Path, Path][source]
Generate a self-signed certificate for TLS
- Parameters:
cert_path – Path where certificate will be saved (default: ~/.padrelay/certs/server.crt)
key_path – Path where private key will be saved (default: ~/.padrelay/certs/server.key)
days_valid – Number of days the certificate is valid (default: 365)
country – Country code for certificate (default: US)
state – State/Province for certificate
locality – City for certificate
organization – Organization name for certificate
common_name – Common name (hostname) for certificate
- Returns:
Tuple of (cert_path, key_path)
- padrelay.security.tls_utils.create_server_ssl_context(cert_path: Path | None = None, key_path: Path | None = None, auto_generate: bool = True) SSLContext | None[source]
Create SSL context for server
- Parameters:
cert_path – Path to certificate file
key_path – Path to private key file
auto_generate – If True, automatically generate certificate if not found
- Returns:
SSLContext or None if TLS is disabled
- padrelay.security.tls_utils.create_client_ssl_context(verify_cert: bool = False, ca_path: Path | None = None) SSLContext[source]
Create SSL context for client
- Parameters:
verify_cert – If True, verify server certificate (requires CA certificate)
ca_path – Path to CA certificate for verification (optional)
- Returns:
SSLContext configured for client
- padrelay.security.tls_utils.check_cert_expiration(cert_path: Path | None = None) datetime | None[source]
Check certificate expiration date
- Parameters:
cert_path – Path to certificate file
- Returns:
Expiration datetime or None if cert doesn’t exist or error
- padrelay.security.tls_utils.warn_if_cert_expiring_soon(cert_path: Path | None = None, days_warning: int = 30) bool[source]
Check if certificate is expiring soon and warn
- Parameters:
cert_path – Path to certificate file
days_warning – Warn if certificate expires within this many days
- Returns:
True if certificate is expiring soon, False otherwise
Password Strength
Password strength checking utilities
- padrelay.security.password_strength.check_password_strength(password: str) Tuple[str, int, List[str]][source]
Check password strength and provide recommendations
- Parameters:
password – The password to check
- Returns:
Tuple of (strength_level, score, recommendations) - strength_level: “very_weak”, “weak”, “medium”, “strong”, “very_strong” - score: Integer score from 0-100 - recommendations: List of improvement suggestions
Core Module
Configuration
Helpers for reading and validating configuration
- padrelay.core.config.load_config(config_path: str) ConfigParser | None[source]
Exceptions
Exception hierarchy for the PadRelay
- exception padrelay.core.exceptions.GamepadBridgeError(message: str = 'An error occurred in the PadRelay', details: Any | None = None)[source]
Bases:
ExceptionBase exception for bridge errors
- exception padrelay.core.exceptions.ProtocolError(message: str = 'Protocol error', details: Any | None = None, protocol_version: str | None = None)[source]
Bases:
GamepadBridgeErrorProtocol-related error
- exception padrelay.core.exceptions.AuthenticationError(message: str = 'Authentication failed', details: Any | None = None, addr: str | None = None)[source]
Bases:
GamepadBridgeErrorAuthentication failed
- exception padrelay.core.exceptions.ConnectionError(message: str = 'Connection error', details: Any | None = None, addr: str | None = None, reconnect_attempt: int | None = None)[source]
Bases:
GamepadBridgeErrorConnection related error
- exception padrelay.core.exceptions.ConfigurationError(message: str = 'Configuration error', details: Any | None = None, config_file: str | None = None, setting: str | None = None)[source]
Bases:
GamepadBridgeErrorConfiguration problem
Logging Utilities
Logging utilities
- padrelay.core.logging_utils.get_logger(name: str) Logger[source]
Return a
logging.Loggerconfigured for the project
Scripts Module
Server Entry Point
Entry point for the PadRelay server
Client Entry Point
Entry point for the PadRelay client
Key Mapper
Xbox360/DS4 Controller Key Mapper
This script helps map your physical gamepad buttons to virtual gamepad buttons
- class padrelay.scripts.key_mapper.ControllerMapper(output_path, polling_interval=0.1)[source]
-
- detect_axis_movement(axis_name, instruction, timeout=5.0, threshold=0.3)[source]
Detect significant axis movement with improved feedback and direction detection
- Parameters:
axis_name – The name of the axis being mapped
instruction – Basic instruction to display to the user
timeout – Time in seconds to wait for movement
threshold – Minimum change to be considered significant
Usage Examples
Creating a Client Programmatically
import asyncio
from padrelay.client.client_app import VirtualGamepadClient
from padrelay.client.input import GamepadInput
async def main():
# Initialize gamepad
gamepad = GamepadInput(joystick_index=0)
if not gamepad.initialize():
print("Failed to initialize gamepad")
return
# Create client
client = VirtualGamepadClient(
server_ip="192.168.1.100",
server_port=9999,
protocol="tcp",
gamepad=gamepad,
update_rate=60,
password="my_password",
enable_tls=True
)
# Run client
await client.run()
if __name__ == "__main__":
asyncio.run(main())
Creating a Server Programmatically
import asyncio
from padrelay.server.server_app import VirtualGamepadServer
async def main():
# Create server
server = VirtualGamepadServer(
host="0.0.0.0",
port=9999,
password="my_password",
gamepad_type="xbox360",
protocol="tcp",
enable_tls=True
)
# Run server
await server.run()
if __name__ == "__main__":
asyncio.run(main())
Using the Authenticator
from padrelay.security.auth import Authenticator
# Hash a password
password_hash = Authenticator.hash_password("my_password")
print(password_hash)
# Output: pbkdf2_sha256$100000$abc123...$def456...
# Create authenticator with plaintext password
auth1 = Authenticator(password="my_password")
# Create authenticator with hashed password
auth2 = Authenticator(password=password_hash)
# Generate challenge
challenge = auth1.generate_challenge()
# Compute response
response = auth2.compute_response(challenge, auth1.salt, auth1.iterations)
# Verify response
is_valid = auth1.verify_response(challenge, response)
print(is_valid) # True
Custom Message Creation
from padrelay.protocol.messages import InputMessage
# Create input message
msg = InputMessage(
buttons=[0, 1, 4], # Buttons A, B, and LB pressed
axes=[0.0, -0.5, 0.8, 0.0], # Left stick up, right stick right
hats=[[0, 0]], # D-pad centered
triggers={"left": 0.0, "right": 0.7} # Right trigger pressed
)
# Serialize to JSON
json_str = msg.to_json()
# Serialize to bytes
data = msg.to_bytes()
Rate Limiting Example
from padrelay.security.rate_limiting import RateLimiter
# Create rate limiter (100 requests per 60 seconds)
limiter = RateLimiter(
max_requests=100,
window_seconds=60,
block_duration=120
)
# Check if client is allowed
client_addr = "192.168.1.50"
if limiter.is_allowed(client_addr):
# Process request
pass
else:
# Reject request
print("Rate limit exceeded")
TLS Certificate Generation
from pathlib import Path
from padrelay.security.tls_utils import generate_self_signed_cert
# Generate certificate
cert_path = Path("server.crt")
key_path = Path("server.key")
generate_self_signed_cert(
cert_path=cert_path,
key_path=key_path,
hostname="localhost",
days=365
)
print(f"Certificate created: {cert_path}")
print(f"Private key created: {key_path}")
See Also
Architecture - System architecture overview
Protocol Specification - Protocol specification
Security - Security implementation details