netrc
The Python netrc module parses the classic .netrc file, which stores machine, login, and password entries used by the Unix ftp program and other network clients. It exposes a single netrc class that reads the file, presents its contents as dictionaries, and can look up credentials for a given host.
Here’s a quick look at how a parsed file is organized:
>>> import netrc
>>> rc = netrc.netrc(".netrc")
>>> sorted(rc.hosts)
['api.example.com', 'default', 'ftp.example.org']
>>> rc.authenticators("api.example.com")
('alice', '', 's3cret')
The returned tuple contains the login, account, and password fields, in that order, with an empty string for any token that the entry did not provide.
Key Features
- Parses the
.netrcfile format into a Python object - Defaults to the
.netrcfile in the current user’s home directory when no path is passed - Enforces POSIX permission and ownership checks before returning passwords
- Looks up credentials for any host through the
.authenticators()method - Falls back to the special
defaultentry when a host isn’t listed - Exposes parsed entries through the
hostsandmacrosdictionaries - Raises
NetrcParseErrorwith a file name and line number when the input is malformed
Frequently Used Classes and Functions
| Object | Type | Description |
|---|---|---|
netrc.netrc |
Class | Parses a .netrc file and exposes its entries |
netrc.netrc.authenticators() |
Method | Returns the (login, account, password) tuple for a host |
netrc.netrc.hosts |
Attribute | Maps host names to their credential tuples |
netrc.netrc.macros |
Attribute | Maps macro names to lists of command strings |
netrc.NetrcParseError |
Exception | Signals a syntax error in a netrc file |
Examples
Given a .netrc file with two hosts and a default entry:
.netrc
machine api.example.com
login alice
password s3cret
machine ftp.example.org
login bob
account adminpool
password hunter2
default
login guest
password guest
Looking up credentials for a named host and falling back to the default entry for an unknown one:
>>> import netrc
>>> rc = netrc.netrc(".netrc")
>>> rc.authenticators("ftp.example.org")
('bob', 'adminpool', 'hunter2')
>>> rc.authenticators("unknown.example.net")
('guest', '', 'guest')
Catching a malformed entry with NetrcParseError:
>>> import netrc
>>> try:
... netrc.netrc("bad.netrc")
... except netrc.NetrcParseError as error:
... print(error.filename, error.lineno, error.msg)
...
bad.netrc 1 bad toplevel token 'unknowntoken'
Loading the default .netrc from the current user’s home directory:
>>> import netrc
>>> rc = netrc.netrc()
>>> list(rc.hosts)[:3]
['api.example.com', 'ftp.example.org', 'default']
Common Use Cases
The most common tasks for netrc include:
- Reading FTP or SFTP credentials from a user’s home directory at runtime
- Sharing a single credentials file between command-line tools, cron jobs, and scripts
- Attaching HTTP Basic authentication to requests without hard-coding secrets
- Validating that a
.netrcfile has the right permissions and syntax before use - Pointing a script at an alternative
.netrcfile during tests or deployments
Real-World Example
Consider a scenario where you need to call a private REST API and the credentials live in your user’s .netrc file. You can look up the host with .authenticators() and hand the result to an HTTP client instead of hard-coding the login and password:
call_api.py
import netrc
from urllib.request import (
HTTPBasicAuthHandler, HTTPPasswordMgrWithDefaultRealm
)
from urllib.request import build_opener
host = "api.example.com"
login, _, password = netrc.netrc().authenticators(host)
passwords = HTTPPasswordMgrWithDefaultRealm()
passwords.add_password(None, f"https://{host}/", login, password)
opener = build_opener(HTTPBasicAuthHandler(passwords))
with opener.open(f"https://{host}/status") as response:
print(response.status, response.read(80))
When the script runs, it reads .netrc once, hands the login and password to urllib.request, and then uses the resulting opener for any call to that host. The sensitive values never appear in the source code or the shell history.
Related Resources
Tutorial
Python 3.11: Cool New Features for You to Try
In this tutorial, you'll explore what Python 3.11 brings to the table. You'll learn how Python 3.11 is the fastest and most user-friendly version of CPython yet, and learn about improvements to the typing system and to the asynchronous features of Python.
For additional information on related topics, take a look at the following resources:
- Python 3.13: Cool New Features for You to Try (Tutorial)
- Python's urllib.request for HTTP Requests (Tutorial)
- Python's Requests Library (Guide) (Tutorial)
- Python and REST APIs: Interacting With Web Services (Tutorial)
- Cool New Features in Python 3.11 (Course)
- What's New in Python 3.13 (Course)
- Python 3.13: Cool New Features for You to Try (Quiz)
- HTTP Requests With Python's urllib.request (Course)
- Making HTTP Requests With Python (Course)
- Python's Requests Library (Quiz)
- Interacting With REST APIs and Python (Course)
- Python and REST APIs: Interacting With Web Services (Quiz)
By Leodanis Pozo Ramos • Updated April 17, 2026