diff --git a/CHANGES.rst b/CHANGES.rst index a33cc430..c364728e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -49,6 +49,9 @@ Enhancements and Fixes Deprecations and Removals ------------------------- +- Deprecating the use of "image" and "spectrum" in registry Servicetype + constraints [#449] + 1.5.2 (2024-05-22) ================== diff --git a/docs/registry/index.rst b/docs/registry/index.rst index bad29743..fe015f69 100644 --- a/docs/registry/index.rst +++ b/docs/registry/index.rst @@ -303,13 +303,13 @@ instance. The opening example could be written like this: >>> from astropy.coordinates import SkyCoord >>> my_obj = SkyCoord.from_name("Bellatrix") - >>> for res in registry.search(waveband="infrared", servicetype="spectrum"): + >>> for res in registry.search(waveband="infrared", servicetype="ssap"): ... print(res.service.search(pos=my_obj, size=0.001)) ... In reality, you will have to add some error handling to this kind of all-VO queries: in a wide and distributed network, some service is -always down. See `Appendix: Robust All-VO Queries`_ +always down. See `Appendix: Robust All-VO Queries`_. The central point is: With a ``servicetype`` constraint, each result has a well-defined ``service`` attribute that contains some @@ -644,3 +644,7 @@ run all-VO queries without reading at least this sentence): 148.204840298431 29.1690999975089 243.044008 -51.778222 321.63278049999997 -54.579285999999996 + +Note that even this is not enough to reliably cover use cases like „give +me all images of M1 in the X-Ray in the VO“. In some future version, +pyVO will come with higher-level functionality for such tasks. diff --git a/pyvo/registry/rtcons.py b/pyvo/registry/rtcons.py index 301a18b0..5d39bfb7 100644 --- a/pyvo/registry/rtcons.py +++ b/pyvo/registry/rtcons.py @@ -11,10 +11,12 @@ """ import datetime +import warnings from astropy import units as u from astropy import constants from astropy.coordinates import SkyCoord +from astropy.utils.exceptions import AstropyDeprecationWarning import numpy from ..dal import query as dalq @@ -356,16 +358,15 @@ class Servicetype(Constraint): The constraint normally is a custom keyword, one of: - * ``image`` (image services; at this point equivalent to sia, but - scheduled to include sia2, too) * ``sia`` (SIAP version 1 services) * ``sia2`` (SIAP version 2 services) - * ``spectrum``, ``ssa``, ``ssap`` (all synonymous for spectral - services, prefer ``spectrum``) + * ``ssa``, ``ssap`` (synonymous for SSAP services) * ``scs``, ``conesearch`` (synonymous for cone search services, prefer ``scs``) * ``line`` (for SLAP services) * ``tap``, ``table`` (synonymous for TAP services, prefer ``tap``) + * ``image`` (a deprecated alias for sia) + * ``spectrum`` (a deprecated alias for ssap) You can also pass in the standards' ivoid (which generally looks like @@ -377,6 +378,15 @@ class Servicetype(Constraint): Multiple service types can be passed in; a match in that case is for records having any of the service types passed in. + Contrary to what the names of the service types may suggest, + “image” and "spectrum" do *not* select all resources serving images + or spectra. For instance, at the moment you would have to search for + images served in three different ways: SIAv1, SIAv2, and ObsTAP. Against + that, “image” only selects SIAv1, and "spectrum" similarly omits ObsTAP. A + global discovery module is under active development to provide global + dataset discovery. When it is ready, these two misleading options may be + removed. + The match is literal (i.e., no patterns are allowed); this means that you will not receive records that only have auxiliary services, which is what you want when enumerating all services @@ -401,6 +411,13 @@ def __init__(self, *stds): self.extra_fragments = [] for std in stds: + if std in ('image', 'spectrum'): + warnings.warn(AstropyDeprecationWarning( + f"The '{std}' servicetype is deprecated. See" + " https://pyvo.readthedocs.io/en/latest/api/pyvo.registry" + ".Servicetype.html#pyvo.registry.Servicetype" + " for more information.")) + if std in SERVICE_TYPE_MAP: self.stdids.add(SERVICE_TYPE_MAP[std]) elif "://" in std: diff --git a/pyvo/registry/tests/test_rtcons.py b/pyvo/registry/tests/test_rtcons.py index 81bc06bc..60b8922e 100644 --- a/pyvo/registry/tests/test_rtcons.py +++ b/pyvo/registry/tests/test_rtcons.py @@ -9,6 +9,8 @@ from astropy.time import Time from astropy import units as u from astropy.coordinates import SkyCoord +from astropy.utils.exceptions import AstropyDeprecationWarning + import numpy import pytest @@ -141,13 +143,13 @@ def test_fulluri(self): == "standard_id IN ('http://extstandards/invention')") def test_multi(self): - assert (rtcons.Servicetype("http://extstandards/invention", "image" + assert (rtcons.Servicetype("http://extstandards/invention", "sia" ).get_search_condition(FAKE_GAVO) == "standard_id IN ('http://extstandards/invention'," " 'ivo://ivoa.net/std/sia')") def test_includeaux(self): - assert (rtcons.Servicetype("http://extstandards/invention", "image" + assert (rtcons.Servicetype("http://extstandards/invention", "sia" ).include_auxiliary_services().get_search_condition(FAKE_GAVO) == "standard_id IN ('http://extstandards/invention'," " 'http://extstandards/invention#aux'," @@ -179,6 +181,16 @@ def test_sia2_aux(self): " OR standard_id like 'ivo://ivoa.net/std/sia#query-2.%'" " OR standard_id like 'ivo://ivoa.net/std/sia#query-aux-2.%'")) + def test_image_deprecated(self): + with pytest.warns(AstropyDeprecationWarning): + assert (rtcons.Servicetype("image").get_search_condition(FAKE_GAVO) + == "standard_id IN ('ivo://ivoa.net/std/sia')") + + def test_spectrum_deprecated(self): + with pytest.warns(AstropyDeprecationWarning): + assert (rtcons.Servicetype("spectrum").get_search_condition(FAKE_GAVO) + == "standard_id IN ('ivo://ivoa.net/std/ssa')") + @pytest.mark.usefixtures('messenger_vocabulary') class TestWavebandConstraint: