Registry / auth-security / pyrad
library2.5.4pypypiunverified

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.

pip install pyrad
INSTALL
IMPORT
SIG · PYRAD
P
pyrad
auth-securitypythonv2.5.4
Install
1.7s avg
Import
Disk
27MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v2.5.4 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.920 runs
installs and imports cleanly · install 0.0s · import 0.000s · 28.6MB
glibc
py 3.103.920 runs
installs and imports cleanly · install 1.7s · import 0.000s · 29MB
27MB installed
● package 27MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

RadiusClient
from pyrad.client import RadiusClient
from pyrad.client import RadiusClient
Packet
from pyrad.packet import Packet
Dictionary
from pyrad.dictionary import Dictionary

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.

import os from pyrad.client import RadiusClient from pyrad.packet import AccessRequest from pyrad.dictionary import Dictionary, getDictionaryPaths # Pyrad relies on RADIUS dictionaries for attribute definitions. # It attempts to find default dictionaries (e.g., in /usr/share/pyrad/dictionaries). # For robustness, specify a dictionary path or ensure defaults are installed. # In a real app, you might use Dictionary('/etc/raddb/dictionary') or a custom path. try: # Try to load dictionaries from common system paths radius_dict = Dictionary(getDictionaryPaths()) except FileNotFoundError: print("Warning: Could not find system RADIUS dictionaries. Using a minimal inline dictionary for example.") # Fallback to a minimal dictionary for demonstration if no default found. radius_dict = Dictionary({"RADIUS": [ {"name": "User-Name", "type": "string", "code": 1}, {"name": "User-Password", "type": "string", "code": 2}, {"name": "NAS-IP-Address", "type": "ipv4addr", "code": 4} ]}) # Configure RADIUS server details (use environment variables for security in real apps) RADIUS_SERVER = os.environ.get('RADIUS_SERVER', '127.0.0.1') RADIUS_PORT = int(os.environ.get('RADIUS_PORT', '1812')) RADIUS_SECRET = os.environ.get('RADIUS_SECRET', 'testing123') try: # Initialize the RADIUS client client = RadiusClient( server=RADIUS_SERVER, authport=RADIUS_PORT, secret=RADIUS_SECRET.encode(), dict=radius_dict ) # Create an Access-Request packet request = client.CreateAuthPacket(code=AccessRequest) request["User-Name"] = "testuser" request["User-Password"] = "testpassword" request["NAS-IP-Address"] = "192.168.1.100" print(f"Sending Access-Request to {RADIUS_SERVER}:{RADIUS_PORT}...") # Send the packet and wait for a reply reply = client.SendPacket(request) if reply: print(f"Received reply: {reply.code}") if reply.code == 2: # Access-Accept print("Authentication successful!") else: print("Authentication failed.") print("Reply attributes:") for attr_name in reply.keys(): # Using .get() is safer for potentially multi-valued attributes print(f" {attr_name}: {reply.get(attr_name)}") else: print("No reply received from RADIUS server (timeout or network issue).") except Exception as e: print(f"An error occurred during RADIUS communication: {e}")
Debug
Known issues
breakingPython 2.x support has been completely dropped. If you are migrating from an older `pyrad` version (prior to 2.5.0) that supported Python 2, your code will break.
fix
Ensure your environment uses Python 3.8 or newer. Update your code to be Python 3 compliant, especially around string and byte handling.
affects: <2.5.0 to >=2.5.0
gotchaPyrad relies on RADIUS dictionaries (`pyrad.dictionary.Dictionary`) to understand attribute types and names. If you don't explicitly provide a dictionary, it attempts to load from common system paths, which might not always exist or contain the specific attributes you need.
fix
Always explicitly provide a `Dictionary` instance when initializing `RadiusClient` or `RadiusServer`. For example, `Dictionary('/etc/raddb/dictionary')` or `Dictionary(pyrad.dictionary.getDictionaryPaths())` if you expect system-wide dictionaries to be present. Create custom dictionaries if needed.
affects: All versions
gotchaPyrad introduced asynchronous client and server implementations (`client_async`, `server_async`) in version 2.2 for Python 3.5+. These operate differently from their synchronous counterparts (`client`, `server`) and require `asyncio` patterns.
fix
Be aware of which client/server implementation you are using. If you need asynchronous I/O, use `pyrad.client_async.RadiusClient` and `pyrad.server_async.RadiusServer` and structure your code with `async`/`await`. Do not mix synchronous and asynchronous APIs directly.
affects: >=2.2
gotchaWhen accessing attributes from a `Packet` object, using `packet.get(attribute_name, default_value)` is generally safer than direct dictionary-style access (`packet[attribute_name]`). This is especially true for attributes that might be multi-valued or not present.
fix
Prefer `packet.get('Attribute-Name', 'default')` over `packet['Attribute-Name']`. This prevents `KeyError` if the attribute is missing and handles multi-valued attributes more gracefully.
affects: All versions (improved `get()` behavior in 2.4)
gotchaThe Message-Authenticator (Attribute 80) provides integrity protection for RADIUS packets. If used incorrectly or omitted when required by the RADIUS server/client, packets may be rejected.
fix
Ensure `request.CreateMessageAuthenticator()` is called after all other attributes are added to an outgoing packet. For incoming packets, verify the authenticator using `reply.verifyMessageAuthenticator()` if the server uses it.
affects: All versions (support added in 2.2)
Upgrade
Version history
2.5.4latest on PyPI · released Feb 5, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
33 hits · last 30 days
node
30
OpenAI (training)
1
Resources