Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Enhancements and Fixes

- Support VOTableFile in accessible_table and broadcast_samp [#745]

- Declaratively define new-style standard IDs in Servicetype constraint [#744]

- Fix raise_if_error() to use cached job phase instead of re-polling [#743]

- Add ``pyvo.registry.get_RegTAP_service_url()`` to allow users to inspect the
Expand Down
43 changes: 22 additions & 21 deletions pyvo/registry/rtcons.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@
("image", "sia"),
("sia", "sia"),
("sia1", "sia"),
# SIA2 is irregular
# funky scheme used by SIA2 without breaking everything else
("spectrum", "ssa"),
("ssap", "ssa"),
("ssa", "ssa"),
Expand All @@ -50,6 +48,14 @@
("tap", "tap"),
]}

# New-style standard IDs carry a #fragment with a minor version and cannot
# be matched with equality, so we match them with LIKE patterns instead.
NEW_STYLE_STDIDS = {
"sia2": ("ivo://ivoa.net/std/sia#query-2.%", "ivo://ivoa.net/std/sia#query-aux-2.%"),
"hats": ("ivo://ivoa.net/std/hats#hats-%", None),
"hips": ("ivo://ivoa.net/std/hips#hips-1.%", None),
}


class RegTAPFeatureMissing(dalq.DALQueryError):
"""
Expand Down Expand Up @@ -411,7 +417,7 @@ def __init__(self, *stds):
match records that have any of them.
"""
self.stdids = set()
self.extra_fragments = []
self.like_patterns = set()

for std in stds:
if std in ('image', 'spectrum'):
Expand All @@ -425,38 +431,34 @@ def __init__(self, *stds):
self.stdids.add(SERVICE_TYPE_MAP[std])
elif "://" in std:
self.stdids.add(std)
elif std == 'sia2':
self.extra_fragments.append(
"standard_id like 'ivo://ivoa.net/std/sia#query-2.%'")
elif std == 'hats':
self.extra_fragments.append(
"standard_id like 'ivo://ivoa.net/std/hats#hats-%'")
Comment on lines -431 to -433
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now a breaking change, with this change we remove functionality that handles hats resources, please don't remove it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I've reinstated and have also contacted the HATS folks to look into registration of the standard id.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I promised writing up a paragraph about it in the note 😄

elif std == 'hips':
self.extra_fragments.append(
"standard_id like 'ivo://ivoa.net/std/hips#hipslist-%'")
elif std in NEW_STYLE_STDIDS:
self.like_patterns.add(NEW_STYLE_STDIDS[std][0])
else:
raise dalq.DALQueryError("Service type {} is neither a full"
" standard URI nor one of the bespoke identifiers"
" {}, sia2, hats, hips".format(std, ", ".join(SERVICE_TYPE_MAP)))
" {}, {}".format(std, ", ".join(SERVICE_TYPE_MAP),
", ".join(NEW_STYLE_STDIDS)))

def clone(self):
"""returns a copy of this servicetype constraint.
"""
new_constraint = Servicetype()
new_constraint.stdids = set(self.stdids)
new_constraint.extra_fragments = self.extra_fragments[:]
new_constraint.like_patterns = set(self.like_patterns)
return new_constraint

def get_search_condition(self, service):
# we sort the stdids to make it easy for tests (and it's
# we sort to make it easy for tests (and it's
# virtually free for the small sets we have here).
fragments = []
std_ids = ", ".join(make_sql_literal(s)
for s in sorted(self.stdids))
if std_ids:
fragments.append(f"standard_id IN ({std_ids})")
for pattern in sorted(self.like_patterns):
fragments.append(f"standard_id like '{pattern}'")

return " OR ".join(fragments + self.extra_fragments)
return " OR ".join(fragments)

def include_auxiliary_services(self):
"""returns a Servicetype constraint that has self's
Expand All @@ -465,11 +467,10 @@ def include_auxiliary_services(self):
This is a convenience to maintain registry.search's signature.
"""
expanded = self.clone()
expanded.stdids |= {
std + '#aux' for std in expanded.stdids}
if "standard_id like 'ivo://ivoa.net/std/sia#query-2.%'" in expanded.extra_fragments:
expanded.extra_fragments.append(
"standard_id like 'ivo://ivoa.net/std/sia#query-aux-2.%'")
expanded.stdids |= {std + '#aux' for std in expanded.stdids}
for main_pattern, aux_pattern in NEW_STYLE_STDIDS.values():
if main_pattern in expanded.like_patterns and aux_pattern:
expanded.like_patterns.add(aux_pattern)
return expanded


Expand Down
14 changes: 14 additions & 0 deletions pyvo/registry/tests/test_rtcons.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,20 @@ 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_hats(self):
assert (rtcons.Servicetype("hats").get_search_condition(FAKE_GAVO)
== "standard_id like 'ivo://ivoa.net/std/hats#hats-%'")

def test_hats_aux(self):
# hats has no auxiliary service concept; aux expansion should not add a pattern
constraint = rtcons.Servicetype("hats").include_auxiliary_services()
assert (constraint.get_search_condition(FAKE_GAVO)
== "standard_id like 'ivo://ivoa.net/std/hats#hats-%'")

def test_hips(self):
assert (rtcons.Servicetype("hips").get_search_condition(FAKE_GAVO)
== "standard_id like 'ivo://ivoa.net/std/hips#hips-1.%'")

def test_image_deprecated(self):
with pytest.warns(AstropyDeprecationWarning):
assert (rtcons.Servicetype("image").get_search_condition(FAKE_GAVO)
Expand Down
Loading