Skip to content

Commit 1379a6f

Browse files
authored
Merge pull request #3305 from cds-astro/simbad-async-sync
[SIMBAD] add async_job option in all queries
2 parents 7f53683 + f1ee46b commit 1379a6f

File tree

7 files changed

+238
-98
lines changed

7 files changed

+238
-98
lines changed

CHANGES.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ imcce
4444
- Changing RuntimeError to NoResultsWarning when an empty result is
4545
returned. [#3307]
4646

47+
SIMBAD
48+
^^^^^^
49+
50+
- add ``async_job`` option in all query methods. This executes the query in asynchronous
51+
mode. It provides slower to start, but more robust queries for which the timeout can
52+
be increased (with the ``timeout`` property or with the configuration file) [#3305]
53+
4754
utils.tap
4855
^^^^^^^^^
4956

astroquery/simbad/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ class Conf(_config.ConfigNamespace):
2222
'Name of the SIMBAD mirror to use.')
2323

2424
timeout = _config.ConfigItem(
25-
60,
26-
'Time limit for connecting to Simbad server.')
25+
1080,
26+
# this is the default value in SIMBAD's main mirror
27+
# https://simbad.cds.unistra.fr/simbad/sim-tap/capabilities
28+
"Time limit for the execution of asynchronous queries, "
29+
"in seconds.")
2730

