Commit f277eea8 authored by Derek Homeier's avatar Derek Homeier
Browse files

Return `QueryResponseTable`, test some range limits

parent 588d8af7
Pipeline #2475 passed with stage
in 3 minutes and 40 seconds
# -*- coding: utf-8 -*-
import warnings
import os
import astropy.units as u
from astropy.time import Time
import sunpy.net.attrs as a
......@@ -9,10 +11,13 @@ from sunpy.net.base_client import BaseClient, QueryResponseTable
from sunpy.util.exceptions import SunpyUserWarning
# from sunpy.net.attrs import Instrument, Level, Physobs, Provider, Time, Wavelength
import sdc.attrs as sattrs
import urllib.parse
import urllib.request
from urllib.error import HTTPError, URLError
import json
import parfive
walker = AttrWalker()
......@@ -227,7 +232,7 @@ class KISClient(BaseClient):
return searches
def search(self, query):
def search(self, query) -> QueryResponseTable:
"""
Query the SDC RESTHeart client for a list of results in the observation collection.
......@@ -238,8 +243,8 @@ class KISClient(BaseClient):
Returns
-------
results : `~sunpy.net.dataretriever.QueryResponse`
A `QueryResponse` instance containing the query result.
results : `~sunpy.net.base_client.QueryResponseTable`
A `QueryResponseTable` instance containing the query result.
"""
# Not very extensively tested on hierarchical queries
if not self._can_handle_query(query):
......@@ -258,10 +263,24 @@ class KISClient(BaseClient):
raise URLError(f'Unable to execute search "{full_url}": {exc}. Confirm that '
f'RESTHeart is running on {self._BASE_URL} and connected.')
return results # QueryResponseTable(results, client=self)
return QueryResponseTable(results, client=self)
def fetch(self):
""""""
def fetch(self, query_results: QueryResponseTable, *, downloader: parfive.Downloader,
path: os.PathLike = None, binary: bool = False, **kwargs):
"""
Fetch GridFS dataset metadata or binary files.
Parameters
----------
query_results:
Results to download.
path : `str` or `pathlib.Path`, optional
Path to the download directory
downloader : `parfive.Downloader`
The download manager to use.
binary : bool, optional
Fetch the binary data for the dataset (default: metadata).
"""
@classmethod
def _can_handle_query(cls, *query, hasinstr=False):
......@@ -351,7 +370,7 @@ class KISClient(BaseClient):
("TESOS", "TESOS/VIP 2D Fabry-Perot interferometric spectrometer @ VTT"),
("LARS", "Lars is an Absolute Reference Spectrograph @ VTT")],
# ("HiFi", "High-resolution Fast Imager @ Gregor"), # 404 error
# ("TIP-I", "Tenerife Infrared Polarimeter @ VTT"), # name?
# ("TIP-II", "Tenerife Infrared Polarimeter @ VTT"), # name?
# ("ZIMPOL", "Zeeman Imaging Polarimeter @ Gregor"), # 404 error
# description.TELESCOPE - Name of the telescope
a.sdc.Telescope: [("ChroTel", "10 cm Chromospheric Telescope, Observatorio del Teide"),
......
import pytest
import urllib.request
from urllib.error import HTTPError, URLError
import json
import pytest
import astropy.units as u
from sunpy.net import attrs as a
from sunpy.net.base_client import QueryResponseTable
from sdc.client import KISClient
......@@ -49,6 +50,7 @@ def test_docker(client):
assert 'description' in data['_embedded'][0]
res = client.search(a.Instrument("GRIS") & a.sdc.ObsName('gris_20140426_000'))
assert isinstance(res, QueryResponseTable)
assert len(res) == 1
description = res[0]['_embedded'][0].get('description')
assert description['INSTRUMENT'] == 'gris'
......@@ -74,7 +76,8 @@ def test_search(client):
assert client._can_handle_query(query)
if HAS_DOCKERTEST:
res = client.search(query)
if len(res) > 0 and len(res[0].get('_embedded')) > 0:
assert isinstance(res, QueryResponseTable)
if len(res[0].get('_embedded')) > 0:
assert 'description' in res[0]['_embedded'][0]
else:
with pytest.raises(URLError, match=r"Unable to execute search "
......@@ -89,7 +92,7 @@ def test_search(client):
assert client._can_handle_query(query)
if HAS_DOCKERTEST:
res = client.search(query)
if len(res) > 0 and len(res[0].get('_embedded')) > 0:
if len(res[0].get('_embedded')) > 0:
assert 'description' in res[0]['_embedded'][0]
else:
with pytest.raises(URLError, match=r"Unable to execute search "
......@@ -103,7 +106,8 @@ def test_search(client):
assert client._can_handle_query(query)
if HAS_DOCKERTEST:
res = client.search(query)
if len(res) > 0 and len(res[0].get('_embedded')) > 0:
assert len(res) == 2
if len(res[0].get('_embedded')) > 0:
assert 'description' in res[0]['_embedded'][0]
else:
with pytest.raises(URLError, match=r"Unable to execute search ") as exc:
......@@ -145,7 +149,7 @@ def test_all_queries(client, query):
assert client._can_handle_query(a.Instrument("GRIS"), query)
if HAS_DOCKERTEST:
res = client.search(a.Instrument("GRIS") & query)
if len(res) > 0 and len(res[0].get('_embedded')) > 0:
if len(res[0].get('_embedded')) > 0:
assert 'description' in res[0]['_embedded'][0]
else:
with pytest.raises(URLError, match=r"Unable to execute search "
......@@ -155,6 +159,28 @@ def test_all_queries(client, query):
client.search(a.Instrument("GRIS") & query)
def test_range(client):
"""
Test range filter - 'FIELD_MIN,_MAX' shall include at least one of `Attr.min`, `Attr.max`.
"""
wl = a.Wavelength(10800*u.AA, 1.25*u.micron)
query = a.Instrument("GRIS") & wl
assert client._can_handle_query(query)
if HAS_DOCKERTEST:
res = client.search(query)
wave_min = [obs['description']['WAVELENGTH_MIN'] for obs in res[0]['_embedded']]
wave_max = [obs['description']['WAVELENGTH_MAX'] for obs in res[0]['_embedded']]
assert max(wave_min) <= 1250
assert min(wave_max) >= 1080
else:
with pytest.raises(URLError, match=r"Unable to execute search "
r".http://dockertest:8083/sdc/gris_observations.filter="
r"{'.and':.{'description.INSTRUMENT':'gris'},"
r"{'description.WAVELENGTH_MIN':{'.lte':1250}},"
r"{'description.WAVELENGTH_MAX':{'.gte':1080}}"):
client.search(query)
def test_full_range(client):
"""
Test 'fullrange' option - 'FIELD_MIN,_MAX' shall completely include `[Attr.min, Attr.max]`.
......@@ -166,7 +192,7 @@ def test_full_range(client):
assert client._can_handle_query(query)
if HAS_DOCKERTEST:
res = client.search(query)
if len(res) > 0 and len(res[0].get('_embedded')) > 0:
if len(res[0].get('_embedded')) > 0:
assert 'description' in res[0]['_embedded'][0]
else:
with pytest.raises(URLError, match=r"Unable to execute search "
......@@ -177,18 +203,35 @@ def test_full_range(client):
client.search(query)
# Test with inverted `min`, `max` inputs.
hplt = a.sdc.HelioProjLat(0.2*u.arcmin, -10*u.arcsec)
hplt = a.sdc.HelioProjLat(0.1*u.arcmin, -2*u.arcsec)
query = a.Instrument("LARS") & hplt
if HAS_DOCKERTEST:
res = client.search(query)
hplt_tan_min = [obs['description']['HPLT_TAN_MIN'] for obs in res[0]['_embedded']]
hplt_tan_max = [obs['description']['HPLT_TAN_MAX'] for obs in res[0]['_embedded']]
assert max(hplt_tan_min) <= 6
assert min(hplt_tan_max) >= -2
else:
with pytest.raises(URLError, match=r"Unable to execute search "
r".http://dockertest:8083/sdc/lars_observations.filter="
r"{'.and':.{'description.INSTRUMENT':'lars'},"
r"{'description.HPLT_TAN_MIN':{'.lte':6}},"
r"{'description.HPLT_TAN_MAX':{'.gte':-2}}"):
client.search(query)
hplt.fullrange = True
query = a.Instrument("LARS") & hplt
assert client._can_handle_query(query)
if HAS_DOCKERTEST:
res = client.search(query)
if len(res) > 0 and len(res[0].get('_embedded')) > 0:
assert 'description' in res[0]['_embedded'][0]
hplt_tan_min = [obs['description']['HPLT_TAN_MIN'] for obs in res[0]['_embedded']]
hplt_tan_max = [obs['description']['HPLT_TAN_MAX'] for obs in res[0]['_embedded']]
assert max(hplt_tan_min) <= -2
assert min(hplt_tan_max) >= 6
else:
with pytest.raises(URLError, match=r"Unable to execute search "
r".http://dockertest:8083/sdc/lars_observations.filter="
r"{'.and':.{'description.INSTRUMENT':'lars'},"
r"{'description.HPLT_TAN_MIN':{'.lte':-10}},"
r"{'description.HPLT_TAN_MAX':{'.gte':12\}}"):
r"{'description.HPLT_TAN_MIN':{'.lte':-2}},"
r"{'description.HPLT_TAN_MAX':{'.gte':6}}"):
client.search(query)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment