Description
Hi!
When using the Eso
class to access the regular "raw" archive,
everything works as expected (see first snippet below).
However, when using the "special access" archive by setting QUERY_INSTRUMENT_URL = "http://archive.eso.org/wdb/wdb/cas"
, I get an IndexError: list index out of range
(see second snippet below, showing full error message as well). The error does not occur with astroquery<0.4.7
.
I tried to investigate a bit more. The issue seems to be that the session is authenticated only at download time (here), but not when retrieving the file table. More specifically, the self._request()
call in self.query()
to get instrument_form
seems to cause the issue (here). For the main archive, which requires no auth to get a table, I get a form webpage, as expected. However, for the special archive, I get the login page in the response. I tried setting the headers
kwarg manually but that did not work.
I have a minimal example showing this in the third snippet.
Currently, my solution to access the special (CAS) archive is to use PyVO to directly do an authenticated TAP query (following the "programmatic access" examples from here).
The fact that the special access worked for version prior to 0.4.7 leads me think the issue is related to #2681, so I'll include @szampier, @almicol and @Pharisaeus and @bsipocz who were involved in the discussion for that PR.
I was wondering:
- Is there a way to make web requests work with this authentication mechanism or is they best way to access the special archive via PyVO+TAP queries directly?
- If PyVO+TAP is the only way, are there plans to migrate astroquery to using the TAP ESO interface?
Thank you!
Snippet 1: Working example with the main archive
# This example works and will give a table containing NIRPS calibrations
from astroquery.eso import Eso
eso = Eso()
eso.login(username="APERO")
criteria = {"instrument": "NIRPS", "night": "2024-03-26"}
table = eso.query_main(**criteria, cache=False)
print(table)
Snippet 2: Working example with the special archive (but working with `astroquery<0.4.7`
# This example does not work and give an error
from astroquery.eso import Eso
eso = Eso()
eso.login(username="APERO")
criteria = {"instrument": "NIRPS", "night": "2024-03-26"}
eso.QUERY_INSTRUMENT_URL = "http://archive.eso.org/wdb/wdb/cas"
table = eso.query_main(**criteria, cache=False)
print(table)
Which gives the following error
Traceback (most recent call last):
File "/home/vandal/repos/astro/nirps-download/scratch/astroquery_not_working_cas.py", line 9, in <module>
table = eso.query_main(**criteria, cache=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vandal/repos/astro/astroquery/astroquery/eso/core.py", line 455, in query_main
return self._query(url, column_filters=column_filters, columns=columns,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vandal/repos/astro/astroquery/astroquery/eso/core.py", line 527, in _query
instrument_response = self._activate_form(instrument_form,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vandal/repos/astro/astroquery/astroquery/eso/core.py", line 98, in _activate_form
form = root.find_all('form', id=form_id)[form_index]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
IndexError: list index out of range
Snippet 3: Example requests to get instrument form
The first block gives an HTML form, the last two a login page.
# This example shows the astroquery function causing the issue (I think)
from astroquery.eso import Eso
# This will show an HTML form
eso_main = Eso()
eso_main.login(username="APERO")
url = eso_main.QUERY_INSTRUMENT_URL + "/eso_archive_main/form"
print(f"Trying with url {url}")
instrument_form = eso_main._request("GET", url, cache=False)
print(instrument_form.content)
# This will show a login page
# In the browser it shows the expected form, because I'm logged in
eso_cas = Eso()
eso_cas.login(username="APERO")
eso_cas.QUERY_INSTRUMENT_URL = "http://archive.eso.org/wdb/wdb/cas"
url = eso_cas.QUERY_INSTRUMENT_URL + "/eso_archive_main/form"
print(f"Trying with url {url}")
instrument_form = eso_cas._request("GET", url, cache=False)
print(instrument_form.content)
# This will also show a login page, despite attempt to use headers
eso_cas = Eso()
eso_cas.login(username="APERO")
eso_cas.QUERY_INSTRUMENT_URL = "http://archive.eso.org/wdb/wdb/cas"
url = eso_cas.QUERY_INSTRUMENT_URL + "/eso_archive_main/form"
print(f"Trying with url {url}")
instrument_form = eso_cas._request("GET", url, cache=False, headers=eso_cas._get_auth_header())
print(instrument_form.content)
print(eso_cas._get_auth_header())