2831
row_limit = _config.ConfigItem(
2932
# defaults to the maximum limit

astroquery/simbad/core.py

Lines changed: 154 additions & 78 deletions
Large diffs are not rendered by default.

astroquery/simbad/tests/test_simbad.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
import astropy.units as u
99
from astropy.utils.exceptions import AstropyDeprecationWarning
1010
from pyvo.dal.tap import TAPService
11+
from pyvo.io.vosi import tapregext
1112

1213
import pytest
1314

15+
from .. import conf
1416
from ... import simbad
1517
from .test_simbad_remote import multicoords
1618
from astroquery.exceptions import NoResultsWarning
@@ -155,6 +157,26 @@ def test_mocked_simbad():
155157
# and the uploadlimit
156158
assert simbad_instance.uploadlimit == 200000
157159

160+
161+
def test_simbad_timeout(monkeypatch):
162+
simbad_instance = simbad.Simbad()
163+
assert simbad_instance.timeout == conf.timeout # default value
164+
165+
class PatchedCapability:
166+
@property
167+
def executionduration(self):
168+
time_limit = tapregext.TimeLimits()
169+
time_limit.hard = 2000
170+
return time_limit
171+
172+
monkeypatch.setattr(TAPService, "capabilities", [PatchedCapability()])
173+
# good value
174+
simbad_instance.timeout = 10
175+
assert simbad_instance.timeout == 10
176+
# too high
177+
with pytest.raises(ValueError, match="'timeout' cannot exceed*"):
178+
simbad_instance.timeout = 10000
179+
158180
# ----------------------------
159181
# Test output options settings
160182
# ----------------------------
@@ -563,14 +585,16 @@ def test_query_tap_errors():
563585
@pytest.mark.usefixtures("_mock_simbad_class")
564586
def test_query_tap_cache_call(monkeypatch):
565587
msg = "called_cached_query_tap"
566-
monkeypatch.setattr(simbad.core, "_cached_query_tap", lambda tap, query, maxrec: msg)
588+
monkeypatch.setattr(simbad.core, "_cached_query_tap",
589+
lambda tap, query, maxrec, async_job, timeout: msg)
567590
assert simbad.Simbad.query_tap("select top 1 * from basic") == msg
568591

569592

570593
@pytest.mark.usefixtures("_mock_simbad_class")
571594
def test_empty_response_warns(monkeypatch):
572595
# return something of length zero
573-
monkeypatch.setattr(simbad.core.Simbad, "query_tap", lambda _, get_query_payload, maxrec: [])
596+
monkeypatch.setattr(simbad.core.Simbad, "query_tap",
597+
lambda _, get_query_payload, maxrec, async_job: [])
574598
msg = ("The request executed correctly, but there was no data corresponding to these"
575599
" criteria in SIMBAD")
576600
with pytest.warns(NoResultsWarning, match=msg):

astroquery/simbad/tests/test_simbad_remote.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,12 @@ def test_query_tap(self):
168168
Simbad.clear_cache()
169169
assert _cached_query_tap.cache_info().currsize == 0
170170

171+
def test_async_query(self):
172+
adql = "select top 1 main_id from basic"
173+
sync_job = Simbad.query_tap(adql)
174+
async_job = Simbad.query_tap(adql, async_job=True)
175+
assert sync_job["main_id"] == async_job["main_id"]
176+
171177
def test_empty_response_warns(self):
172178
with pytest.warns(NoResultsWarning, match="The request executed correctly, but *"):
173179
# a catalog that does not exists should return an empty response

docs/simbad/query_tap.rst

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -139,22 +139,22 @@ some tables, add their name. To get the columns of the tables ``ref`` and ``bibl
139139
>>> from astroquery.simbad import Simbad
140140
>>> Simbad.list_columns("ref", "biblio")
141141
<Table length=13>
142-
table_name column_name datatype ... unit ucd
143-
object object object ... object object
144-
---------- ----------- ----------- ... ------ --------------------
145-
biblio biblio VARCHAR ... meta.record;meta.bib
146-
biblio oidref BIGINT ... meta.record;meta.id
147-
ref "year" SMALLINT ... meta.note;meta.bib
148-
ref abstract UNICODECHAR ... meta.record
149-
ref bibcode CHAR ... meta.bib.bibcode
150-
ref doi VARCHAR ... meta.code;meta.bib
151-
ref journal VARCHAR ... meta.bib.journal
152-
ref last_page INTEGER ... meta.bib.page
153-
ref nbobject INTEGER ... meta.number
154-
ref oidbib BIGINT ... meta.record;meta.bib
155-
ref page INTEGER ... meta.bib.page
156-
ref title UNICODECHAR ... meta.title
157-
ref volume INTEGER ... meta.bib.volume
142+
table_name column_name datatype ... unit ucd
143+
object object object ... object object
144+
---------- ----------- ----------- ... ------ -----------------
145+
biblio biblio VARCHAR ... meta.bib.bibcode
146+
biblio oidref BIGINT ... meta.record
147+
ref "year" SMALLINT ... time.publiYear
148+
ref abstract UNICODECHAR ... meta.record
149+
ref bibcode CHAR ... meta.bib.bibcode
150+
ref doi VARCHAR ... meta.ref.doi
151+
ref journal VARCHAR ... meta.bib.journal
152+
ref last_page INTEGER ... meta.bib.page
153+
ref nbobject INTEGER ... meta.id;arith.sum
154+
ref oidbib BIGINT ... meta.record
155+
ref page INTEGER ... meta.bib.page
156+
ref title UNICODECHAR ... meta.title
157+
ref volume INTEGER ... meta.bib.volume
158158

159159
`~astroquery.simbad.SimbadClass.list_columns` can also be called with a keyword argument.
160160
This returns columns from any table for witch the given keyword is either in the table name,

docs/simbad/simbad.rst

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,30 @@ Query TAP
829829
Troubleshooting
830830
===============
831831

832+
Longer queries
833+
--------------
834+
835+
It can be useful to execute longer queries in asynchronous mode by setting the
836+
``async_job`` argument to ``True``. This may take longer to start, depending on the
837+
current number of other people using the asynchronous SIMBAD queue, but it is more
838+
robust against transient errors. Asynchronous queries will take the ``timeout`` property
839+
in account:
840+
841+
.. doctest-remote-data::
842+
843+
>>> from astroquery.simbad import Simbad
844+
>>> simbad = Simbad(timeout=2000) # in seconds
845+
>>> simbad.query_tap("select otype, description from otypedef where otype = 'N*'",
846+
... async_job=True)
847+
<Table length=1>
848+
otype description
849+
object object
850+
------ ------------
851+
N* Neutron Star
852+
853+
Clearing the cache
854+
------------------
855+
832856
If you are repeatedly getting failed queries, or bad/out-of-date results, try clearing
833857
your cache:
834858

0 commit comments

Comments
 (0)