{"library":"pyrad","title":"PyRad RADIUS Library","description":"PyRad is a Python library for implementing RADIUS (Remote Authentication Dial-In User Service) clients and servers. It simplifies handling RADIUS packets, attributes, and dictionaries. The current version is 2.5.4, and the project maintains an active release cadence with minor updates and bug fixes.","language":"python","status":"active","last_verified":"Sun May 17","install":{"commands":["pip install pyrad"],"cli":null},"imports":["from pyrad.client import RadiusClient","from pyrad.server import RadiusServer","from pyrad.dictionary import Dictionary","from pyrad.packet import AccessRequest"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"import os\nfrom pyrad.client import RadiusClient\nfrom pyrad.packet import AccessRequest\nfrom pyrad.dictionary import Dictionary, getDictionaryPaths\n\n# Pyrad relies on RADIUS dictionaries for attribute definitions.\n# It attempts to find default dictionaries (e.g., in /usr/share/pyrad/dictionaries).\n# For robustness, specify a dictionary path or ensure defaults are installed.\n# In a real app, you might use Dictionary('/etc/raddb/dictionary') or a custom path.\ntry:\n    # Try to load dictionaries from common system paths\n    radius_dict = Dictionary(getDictionaryPaths())\nexcept FileNotFoundError:\n    print(\"Warning: Could not find system RADIUS dictionaries. Using a minimal inline dictionary for example.\")\n    # Fallback to a minimal dictionary for demonstration if no default found.\n    radius_dict = Dictionary({\"RADIUS\": [\n        {\"name\": \"User-Name\", \"type\": \"string\", \"code\": 1},\n        {\"name\": \"User-Password\", \"type\": \"string\", \"code\": 2},\n        {\"name\": \"NAS-IP-Address\", \"type\": \"ipv4addr\", \"code\": 4}\n    ]})\n\n# Configure RADIUS server details (use environment variables for security in real apps)\nRADIUS_SERVER = os.environ.get('RADIUS_SERVER', '127.0.0.1')\nRADIUS_PORT = int(os.environ.get('RADIUS_PORT', '1812'))\nRADIUS_SECRET = os.environ.get('RADIUS_SECRET', 'testing123')\n\ntry:\n    # Initialize the RADIUS client\n    client = RadiusClient(\n        server=RADIUS_SERVER, \n        authport=RADIUS_PORT, \n        secret=RADIUS_SECRET.encode(), \n        dict=radius_dict\n    )\n\n    # Create an Access-Request packet\n    request = client.CreateAuthPacket(code=AccessRequest)\n    request[\"User-Name\"] = \"testuser\"\n    request[\"User-Password\"] = \"testpassword\"\n    request[\"NAS-IP-Address\"] = \"192.168.1.100\"\n\n    print(f\"Sending Access-Request to {RADIUS_SERVER}:{RADIUS_PORT}...\")\n    \n    # Send the packet and wait for a reply\n    reply = client.SendPacket(request)\n\n    if reply:\n        print(f\"Received reply: {reply.code}\")\n        if reply.code == 2:  # Access-Accept\n            print(\"Authentication successful!\")\n        else:\n            print(\"Authentication failed.\")\n        print(\"Reply attributes:\")\n        for attr_name in reply.keys():\n            # Using .get() is safer for potentially multi-valued attributes\n            print(f\"  {attr_name}: {reply.get(attr_name)}\")\n    else:\n        print(\"No reply received from RADIUS server (timeout or network issue).\")\n\nexcept Exception as e:\n    print(f\"An error occurred during RADIUS communication: {e}\")","lang":"python","description":"This quickstart demonstrates how to create a basic RADIUS client using `pyrad` to send an `Access-Request` packet and process the server's reply. It includes robust dictionary loading and environment variable usage for sensitive information like server address and secret.","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-17","installed_version":"2.5.4","pypi_latest":"2.5.4","is_stale":false,"summary":{"python_range":"3.10–3.9","success_rate":100,"avg_install_s":1.7,"avg_import_s":null,"wheel_type":"wheel"},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"pyrad","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"28.6M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"pyrad","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":1.7,"import_time_s":null,"mem_mb":null,"disk_size":"29M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"pyrad","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"30.7M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"pyrad","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":1.8,"import_time_s":null,"mem_mb":null,"disk_size":"31M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"pyrad","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"22.5M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"pyrad","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":1.6,"import_time_s":null,"mem_mb":null,"disk_size":"23M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"pyrad","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"22.3M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"pyrad","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":1.7,"import_time_s":null,"mem_mb":null,"disk_size":"23M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"pyrad","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":"28.1M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"pyrad","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"broken","install_time_s":1.9,"import_time_s":null,"mem_mb":null,"disk_size":"29M"}]}}