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
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.
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')`.

Parse .netrc file and authenticate to a host. The file must have permissions 600 or less (owner-only read/write).

from safe_netrc import netrc
import os

host = 'example.com'
login, _, password = netrc(os.path.expanduser('~/.netrc')).authenticators(host)
print(f'Login: {login}')