obspy / obspy

ObsPy: A Python Toolbox for seismology/seismological observatories.

Home Page:https://www.obspy.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support for `.netrc` files for authentication?

liamtoney opened this issue · comments

Problem

EarthScope (formerly IRIS) provides .netrc files for restricted data access. These have the form

machine service.iris.edu login <user> password <password>

where <user> and <password> are the arguments taken by obspy.clients.fdsn.client.Client (hereafter, Client). The .netrc file can be conveniently downloaded from the SAGE Data Services account:

Screenshot 2024-04-03 at 4 06 17 PM

It would be convenient if the Client checked for ~/.netrc in its __init__() method and if an entry was present which matched self.base_url, it populated user and password automatically. This would allow folks to avoid providing user and password as arguments or via the set_credentials() method — therefore, helping us avoid sticking such credentials in the code itself.

Then we could ask EarthScope to update the text here 😉

ObsPy does not currently permit the use of a .netrc or other private file to keep the username and password secret (unless you are using EIDA tokens).

Proposed solution

Here's a proof-of-concept snippet that could be adopted into the __init__() method to accomplish this. It uses the base_url attribute to determine which host to grab credentials for.

import netrc

base_url = 'http://service.iris.edu'  # In reality this is self.base_url, AFTER it's been mapped

try:
    n = netrc.netrc()  # Looks for ~/.netrc by default
    host = base_url.replace('http://', '').replace('https://', '')  # Strip URL
    host_credentials = n.authenticators(host)
    if host_credentials:  # This is None if no match in .netrc file
        user = host_credentials[0]
        password = host_credentials[2]
except FileNotFoundError:  # If no ~/.netrc
    pass  # Just carry on

We'd want to not overwrite the user and password if they're provided to __init__() (i.e., if they're not None) of course.