obspy icon indicating copy to clipboard operation
obspy copied to clipboard

AttributeError: 'TimeoutError' object has no attribute 'splitlines'

Open Thomas-Ulrich opened this issue 10 months ago • 2 comments

Avoid duplicates

  • [x] I searched existing issues

Bug Summary

I'm trying to retrieve a lot of channel information near a seismic event, from the client NCEDC. the request times out, but the handle of the server response is not properly done by obspy it seems.

Code to Reproduce

def load_or_create_inventory(
    client, client_name, event, path_observations, spatial_range, t_before, t_after
):
    fn_inventory = f"{path_observations}/inv_{client_name}.xml"
    if os.path.exists(fn_inventory):
        inventory = read_inventory(fn_inventory)
    else:
        starttime = event["onset"] - t_before
        endtime = event["onset"] + t_after
        kargs = {}
        r0, r1 = spatial_range["radius"]
        if "source_lon_range" in spatial_range.keys():
            kargs["minlongitude"] = spatial_range["source_lon_range"][0] - r1
            kargs["maxlongitude"] = spatial_range["source_lon_range"][1] + r1
            kargs["minlatitude"] = spatial_range["source_lat_range"][0] - r1
            kargs["maxlatitude"] = spatial_range["source_lat_range"][1] + r1
        else:
            kargs["minradius"] = r0
            kargs["maxradius"] = r1
            kargs["latitude"] = event["latitude"]
            kargs["longitude"] = event["longitude"]
            if r1 > 30:
                kargs["network"] = "IU,II,GE,G"
                print(f"Warning: restricting to networks {kargs['network']} for teleseismic")

        print(kargs)
        try:
            inventory = client.get_stations(
                starttime=starttime,
                endtime=endtime,
                level="channel",
                channel="*",
                includerestricted=False,
                includeavailability=True,
                **kargs,
            )
        except TypeError:
            # TypeError: The parameter 'includerestricted' is not supported by the service.
            inventory = client.get_stations(
                starttime=starttime,
                endtime=endtime,
                level="channel",
                channel="*",
                includeavailability=True,
                **kargs,
            )
        inventory = filter_channels_by_availability(inventory, starttime, endtime)
        inventory.write(fn_inventory, format="STATIONXML")
    return inventory

Error Traceback

{'minradius': 0.0, 'maxradius': 2.5, 'latitude': 40.374, 'longitude': -125.021666666667}
Traceback (most recent call last):
  File "/home/ulrich/seismic-waveform-factory/scripts/select_stations.py", line 306, in load_or_create_inventory
    inventory = client.get_stations(
                ^^^^^^^^^^^^^^^^^^^^
  File "/home/ulrich/mambaforge/lib/python3.12/site-packages/obspy/clients/fdsn/client.py", line 745, in get_stations
    url = self._create_url_from_parameters(
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ulrich/mambaforge/lib/python3.12/site-packages/obspy/clients/fdsn/client.py", line 1311, in _create_url_from_parameters
    raise TypeError(msg)
TypeError: The parameter 'includerestricted' is not supported by the service.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ulrich/seismic-waveform-factory/scripts/select_stations.py", line 436, in <module>
    inventory = load_or_create_inventory(
                ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ulrich/seismic-waveform-factory/scripts/select_stations.py", line 317, in load_or_create_inventory
    inventory = client.get_stations(
                ^^^^^^^^^^^^^^^^^^^^
  File "/home/ulrich/mambaforge/lib/python3.12/site-packages/obspy/clients/fdsn/client.py", line 748, in get_stations
    data_stream = self._download(url)
                  ^^^^^^^^^^^^^^^^^^^
  File "/home/ulrich/mambaforge/lib/python3.12/site-packages/obspy/clients/fdsn/client.py", line 1486, in _download
    raise_on_error(code, data)
  File "/home/ulrich/mambaforge/lib/python3.12/site-packages/obspy/clients/fdsn/client.py", line 1831, in raise_on_error
    line for line in server_info.splitlines() if line)
                     ^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'TimeoutError' object has no attribute 'splitlines'

ObsPy Version?

1.4.1

Operating System?

Debian

Python Version?

3.12.6

Installation Method?

conda

Thomas-Ulrich avatar Jan 27 '25 13:01 Thomas-Ulrich

        if server_info:
            server_info = "\n".join(
                line for line in str(server_info).splitlines() if line)

fixes the problem it seems

Thomas-Ulrich avatar Jan 27 '25 16:01 Thomas-Ulrich

My guess is this is a duplicate of #3320 and fixed on master branch by #3306

megies avatar Feb 13 '25 12:02 megies

This solution doesn't work as TimeoutError gets interpreted as True.

In [1]: bool(TimeoutError)
Out[1]: True

We might be able to use server_info == TimeoutError, but that seems clunky. I looked through the code base trying to understand why server_info gets set to TimeoutError, but I don't see it.

arkottke avatar Aug 14 '25 18:08 arkottke

Hi,

Just to confirm that the error is still there with obspy 1.4.2 (I was using iris client):

File "/home/ulrich/mambaforge/lib/python3.13/site-packages/obspy/clients/fdsn/client.py", line 748, in get_stations
    data_stream = self._download(url)
  File "/home/ulrich/mambaforge/lib/python3.13/site-packages/obspy/clients/fdsn/client.py", line 1486, in _download
    raise_on_error(code, data)
    ~~~~~~~~~~~~~~^^^^^^^^^^^^
  File "/home/ulrich/mambaforge/lib/python3.13/site-packages/obspy/clients/fdsn/client.py", line 1831, in raise_on_error
    line for line in server_info.splitlines() if line)
                     ^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'URLError' object has no attribute 'splitlines'

obspy version:

(base) ulrich@ulrich-ThinkPad-T490s:~/seismic-waveform-factory/test$ python
Python 3.13.8 | packaged by conda-forge | (main, Oct 13 2025, 14:15:33) [GCC 14.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import obspy
>>> print(obspy.__version__)
1.4.2

Thomas-Ulrich avatar Oct 24 '25 08:10 Thomas-Ulrich