hdpws 0.6.8__tar.gz → 0.6.19__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,12 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hdpws
3
- Version: 0.6.8
3
+ Version: 0.6.19
4
4
  Summary: NASA's Heliophysics Data Portal Web Service Client Library
5
5
  Home-page: https://heliophysicsdata.gsfc.nasa.gov/WebServices
6
6
  Author: Bernie Harris
7
7
  Author-email: NASA-SPDF-Support@nasa.onmicrosoft.com
8
8
  License: NOSA
9
9
  Keywords: heliophysics,spase,space physics,spdf,hdp
10
- Platform: UNKNOWN
11
10
  Classifier: Development Status :: 3 - Alpha
12
11
  Classifier: Environment :: Console
13
12
  Classifier: Environment :: Web Environment
@@ -98,5 +97,3 @@ Bernie Harris.
98
97
 
99
98
  This code is licensed under the
100
99
  [NASA Open Source Agreement](https://cdaweb.gsfc.nasa.gov/WebServices/NASA_Open_Source_Agreement_1.3.txt) (NOSA).
101
-
102
-
@@ -41,7 +41,7 @@ the United States under Title 17, U.S.Code. All Other Rights Reserved.
41
41
  """
42
42
 
43
43
 
44
- __version__ = "0.6.8"
44
+ __version__ = "0.6.19"
45
45
 
46
46
 
47
47
  #
@@ -147,6 +147,23 @@ def example(
147
147
  disable_ssl_certificate_validation, user_agent='Example')
148
148
 
149
149
 
150
+ result = hdp.get_application_interfaces()
151
+ if result['HttpStatus'] == 200:
152
+ print('HDP ApplicationInterfaces:')
153
+ for value in result['ApplicationInterface']:
154
+ print(f' {value}')
155
+ else:
156
+ print_error('hdp.get_application_interfaces', result)
157
+
158
+ result = hdp.get_keywords()
159
+ if result['HttpStatus'] == 200:
160
+ print('HDP Keywords:')
161
+ for value in result['Keyword'][0:5]:
162
+ print(f' {value}')
163
+ print(' ...')
164
+ else:
165
+ print_error('hdp.get_keywords', result)
166
+
150
167
  result = hdp.get_instrument_ids()
151
168
  if result['HttpStatus'] == 200:
152
169
  print('HDP InstrumentIDs:')
@@ -325,6 +342,7 @@ def example(
325
342
  'InstrumentID': 'spase://SMWG/Instrument/ACE/MAG',
326
343
  'PhenomenonType': 'MagneticCloud',
327
344
  'Description': 'ICME'
345
+ # 'Keyword': 'current sheet'
328
346
  }
329
347
  time_range = ['1999-01-01', '1999-01-02']
330
348
 
@@ -385,6 +403,27 @@ def example(
385
403
  print_error('hdp.get_spase_document', result)
386
404
 
387
405
 
406
+ query = {
407
+ 'ResourceID': 'spase://CCMC/Software/Kamodo',
408
+ 'CodeLanguage': 'Python',
409
+ 'Description': '"space weather models and data"'
410
+ }
411
+
412
+
413
+ if result['HttpStatus'] == 200:
414
+ #print('HDP Spase:')
415
+ #print(ET.tostring(result['Result']))
416
+ print('Result Software:')
417
+ for software in result['Result'].findall('.//Software', namespaces=NS):
418
+ print(software.findall('.//ResourceID', namespaces=NS)[0].text)
419
+ print(' ', software.findall('.//ResourceName', namespaces=NS)[0].text)
420
+ #ET.indent(software)
421
+ #print(ET.tostring(software, encoding='unicode',
422
+ # default_namespace=SPASE_NS))
423
+ else:
424
+ print_error('hdp.get_spase_software', result)
425
+
426
+
388
427
  def print_error(
389
428
  label: str,
390
429
  result: Dict
@@ -197,6 +197,61 @@ class HdpWs:
197
197
  return self._endpoint
198
198
 
199
199
 
200
+ def get_application_interfaces(
201
+ self
202
+ ) -> Dict:
203
+ """
204
+ Gets all /Spase/Software/ApplicationInterface values available at HDP.
205
+
206
+ Returns
207
+ -------
208
+ Dict
209
+ Dictionary containing a 'ApplicationInterface' key with a value
210
+ of a List containing all /Spase/Software/ApplicationInterface values
211
+ with the addition of the following key/values:<br>
212
+ - HttpStatus: with the value of the HTTP status code.
213
+ Successful == 200.<br>
214
+ When HttpStatus != 200:<br>
215
+ - HttpText: containing a string representation of the HTTP
216
+ entity body.<br>
217
+ When HttpText is a standard HDP WS error entity body the
218
+ following key/values (convenience to avoid parsing
219
+ HttpStatus):<br>
220
+ - ErrorMessage: value from HttpText.<br>
221
+ - ErrorDescription: value from HttpText.<br>
222
+ """
223
+ return self.__get_simple_resource('Spase/ApplicationInterface',
224
+ 'ApplicationInterface',
225
+ 'ApplicationInterface')
226
+
227
+ def get_keywords(
228
+ self
229
+ ) -> Dict:
230
+ """
231
+ Gets all //Keyword values available at HDP.
232
+
233
+ Returns
234
+ -------
235
+ Dict
236
+ Dictionary containing a 'Keyword' key with a value
237
+ of a List containing all /Keyword values
238
+ with the addition of the following key/values:<br>
239
+ - HttpStatus: with the value of the HTTP status code.
240
+ Successful == 200.<br>
241
+ When HttpStatus != 200:<br>
242
+ - HttpText: containing a string representation of the HTTP
243
+ entity body.<br>
244
+ When HttpText is a standard HDP WS error entity body the
245
+ following key/values (convenience to avoid parsing
246
+ HttpStatus):<br>
247
+ - ErrorMessage: value from HttpText.<br>
248
+ - ErrorDescription: value from HttpText.<br>
249
+ """
250
+ return self.__get_simple_resource('Spase/Keyword',
251
+ 'Keyword',
252
+ 'Keyword')
253
+
254
+
200
255
  def get_instrument_ids(
201
256
  self
202
257
  ) -> Dict:
@@ -790,6 +845,45 @@ class HdpWs:
790
845
  return self.__get_complex_resource([ResourceType.DOCUMENT], query)
791
846
 
792
847
 
848
+ def get_spase_software(
849
+ self,
850
+ query: Dict
851
+ ) -> Dict:
852
+ """
853
+ Gets the specified SPASE Software documents from HDP.
854
+
855
+ Parameters
856
+ ----------
857
+ query
858
+ Dictionary containing query parameters and values. For
859
+ example,<pre>
860
+ query = {
861
+ 'ResourceID': 'spase://CCMC/Software/Kamodo',
862
+ 'CodeLanguage': 'Python',
863
+ 'Description': '"space weather models and data"'
864
+ }</pre>
865
+
866
+ Returns
867
+ -------
868
+ Dict
869
+ Dictionary containing a 'Result' key with a value of an
870
+ ElementTree representation of the results as described by
871
+ <https://heliophysicsdata.gsfc.nasa.gov/WebServices/hdpspase.xsd>
872
+ with the addition of the following key/values:<br>
873
+ - HttpStatus: with the value of the HTTP status code.
874
+ Successful == 200.<br>
875
+ When HttpStatus != 200:<br>
876
+ - HttpText: containing a string representation of the HTTP
877
+ entity body.<br>
878
+ When HttpText is a standard HDP WS error entity body the
879
+ following key/values (convenience to avoid parsing
880
+ HttpStatus):<br>
881
+ - ErrorMessage: value from HttpText.<br>
882
+ - ErrorDescription: value from HttpText.<br>
883
+ """
884
+ return self.__get_complex_resource([ResourceType.SOFTWARE], query)
885
+
886
+
793
887
  def __get_simple_resource(
794
888
  self,
795
889
  resource: str,
@@ -52,3 +52,4 @@ class ResourceType(Enum):
52
52
  DISPLAY_DATA = 'DisplayData'
53
53
  OBSERVATORY = 'Observatory'
54
54
  SERVICE = 'Service'
55
+ SOFTWARE = 'Software'
@@ -1,13 +1,12 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hdpws
3
- Version: 0.6.8
3
+ Version: 0.6.19
4
4
  Summary: NASA's Heliophysics Data Portal Web Service Client Library
5
5
  Home-page: https://heliophysicsdata.gsfc.nasa.gov/WebServices
6
6
  Author: Bernie Harris
7
7
  Author-email: NASA-SPDF-Support@nasa.onmicrosoft.com
8
8
  License: NOSA
9
9
  Keywords: heliophysics,spase,space physics,spdf,hdp
10
- Platform: UNKNOWN
11
10
  Classifier: Development Status :: 3 - Alpha
12
11
  Classifier: Environment :: Console
13
12
  Classifier: Environment :: Web Environment
@@ -98,5 +97,3 @@ Bernie Harris.
98
97
 
99
98
  This code is licensed under the
100
99
  [NASA Open Source Agreement](https://cdaweb.gsfc.nasa.gov/WebServices/NASA_Open_Source_Agreement_1.3.txt) (NOSA).
101
-
102
-
@@ -11,4 +11,8 @@ hdpws.egg-info/PKG-INFO
11
11
  hdpws.egg-info/SOURCES.txt
12
12
  hdpws.egg-info/dependency_links.txt
13
13
  hdpws.egg-info/requires.txt
14
- hdpws.egg-info/top_level.txt
14
+ hdpws.egg-info/top_level.txt
15
+ tests/test_access_information.py
16
+ tests/test_access_url.py
17
+ tests/test_dateinterval.py
18
+ tests/test_hdpws.py
@@ -10,7 +10,7 @@ README = (HERE / "README.md").read_text()
10
10
  # This call to setup() does all the work
11
11
  setup(
12
12
  name="hdpws",
13
- version="0.6.8",
13
+ version="0.6.19",
14
14
  description="NASA's Heliophysics Data Portal Web Service Client Library",
15
15
  long_description=README,
16
16
  long_description_content_type="text/markdown",
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env python3
2
+
3
+ #
4
+ # NOSA HEADER START
5
+ #
6
+ # The contents of this file are subject to the terms of the NASA Open
7
+ # Source Agreement (NOSA), Version 1.3 only (the "Agreement"). You may
8
+ # not use this file except in compliance with the Agreement.
9
+ #
10
+ # You can obtain a copy of the agreement at
11
+ # docs/NASA_Open_Source_Agreement_1.3.txt
12
+ # or
13
+ # https://cdaweb.gsfc.nasa.gov/WebServices/NASA_Open_Source_Agreement_1.3.txt.
14
+ #
15
+ # See the Agreement for the specific language governing permissions
16
+ # and limitations under the Agreement.
17
+ #
18
+ # When distributing Covered Code, include this NOSA HEADER in each
19
+ # file and include the Agreement file at
20
+ # docs/NASA_Open_Source_Agreement_1.3.txt. If applicable, add the
21
+ # following below this NOSA HEADER, with the fields enclosed by
22
+ # brackets "[]" replaced with your own identifying information:
23
+ # Portions Copyright [yyyy] [name of copyright owner]
24
+ #
25
+ # NOSA HEADER END
26
+ #
27
+ # Copyright (c) 2023 United States Government as represented by
28
+ # the National Aeronautics and Space Administration. No copyright is
29
+ # claimed in the United States under Title 17, U.S.Code. All Other
30
+ # Rights Reserved.
31
+ #
32
+
33
+ """
34
+ Module for unittest of the AccessURL class.<br>
35
+
36
+ Copyright &copy; 2023 United States Government as represented by the
37
+ National Aeronautics and Space Administration. No copyright is claimed in
38
+ the United States under Title 17, U.S.Code. All Other Rights Reserved.
39
+ """
40
+
41
+ import unittest
42
+ import xml.etree.ElementTree as ET
43
+ import copy
44
+
45
+ from context import hdpws # pylint: disable=unused-import
46
+
47
+ from hdpws import NAMESPACES as NS
48
+ from hdpws.spase import AccessInformation # pylint: disable=import-error
49
+
50
+
51
+ BAD_ACCESS_INFO = ET.fromstring('<BadAccessInformation/>')
52
+
53
+ TEST_REPOSITORY_ID = 'spase://SMWG/Repository/NASA/GSFC/SPDF'
54
+ TEST_AVAILABILITY = 'Online'
55
+ TEST_ACCESS_RIGHTS = 'Open'
56
+ TEST_NAME = 'CDAWeb HAPI Server'
57
+ TEST_URL = 'https://cdaweb.gsfc.nasa.gov/hapi'
58
+ TEST_STYLE = 'HAPI'
59
+ TEST_PRODUCT_KEYS = ['WI_H0_MFI@0', 'WI_H0_MFI@1', 'WI_H0_MFI@2']
60
+ TEST_DESCRIPTION = 'Web Service to this product using the HAPI interface.'
61
+ TEST_LANGUAGE = 'en'
62
+ TEST_FORMAT = 'CSV'
63
+
64
+ TEST_ACCESS_INFO = ET.fromstring(
65
+ '<AccessInformation xmlns="http://www.spase-group.org/data/schema">\
66
+ <RepositoryID>' + TEST_REPOSITORY_ID + '</RepositoryID>\
67
+ <Availability>' + TEST_AVAILABILITY + '</Availability>\
68
+ <AccessRights>' + TEST_ACCESS_RIGHTS + '</AccessRights>\
69
+ <AccessURL>\
70
+ <Name>' + TEST_NAME + '</Name>\
71
+ <URL>' + TEST_URL + '</URL>\
72
+ <Style>' + TEST_STYLE + '</Style>\
73
+ <ProductKey>' + TEST_PRODUCT_KEYS[0] + '</ProductKey>\
74
+ <ProductKey>' + TEST_PRODUCT_KEYS[1] + '</ProductKey>\
75
+ <ProductKey>' + TEST_PRODUCT_KEYS[2] + '</ProductKey>\
76
+ <Description>' + TEST_DESCRIPTION + '</Description>\
77
+ <Language>' + TEST_LANGUAGE + '</Language>\
78
+ </AccessURL>\
79
+ <Format>' + TEST_FORMAT + '</Format>\
80
+ </AccessInformation>')
81
+
82
+
83
+ class TestAccessInformation(unittest.TestCase):
84
+ """
85
+ Class for unittest of AccessInformation class.
86
+ """
87
+
88
+ def __init__(self, *args, **kwargs):
89
+ super(TestAccessInformation, self).__init__(*args, **kwargs)
90
+
91
+
92
+ def test_access_information_exception(self):
93
+ """
94
+ Test for constructor exception.
95
+ """
96
+
97
+ with self.assertRaises(ValueError):
98
+ AccessInformation(BAD_ACCESS_INFO)
99
+
100
+
101
+
102
+ def test_access_information_properties(self):
103
+ """
104
+ Test for AccessInformation properties.
105
+ """
106
+
107
+ access_info = AccessInformation(TEST_ACCESS_INFO)
108
+
109
+ self.assertEqual(access_info.repository_id, TEST_REPOSITORY_ID)
110
+ self.assertEqual(access_info.availability, TEST_AVAILABILITY)
111
+ self.assertEqual(access_info.access_rights, TEST_ACCESS_RIGHTS)
112
+ self.assertListEqual(access_info.format, [TEST_FORMAT])
113
+
114
+
115
+
116
+ if __name__ == '__main__':
117
+ unittest.main()
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env python3
2
+
3
+ #
4
+ # NOSA HEADER START
5
+ #
6
+ # The contents of this file are subject to the terms of the NASA Open
7
+ # Source Agreement (NOSA), Version 1.3 only (the "Agreement"). You may
8
+ # not use this file except in compliance with the Agreement.
9
+ #
10
+ # You can obtain a copy of the agreement at
11
+ # docs/NASA_Open_Source_Agreement_1.3.txt
12
+ # or
13
+ # https://cdaweb.gsfc.nasa.gov/WebServices/NASA_Open_Source_Agreement_1.3.txt.
14
+ #
15
+ # See the Agreement for the specific language governing permissions
16
+ # and limitations under the Agreement.
17
+ #
18
+ # When distributing Covered Code, include this NOSA HEADER in each
19
+ # file and include the Agreement file at
20
+ # docs/NASA_Open_Source_Agreement_1.3.txt. If applicable, add the
21
+ # following below this NOSA HEADER, with the fields enclosed by
22
+ # brackets "[]" replaced with your own identifying information:
23
+ # Portions Copyright [yyyy] [name of copyright owner]
24
+ #
25
+ # NOSA HEADER END
26
+ #
27
+ # Copyright (c) 2023 United States Government as represented by
28
+ # the National Aeronautics and Space Administration. No copyright is
29
+ # claimed in the United States under Title 17, U.S.Code. All Other
30
+ # Rights Reserved.
31
+ #
32
+
33
+ """
34
+ Module for unittest of the AccessURL class.<br>
35
+
36
+ Copyright &copy; 2023 United States Government as represented by the
37
+ National Aeronautics and Space Administration. No copyright is claimed in
38
+ the United States under Title 17, U.S.Code. All Other Rights Reserved.
39
+ """
40
+
41
+ import unittest
42
+ import xml.etree.ElementTree as ET
43
+ import copy
44
+
45
+ from context import hdpws # pylint: disable=unused-import
46
+
47
+ from hdpws import NAMESPACES as NS
48
+ from hdpws.spase import AccessURL, HapiAccessURL, HAPI_DISPLAY_URL # pylint: disable=import-error
49
+
50
+
51
+ BAD_ACCESS_URL = ET.fromstring('<BadAccessUrl/>')
52
+
53
+ TEST_NAME = 'CDAWeb HAPI Server'
54
+ TEST_URL = 'https://cdaweb.gsfc.nasa.gov/hapi'
55
+ TEST_STYLE = 'HAPI'
56
+ TEST_PRODUCT_KEYS = ['WI_H0_MFI@0', 'WI_H0_MFI@1', 'WI_H0_MFI@2']
57
+ TEST_DESCRIPTION = 'Web Service to this product using the HAPI interface.'
58
+ TEST_LANGUAGE = 'en'
59
+
60
+ TEST_ACCESS_URL = ET.fromstring(
61
+ '<AccessURL xmlns="http://www.spase-group.org/data/schema">\
62
+ <Name>' + TEST_NAME + '</Name>\
63
+ <URL>' + TEST_URL + '</URL>\
64
+ <Style>' + TEST_STYLE + '</Style>\
65
+ <ProductKey>' + TEST_PRODUCT_KEYS[0] + '</ProductKey>\
66
+ <ProductKey>' + TEST_PRODUCT_KEYS[1] + '</ProductKey>\
67
+ <ProductKey>' + TEST_PRODUCT_KEYS[2] + '</ProductKey>\
68
+ <Description>' + TEST_DESCRIPTION + '</Description>\
69
+ <Language>' + TEST_LANGUAGE + '</Language>\
70
+ </AccessURL>')
71
+
72
+
73
+ class TestAccessURL(unittest.TestCase):
74
+ """
75
+ Class for unittest of AccessURL class.
76
+ """
77
+
78
+ def __init__(self, *args, **kwargs):
79
+ super(TestAccessURL, self).__init__(*args, **kwargs)
80
+
81
+
82
+ def test_access_url_exception(self):
83
+ """
84
+ Test for constructor exception.
85
+ """
86
+
87
+ with self.assertRaises(ValueError):
88
+ AccessURL(BAD_ACCESS_URL)
89
+
90
+
91
+
92
+ def test_access_url_properties(self):
93
+ """
94
+ Test for AccessURL properties.
95
+ """
96
+
97
+ access_url = AccessURL(TEST_ACCESS_URL)
98
+
99
+ self.assertEqual(access_url.name, TEST_NAME)
100
+ self.assertEqual(access_url.url, TEST_URL)
101
+ self.assertEqual(access_url.style, TEST_STYLE)
102
+ for idx, product_key in enumerate(access_url.product_key):
103
+ self.assertEqual(product_key, TEST_PRODUCT_KEYS[idx])
104
+ self.assertEqual(access_url.description, TEST_DESCRIPTION)
105
+ self.assertEqual(access_url.language, TEST_LANGUAGE)
106
+
107
+
108
+ class TestHapiAccessURL(unittest.TestCase):
109
+ """
110
+ Class for unittest of HapiAccessURL class.
111
+ """
112
+
113
+ def __init__(self, *args, **kwargs):
114
+ super(TestHapiAccessURL, self).__init__(*args, **kwargs)
115
+
116
+
117
+ def test_hapi_access_url_exception(self):
118
+ """
119
+ Test for constructor exception.
120
+ """
121
+
122
+ hapi_access_url = copy.deepcopy(TEST_ACCESS_URL)
123
+ style = hapi_access_url.find('Style', namespaces=NS)
124
+ self.assertIsNotNone(style)
125
+ style.text = 'WebService'
126
+
127
+ with self.assertRaises(ValueError):
128
+ HapiAccessURL(hapi_access_url)
129
+
130
+ def test_get_html_url(self):
131
+ """
132
+ Test for get_html_url method.
133
+ """
134
+
135
+ hapi_access_url = HapiAccessURL(TEST_ACCESS_URL)
136
+
137
+ self.assertEqual(hapi_access_url.get_html_url(),
138
+ HAPI_DISPLAY_URL + '#url=' + hapi_access_url.url + \
139
+ '&id=' + TEST_PRODUCT_KEYS[0] + ',' + \
140
+ TEST_PRODUCT_KEYS[1] + ',' + \
141
+ TEST_PRODUCT_KEYS[2])
142
+
143
+
144
+ if __name__ == '__main__':
145
+ unittest.main()
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env python3
2
+
3
+ #
4
+ # NOSA HEADER START
5
+ #
6
+ # The contents of this file are subject to the terms of the NASA Open
7
+ # Source Agreement (NOSA), Version 1.3 only (the "Agreement"). You may
8
+ # not use this file except in compliance with the Agreement.
9
+ #
10
+ # You can obtain a copy of the agreement at
11
+ # docs/NASA_Open_Source_Agreement_1.3.txt
12
+ # or
13
+ # https://cdaweb.gsfc.nasa.gov/WebServices/NASA_Open_Source_Agreement_1.3.txt.
14
+ #
15
+ # See the Agreement for the specific language governing permissions
16
+ # and limitations under the Agreement.
17
+ #
18
+ # When distributing Covered Code, include this NOSA HEADER in each
19
+ # file and include the Agreement file at
20
+ # docs/NASA_Open_Source_Agreement_1.3.txt. If applicable, add the
21
+ # following below this NOSA HEADER, with the fields enclosed by
22
+ # brackets "[]" replaced with your own identifying information:
23
+ # Portions Copyright [yyyy] [name of copyright owner]
24
+ #
25
+ # NOSA HEADER END
26
+ #
27
+ # Copyright (c) 2023 United States Government as represented by
28
+ # the National Aeronautics and Space Administration. No copyright is
29
+ # claimed in the United States under Title 17, U.S.Code. All Other
30
+ # Rights Reserved.
31
+ #
32
+
33
+ """
34
+ Module for unittest of the DateInterval class.<br>
35
+
36
+ Copyright &copy; 2023 United States Government as represented by the
37
+ National Aeronautics and Space Administration. No copyright is claimed in
38
+ the United States under Title 17, U.S.Code. All Other Rights Reserved.
39
+ """
40
+
41
+ import unittest
42
+ from datetime import date
43
+
44
+ from context import hdpws # pylint: disable=unused-import
45
+
46
+ from hdpws.dateinterval import DateInterval # pylint: disable=import-error
47
+
48
+
49
+
50
+ class TestDateInterval(unittest.TestCase):
51
+ """
52
+ Class for unittest of DateInterval class.
53
+ """
54
+
55
+ def __init__(self, *args, **kwargs):
56
+ super(TestDateInterval, self).__init__(*args, **kwargs)
57
+
58
+
59
+ def test_get_date_exceptions(self):
60
+ """
61
+ Test for get_date function exceptions.
62
+ """
63
+
64
+ with self.assertRaises(ValueError):
65
+ DateInterval.get_date(123)
66
+
67
+ with self.assertRaises(ValueError):
68
+ DateInterval.get_date('bad_date')
69
+
70
+
71
+ def test_get_dates_exceptions(self):
72
+ """
73
+ Test for get_date function.
74
+ """
75
+
76
+ with self.assertRaises(ValueError):
77
+ DateInterval.get_dates('2020-01-01', 123)
78
+
79
+ with self.assertRaises(ValueError):
80
+ DateInterval.get_dates('2020-01-01', 'bad_date')
81
+
82
+
83
+ def test_date_interval_init(self):
84
+ """
85
+ Test for DateInterval constructor.
86
+ """
87
+
88
+ self.assertEqual(DateInterval.get_date('2023-01-01'),
89
+ date(2023, 1, 1))
90
+
91
+
92
+ def test_date_interval_eq(self):
93
+ """
94
+ Test for DateInterval equality operator.
95
+ """
96
+
97
+ t_1 = DateInterval('2023-01-01', '2023-01-02')
98
+ t_2 = DateInterval(date(2023, 1, 1),
99
+ date(2023, 1, 2))
100
+
101
+ self.assertEqual(t_1, t_2)
102
+
103
+
104
+ def test_date_interval_str(self):
105
+ """
106
+ Test DateInterval.str().
107
+ """
108
+
109
+ t_1 = DateInterval(date(2023, 1, 1),
110
+ date(2023, 1, 2))
111
+
112
+ self.assertEqual(str(t_1),
113
+ '2023-01-01,2023-01-02')
114
+
115
+
116
+ def test_date_interval_properties(self):
117
+ """
118
+ Test DateInterval properties.
119
+ """
120
+
121
+ t_1 = DateInterval(date(2023, 1, 1),
122
+ date(2023, 1, 2))
123
+
124
+ t_1.start = date(2020, 1, 1)
125
+ t_1.end = date(2020, 1, 2)
126
+
127
+ self.assertEqual(t_1.start, date(2020, 1, 1))
128
+ self.assertEqual(t_1.end, date(2020, 1, 2))
129
+
130
+
131
+ if __name__ == '__main__':
132
+ unittest.main()
@@ -0,0 +1,438 @@
1
+ #!/usr/bin/env python3
2
+
3
+ #
4
+ # NOSA HEADER START
5
+ #
6
+ # The contents of this file are subject to the terms of the NASA Open
7
+ # Source Agreement (NOSA), Version 1.3 only (the "Agreement"). You may
8
+ # not use this file except in compliance with the Agreement.
9
+ #
10
+ # You can obtain a copy of the agreement at
11
+ # docs/NASA_Open_Source_Agreement_1.3.txt
12
+ # or
13
+ # https://cdaweb.gsfc.nasa.gov/WebServices/NASA_Open_Source_Agreement_1.3.txt.
14
+ #
15
+ # See the Agreement for the specific language governing permissions
16
+ # and limitations under the Agreement.
17
+ #
18
+ # When distributing Covered Code, include this NOSA HEADER in each
19
+ # file and include the Agreement file at
20
+ # docs/NASA_Open_Source_Agreement_1.3.txt. If applicable, add the
21
+ # following below this NOSA HEADER, with the fields enclosed by
22
+ # brackets "[]" replaced with your own identifying information:
23
+ # Portions Copyright [yyyy] [name of copyright owner]
24
+ #
25
+ # NOSA HEADER END
26
+ #
27
+ # Copyright (c) 2023 United States Government as represented by
28
+ # the National Aeronautics and Space Administration. No copyright is
29
+ # claimed in the United States under Title 17, U.S.Code. All Other
30
+ # Rights Reserved.
31
+ #
32
+
33
+ """
34
+ Module for unittest of the HdpWs class.<br>
35
+
36
+ Copyright &copy; 2023 United States Government as represented by the
37
+ National Aeronautics and Space Administration. No copyright is claimed in
38
+ the United States under Title 17, U.S.Code. All Other Rights Reserved.
39
+ """
40
+
41
+ import unittest
42
+ import datetime
43
+ import xml.etree.ElementTree as ET
44
+
45
+ from context import hdpws # pylint: disable=unused-import
46
+
47
+ from hdpws.hdpws import HdpWs # pylint: disable=import-error
48
+ from hdpws import XHTML_NS, NAMESPACES as NS
49
+ from hdpws.resourcetype import ResourceType as rt
50
+
51
+
52
+ # More checks of the following result should probably be added
53
+ # but more checks risk failing when the contents of the database
54
+ # changes.
55
+
56
+ class TestHdpWs(unittest.TestCase):
57
+ """
58
+ Class for unittest of HdpWs class.
59
+ """
60
+
61
+ def __init__(self, *args, **kwargs):
62
+ super(TestHdpWs, self).__init__(*args, **kwargs)
63
+ self._hdp = HdpWs(endpoint='http://localhost:8080/exist/restxq/')
64
+
65
+
66
+ def test_get_application_interfaces(self):
67
+ """
68
+ Test for get_application_interfaces function.
69
+ """
70
+
71
+ result = self._hdp.get_application_interfaces()
72
+
73
+ self.assertEqual(result['HttpStatus'], 200)
74
+ application_interfaces = result['ApplicationInterface']
75
+ self.assertTrue(len(application_interfaces) > 0)
76
+ self.assertTrue(application_interfaces[0] == 'CLI')
77
+
78
+
79
+ def test_get_keywords(self):
80
+ """
81
+ Test for get_keywords function.
82
+ """
83
+
84
+ result = self._hdp.get_keywords()
85
+
86
+ self.assertEqual(result['HttpStatus'], 200)
87
+ keywords = result['Keyword']
88
+ self.assertTrue(len(keywords) > 0)
89
+
90
+
91
+ def test_get_instrument_ids(self):
92
+ """
93
+ Test for get_instrument_ids function.
94
+ """
95
+
96
+ result = self._hdp.get_instrument_ids()
97
+
98
+ self.assertEqual(result['HttpStatus'], 200)
99
+ instr_ids = result['InstrumentID']
100
+ self.assertTrue(len(instr_ids) > 0)
101
+
102
+
103
+ def test_get_repository_ids(self):
104
+ """
105
+ Test for get_repository_ids function.
106
+ """
107
+
108
+ result = self._hdp.get_repository_ids()
109
+
110
+ self.assertEqual(result['HttpStatus'], 200)
111
+ repo_ids = result['RepositoryID']
112
+ self.assertTrue(len(repo_ids) > 0)
113
+
114
+
115
+ def test_get_styles(self):
116
+ """
117
+ Test for get_style function.
118
+ """
119
+
120
+ result = self._hdp.get_styles()
121
+
122
+ self.assertEqual(result['HttpStatus'], 200)
123
+ styles = result['Style']
124
+ self.assertTrue(len(styles) > 0)
125
+ self.assertTrue(styles[0] == 'EPNTAP')
126
+
127
+
128
+ def test_get_measurement_types(self):
129
+ """
130
+ Test for get_measurement_types function.
131
+ """
132
+
133
+ result = self._hdp.get_measurement_types()
134
+
135
+ self.assertEqual(result['HttpStatus'], 200)
136
+ measurement_types = result['MeasurementType']
137
+ self.assertTrue(len(measurement_types) > 0)
138
+ self.assertTrue(measurement_types[0] == 'ActivityIndex')
139
+
140
+
141
+ def test_get_spectral_ranges(self):
142
+ """
143
+ Test for get_spectral_ranges function.
144
+ """
145
+
146
+ result = self._hdp.get_spectral_ranges()
147
+
148
+ self.assertEqual(result['HttpStatus'], 200)
149
+ s_range = result['SpectralRange']
150
+ self.assertTrue(len(s_range) > 0)
151
+ self.assertTrue(s_range[0] == 'CaK')
152
+
153
+
154
+ def test_get_observatory_group_ids(self):
155
+ """
156
+ Test for get_observatory_group_ids function.
157
+ """
158
+
159
+ result = self._hdp.get_observatory_group_ids()
160
+
161
+ self.assertEqual(result['HttpStatus'], 200)
162
+ obs_grp_ids = result['ObservatoryGroupID']
163
+ self.assertTrue(len(obs_grp_ids) > 0)
164
+
165
+
166
+ def test_get_observatory_ids(self):
167
+ """
168
+ Test for get_observatory_ids function.
169
+ """
170
+
171
+ result = self._hdp.get_observatory_ids()
172
+
173
+ self.assertEqual(result['HttpStatus'], 200)
174
+ obs_ids = result['ObservatoryID']
175
+ self.assertTrue(len(obs_ids) > 0)
176
+
177
+
178
+ def test_get_observed_regions(self):
179
+ """
180
+ Test for get_observed_regions function.
181
+ """
182
+
183
+ result = self._hdp.get_observed_regions()
184
+
185
+ self.assertEqual(result['HttpStatus'], 200)
186
+ obs_regions = result['ObservedRegion']
187
+ self.assertTrue(len(obs_regions) > 0)
188
+ self.assertTrue(obs_regions[0] == 'Asteroid')
189
+
190
+
191
+ def test_get_spase(self):
192
+ """
193
+ Test for get_spase function.
194
+ """
195
+
196
+ resource_ids = [
197
+ 'spase://NASA/Collection/IRIS_AIA',
198
+ 'spase://SMWG/Service/CCMC/Models'
199
+ ]
200
+ result = self._hdp.get_spase(resource_ids)
201
+
202
+ self.assertEqual(result['HttpStatus'], 200)
203
+ result = result['Result']
204
+ result_id_elements = result.findall('.//ResourceID', namespaces=NS)
205
+ result_ids = list(map(lambda e: e.text, result_id_elements))
206
+ self.assertTrue(len(result_ids) == 3)
207
+ # above should be == 2 when duplicate is removed from hdp and
208
+ # then the following will work
209
+ #self.assertTrue(sorted(result_ids) == sorted(resource_ids))
210
+
211
+
212
+ def test_get_spase_if_modified_since(self):
213
+ """
214
+ Test for get_spase function's if_modified_since option.
215
+ """
216
+
217
+ resource_ids = [
218
+ 'spase://NASA/NumericalData/Wind/MFI/PT03S'
219
+ ]
220
+ result = self._hdp.get_spase(resource_ids)
221
+
222
+ self.assertEqual(result['HttpStatus'], 200)
223
+
224
+ last_modified = result['Last-Modified']
225
+ self.assertIsNotNone(last_modified)
226
+
227
+ result = self._hdp.get_spase(resource_ids,
228
+ if_modified_since=last_modified)
229
+
230
+ self.assertEqual(result['HttpStatus'], 304)
231
+
232
+ last_modified -= datetime.timedelta(seconds=5)
233
+ result = self._hdp.get_spase(resource_ids,
234
+ if_modified_since=last_modified)
235
+
236
+ self.assertEqual(result['HttpStatus'], 200)
237
+
238
+
239
+ def test_get_spase_url(self):
240
+ """
241
+ Test for get_spase_url function.
242
+ """
243
+
244
+ resource_id = 'spase://NASA/NumericalData/Wind/MFI/PT03S'
245
+
246
+ result = self._hdp.get_spase_url(resource_id)
247
+
248
+ self.assertIsNotNone(result)
249
+ self.assertEqual(result,
250
+ self._hdp.endpoint + 'Spase?ResourceID=' + \
251
+ resource_id)
252
+
253
+
254
+ def test_get_spase_html(self):
255
+ """
256
+ Test for get_spase_html function.
257
+ """
258
+
259
+ resource_id = 'spase://NASA/NumericalData/Wind/MFI/PT03S'
260
+
261
+ result = self._hdp.get_spase_html(resource_id)
262
+
263
+ self.assertEqual(result['HttpStatus'], 200)
264
+
265
+ last_modified = result['Last-Modified']
266
+ self.assertIsNotNone(last_modified)
267
+
268
+ result = self._hdp.get_spase_html(resource_id,
269
+ if_modified_since=last_modified)
270
+
271
+ self.assertEqual(result['HttpStatus'], 304)
272
+
273
+ last_modified -= datetime.timedelta(seconds=5)
274
+ result = self._hdp.get_spase_html(resource_id,
275
+ if_modified_since=last_modified)
276
+
277
+ self.assertEqual(result['HttpStatus'], 200)
278
+ result_element = ET.fromstring(result['Result'])
279
+ self.assertEqual(result_element.tag,
280
+ '{' + XHTML_NS + '}html')
281
+
282
+
283
+ def test_get_spase_data(self):
284
+ """
285
+ Test for get_spase_data function.
286
+ """
287
+
288
+ query = {
289
+ 'ResourceID': ['spase://NASA/NumericalData/ACE/CRIS/L2/P1D',
290
+ 'spase://NASA/NumericalData/ACE/CRIS/L2/PT1H'
291
+ ],
292
+ # 'DOI': ['10.48322/e0dc-0h53'],
293
+ # 'InstrumentID': 'spase://SMWG/Instrument/ACE/CRIS',
294
+ # 'ObservatoryID': 'spase://SMWG/Observatory/ACE',
295
+ # 'Cadence': '=PT1H',
296
+ # 'ObservedRegion': 'Heliosphere.NearEarth',
297
+ # 'MeasurementType': 'EnergeticParticles',
298
+ # 'AccessRights': 'Open',
299
+ # 'Format': 'CDF'
300
+ }
301
+
302
+ types = [rt.NUMERICAL_DATA, rt.DISPLAY_DATA]
303
+ time_range = ['2022-01-01', '2022-01-02']
304
+
305
+ result = self._hdp.get_spase_data(types, query, time_range)
306
+
307
+ self.assertEqual(result['HttpStatus'], 200)
308
+ result = result['Result']
309
+ result_id_elements = result.findall('.//ResourceID',
310
+ namespaces=NS)
311
+ result_ids = list(map(lambda e: e.text, result_id_elements))
312
+ self.assertTrue(len(result_ids) == 2)
313
+ self.assertTrue(sorted(result_ids) == sorted(query['ResourceID']))
314
+
315
+
316
+ def test_get_spase_data_if_modified_since(self):
317
+ """
318
+ Test for get_spase_data function's if_modified_since option.
319
+ """
320
+
321
+ query = {
322
+ 'ResourceID': ['spase://NASA/NumericalData/ACE/CRIS/L2/P1D'],
323
+ }
324
+
325
+ types = [rt.NUMERICAL_DATA, rt.DISPLAY_DATA]
326
+ time_range = ['2022-01-01', '2022-01-02']
327
+
328
+ result = self._hdp.get_spase_data(types, query, time_range)
329
+
330
+ self.assertEqual(result['HttpStatus'], 200)
331
+
332
+ last_modified = result['Last-Modified']
333
+ last_modified += datetime.timedelta(seconds=1)
334
+ self.assertIsNotNone(last_modified)
335
+
336
+ result = self._hdp.get_spase_data(types, query, time_range,
337
+ if_modified_since=last_modified)
338
+
339
+ self.assertEqual(result['HttpStatus'], 304)
340
+
341
+ last_modified -= datetime.timedelta(seconds=5)
342
+ result = self._hdp.get_spase_data(types, query, time_range,
343
+ if_modified_since=last_modified)
344
+
345
+ self.assertEqual(result['HttpStatus'], 200)
346
+
347
+
348
+ def test_get_spase_catalog(self):
349
+ """
350
+ Test for get_spase_catalog function.
351
+ """
352
+
353
+ query = {
354
+ 'InstrumentID': 'spase://SMWG/Instrument/ACE/MAG',
355
+ 'PhenomenonType': 'MagneticCloud',
356
+ 'Description': 'ICME'
357
+ }
358
+ time_range = ['1999-01-01', '1999-01-02']
359
+
360
+ result = self._hdp.get_spase_catalog(query, time_range)
361
+
362
+ self.assertEqual(result['HttpStatus'], 200)
363
+ result = result['Result']
364
+ result_id_elements = result.findall('.//ResourceID',
365
+ namespaces=NS)
366
+ result_ids = list(map(lambda e: e.text, result_id_elements))
367
+ self.assertTrue(len(result_ids) == 1)
368
+ self.assertTrue(result_ids[0] == 'spase://NASA/Catalog/CME-ICME_Cho2003')
369
+
370
+
371
+ def test_get_spase_collection(self):
372
+ """
373
+ Test for get_spase_collection function.
374
+ """
375
+
376
+ query = {
377
+ 'ResourceID': 'spase://NASA/Collection/IRIS_AIA',
378
+ 'MemberID': 'spase://NASA/NumericalData/SDO/AIA/PT10S',
379
+ 'Description': 'IRIS AND SDO and AIA'
380
+ }
381
+
382
+ result = self._hdp.get_spase_collection(query)
383
+
384
+ self.assertEqual(result['HttpStatus'], 200)
385
+ result = result['Result']
386
+ result_id_elements = result.findall('.//ResourceID',
387
+ namespaces=NS)
388
+ result_ids = list(map(lambda e: e.text, result_id_elements))
389
+ self.assertTrue(len(result_ids) == 1)
390
+ self.assertTrue(result_ids[0] == 'spase://NASA/Collection/IRIS_AIA')
391
+
392
+
393
+ def test_get_spase_document(self):
394
+ """
395
+ Test for get_spase_document function.
396
+ """
397
+
398
+ query = {
399
+ 'ResourceID': 'spase://SMWG/Document/HPDE/Policy/HP_DataPolicy_v1.2',
400
+ 'DOI': '10.21978/P83P78',
401
+ 'Description': '"Program Data Management Plan"'
402
+ }
403
+
404
+ result = self._hdp.get_spase_document(query)
405
+
406
+ self.assertEqual(result['HttpStatus'], 200)
407
+ result = result['Result']
408
+ result_id_elements = result.findall('.//ResourceID',
409
+ namespaces=NS)
410
+ result_ids = list(map(lambda e: e.text, result_id_elements))
411
+ self.assertTrue(len(result_ids) == 1)
412
+ self.assertTrue(result_ids[0] == 'spase://SMWG/Document/HPDE/Policy/HP_DataPolicy_v1.2')
413
+
414
+
415
+ def test_get_spase_software(self):
416
+ """
417
+ Test for get_spase_software function.
418
+ """
419
+
420
+ query = {
421
+ 'ResourceID': 'spase://CCMC/Software/Kamodo',
422
+ 'CodeLanguage': 'Python',
423
+ 'Description': '"space weather models and data"'
424
+ }
425
+
426
+ result = self._hdp.get_spase_software(query)
427
+
428
+ self.assertEqual(result['HttpStatus'], 200)
429
+ result = result['Result']
430
+ result_id_elements = result.findall('.//ResourceID',
431
+ namespaces=NS)
432
+ result_ids = list(map(lambda e: e.text, result_id_elements))
433
+ self.assertTrue(len(result_ids) == 1)
434
+ self.assertTrue(result_ids[0] == 'spase://CCMC/Software/Kamodo')
435
+
436
+
437
+ if __name__ == '__main__':
438
+ unittest.main()
File without changes
File without changes
File without changes
File without changes
File without changes