safe-netrc
raw JSON → 1.0.1 verified Mon Apr 27 auth: no python
A drop-in replacement for Python's netrc module that safely parses .netrc files without leaking credentials. Provides the same API but with better error handling and support for permission checks. Current version: 1.0.1, released 2023-08. Monthly releases.
pip install safe-netrc Common errors
error safe_netrc.NetrcParseError: permissions too open ↓
cause The .netrc file has permissions that allow other users to read it (e.g., 644). safe-netrc requires permissions to be 600 or less.
fix
Run
chmod 600 ~/.netrc in the terminal to restrict permissions. error AttributeError: module 'netrc' has no attribute 'netrc' ↓
cause You are importing the standard library module `netrc` instead of `safe_netrc`. The safe-netrc module is `safe_netrc` and you must import from it.
fix
Use
from safe_netrc import netrc or import safe_netrc and access via safe_netrc.netrc. Warnings
breaking The `netrc` function from safe-netrc returns a different object type than stdlib `netrc.netrc`. It returns a `Netrc` object from safe_netrc, which behaves identically but is not a subclass of stdlib's. Do not use `isinstance` checks. ↓
fix Avoid isinstance checks; just use the object directly.
gotcha The file permissions are checked strictly. If your .netrc file has group or world permissions (e.g., 644), safe-netrc raises `NetrcParseError` with "permissions too open". stdlib netrc silently accepts such files. ↓
fix Run `chmod 600 ~/.netrc` to fix permissions. Or handle the error gracefully.
gotcha The `authenticators` method requires the host argument to be a string. Passing bytes or other types will raise TypeError. stdlib netrc also has this requirement, but it's a common mistake. ↓
fix Always pass a string hostname: `netrc_obj.authenticators('example.com')`.
Imports
- netrc wrong
import netrccorrectfrom safe_netrc import netrc
Quickstart
from safe_netrc import netrc
import os
host = 'example.com'
login, _, password = netrc(os.path.expanduser('~/.netrc')).authenticators(host)
print(f'Login: {login}')