cdasws 1.8.4__tar.gz → 1.8.6__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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cdasws
3
- Version: 1.8.4
3
+ Version: 1.8.6
4
4
  Summary: NASA's Coordinated Data Analysis System Web Service Client Library
5
5
  Home-page: https://cdaweb.gsfc.nasa.gov/WebServices/REST
6
6
  Author: Bernie Harris
@@ -118,12 +118,11 @@ Classifier: Environment :: Web Environment
118
118
  Classifier: Intended Audience :: End Users/Desktop
119
119
  Classifier: Intended Audience :: Developers
120
120
  Classifier: Intended Audience :: System Administrators
121
- Classifier: Operating System :: MacOS :: MacOS X
122
- Classifier: Operating System :: Microsoft :: Windows
123
- Classifier: Operating System :: POSIX
121
+ Classifier: License :: OSI Approved :: NASA Open Source Agreement v1.3 (NASA-1.3)
122
+ Classifier: Operating System :: OS Independent
124
123
  Classifier: Programming Language :: Python
125
124
  Classifier: Topic :: Scientific/Engineering :: Physics
126
125
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
127
126
  Description-Content-Type: text/markdown
128
- Provides-Extra: spdm
129
127
  Provides-Extra: xarray
128
+ Provides-Extra: spdm
@@ -137,7 +137,7 @@ except ImportError:
137
137
  CDF_XARRAY_AVAILABLE = False
138
138
 
139
139
 
140
- __version__ = "1.8.4"
140
+ __version__ = "1.8.6"
141
141
 
142
142
 
143
143
  #
@@ -282,7 +282,8 @@ class CdasWs:
282
282
  self._user_agent += ' (' + user_agent + ')'
283
283
 
284
284
  self._request_headers = {
285
- 'Content-Type' : 'application/json',
285
+ #'Content-Type' : 'application/json',
286
+ 'Content-Type' : 'application/xml',
286
287
  'Accept' : 'application/xml',
287
288
  'User-Agent' : self._user_agent,
288
289
  #'Accept-Encoding' : 'gzip' # only beneficial for icdfml responses
@@ -729,17 +730,21 @@ class CdasWs:
729
730
  interval. See module note about timezone value. If this
730
731
  parameter is omitted, the time interval will end infinitely
731
732
  in the future.<br>
733
+ <b>id</b> - a dataset identifier. The value may be a CDAS
734
+ (e.g., AC_H2_MFI), DOI (e.g., 10.48322/fh85-fj47), or SPASE
735
+ [ResourceID] (e.g., spase://NASA/NumericalData/ACE/MAG/L2/PT1H)
736
+ identifier. If specified, all other keywords are ignored.<br>
732
737
  <b>idPattern</b> - a java.util.regex compatible regular
733
- expression that must match the dataset's identifier value.
738
+ expression that must match the dataset's CDAS identifier value.
734
739
  Omitting this parameter is equivalent to `.*`.<br>
735
740
  <b>labelPattern</b> - a java.util.regex compatible regular
736
- expression that must match the dataset's label text.
741
+ expression that must match the dataset's CDAS label text.
737
742
  Omitting this parameter is equivalent to `.*`. Embedded
738
743
  matching flag expressions (e.g., `(?i)` for case insensitive
739
744
  match mode) are supported and likely to be useful in this
740
745
  case.<br>
741
746
  <b>notesPattern</b> - a java.util.regex compatible regular
742
- expression that must match the dataset's notes text.
747
+ expression that must match the dataset's CDAS notes text.
743
748
  Omitting this parameter is equivalent to `.*`. Embedded
744
749
  matching flag expressions (e.g., `(?s)` for dotall match mode)
745
750
  are supported and likely to be useful in this case.<br>
@@ -793,6 +798,10 @@ class CdasWs:
793
798
  url = url + 'stopDate=' \
794
799
  + urllib.parse.quote(keywords['stopDate']) + '&'
795
800
 
801
+ if 'id' in keywords:
802
+ url = url + 'id=' \
803
+ + urllib.parse.quote(keywords['id']) + '&'
804
+
796
805
  if 'idPattern' in keywords:
797
806
  url = url + 'idPattern=' \
798
807
  + urllib.parse.quote(keywords['idPattern']) + '&'
@@ -933,6 +942,30 @@ class CdasWs:
933
942
  return doi
934
943
 
935
944
 
945
+ @staticmethod
946
+ def get_citation(
947
+ doi: str
948
+ ) -> str:
949
+ """
950
+ Returns the citation from doi.org for the given DOI.
951
+
952
+ Parameters
953
+ ----------
954
+ doi
955
+ digital object identifier.
956
+ Returns
957
+ -------
958
+ str
959
+ The citation from doi.org for the given DOI.
960
+ """
961
+
962
+ url = 'https://doi.org/' + doi
963
+ headers = {'Accept': 'text/x-bibliography; style=apa'}
964
+ response = requests.get(url, headers=headers)
965
+
966
+ return response.text
967
+
968
+
936
969
  def get_inventory(
937
970
  self,
938
971
  identifier: str,
@@ -1305,7 +1338,8 @@ class CdasWs:
1305
1338
  url = self._endpoint + 'datasets'
1306
1339
 
1307
1340
  for retries in range(RETRY_LIMIT):
1308
- response = self._session.post(url, data=data_request.json(),
1341
+ #response = self._session.post(url, data=data_request.json(),
1342
+ response = self._session.post(url, data=data_request.xml_str(),
1309
1343
  timeout=self._timeout)
1310
1344
 
1311
1345
  if response.status_code == 200:
@@ -1557,8 +1591,8 @@ class CdasWs:
1557
1591
  If an Exception is raise by either the spdm.fromCDF() or
1558
1592
  cdflib.cdf_to_xarray() functions.
1559
1593
  ModuleNotFoundError
1560
- If neither the spacepy.datamodel nor the cdflib and xarray
1561
- modules are installed.
1594
+ If the required spacepy.datamodel or the cdflib and xarray
1595
+ modules are not installed.
1562
1596
  """
1563
1597
  if data_representation is None:
1564
1598
  if SPDM_AVAILABLE:
@@ -1569,6 +1603,14 @@ class CdasWs:
1569
1603
  raise ModuleNotFoundError(
1570
1604
  'neither the spacepy.datamodel nor the cdflib and '
1571
1605
  'xarray modules are installed')
1606
+
1607
+ if data_representation is DataRepresentation.SPACEPY and \
1608
+ not SPDM_AVAILABLE:
1609
+ raise ModuleNotFoundError('spacepy module must be installed')
1610
+ if data_representation is DataRepresentation.XARRAY and \
1611
+ not CDF_XARRAY_AVAILABLE:
1612
+ raise ModuleNotFoundError('cdflib and xarray modules must be installed')
1613
+
1572
1614
  if data_representation is DataRepresentation.SPACEPY:
1573
1615
  return spdm.fromCDF(filename)
1574
1616
  if data_representation is DataRepresentation.XARRAY:
@@ -1768,8 +1810,9 @@ class CdasWs:
1768
1810
  progress_user_value) != 0:
1769
1811
  return (status, None)
1770
1812
  except:
1771
- self.logger.error('Exception from read_data(%s): %s',
1772
- tmp_filename, sys.exc_info()[0])
1813
+ self.logger.error('Exception from read_data(%s): %s, %s',
1814
+ tmp_filename, sys.exc_info()[0],
1815
+ sys.exc_info()[1])
1773
1816
  self.logger.error('CDF file has been retained.')
1774
1817
  raise
1775
1818
  return (status, data)
@@ -24,7 +24,7 @@
24
24
  #
25
25
  # NOSA HEADER END
26
26
  #
27
- # Copyright (c) 2018-2023 United States Government as represented by
27
+ # Copyright (c) 2018-2024 United States Government as represented by
28
28
  # the National Aeronautics and Space Administration. No copyright is
29
29
  # claimed in the United States under Title 17, U.S.Code. All Other
30
30
  # Rights Reserved.
@@ -34,7 +34,7 @@
34
34
  Example Coordinate Data Analysis System (CDAS) web service client.
35
35
  Includes example calls to most of the web services.
36
36
 
37
- Copyright &copy; 2018-2023 United States Government as represented by the
37
+ Copyright &copy; 2018-2024 United States Government as represented by the
38
38
  National Aeronautics and Space Administration. No copyright is claimed in
39
39
  the United States under Title 17, U.S.Code. All Other Rights Reserved.
40
40
  """
@@ -138,6 +138,7 @@ def example(
138
138
  print_usage(argv[0])
139
139
  sys.exit()
140
140
 
141
+
141
142
  cdas = CdasWs(endpoint=endpoint, ca_certs=ca_certs,
142
143
  disable_ssl_certificate_validation=
143
144
  disable_ssl_certificate_validation, user_agent='Example')
@@ -160,6 +161,8 @@ def example(
160
161
  print('DOI landing page:',
161
162
  cdas.get_doi_landing_page_url('10.48322/e0dc-0h53'))
162
163
 
164
+ print('citation = ' + cdas.get_citation('10.48322/541v-1f57'))
165
+
163
166
  mms_brst_inventory = cdas.get_inventory('MMS1_FPI_BRST_L2_DES-MOMS',
164
167
  timeInterval=TimeInterval(
165
168
  '2018-08-30T08:09:53Z',
@@ -200,6 +203,7 @@ def example(
200
203
  # 'sigmaMultiplier': 4,
201
204
  # 'overrideDefaultBinning': True
202
205
  #}
206
+ dataRepresentation=DataRepresentation.SPACEPY
203
207
  )
204
208
  # cdas.get_data('10.21978/P8PG8V', ['BT'],
205
209
  # '1987-09-24T00:00:00Z', '1987-09-24T01:00:00Z'
@@ -44,8 +44,10 @@ the United States under Title 17, U.S.Code. All Other Rights Reserved.
44
44
 
45
45
  import enum
46
46
  import json
47
+ import xml.etree.ElementTree as ET
47
48
  from typing import List, Union # when python 3.8 , TypedDict
48
49
  from abc import ABCMeta, abstractmethod
50
+ #from cdasws import NS
49
51
  from cdasws.timeinterval import TimeInterval
50
52
 
51
53
 
@@ -117,6 +119,14 @@ class DataRequest(metaclass=ABCMeta): # pylint: disable=too-few-public-methods
117
119
  Creates an object representing a DataRequestEntity from
118
120
  <https://cdaweb.gsfc.nasa.gov/WebServices/REST/CDAS.xsd>.
119
121
 
122
+ Notes
123
+ -----
124
+ This class was originally written with serialization to JSON
125
+ in mind so some dict key values are the JSON representations.
126
+ For example, Start/End key values are strings instead of
127
+ datetimes. These value data type choices cause extra code
128
+ for serialization to XML.
129
+
120
130
  Parameters
121
131
  ----------
122
132
  request_type
@@ -180,6 +190,170 @@ class DataRequest(metaclass=ABCMeta): # pylint: disable=too-few-public-methods
180
190
  bin_data['overrideDefaultBinning']
181
191
 
182
192
 
193
+ # pylint: disable=too-many-locals
194
+ # pylint: disable=too-many-branches
195
+ # pylint: disable=too-many-statements
196
+ def xml_element(self) -> ET:
197
+ """
198
+ Produces the XML Element representation of this object.
199
+
200
+ Returns
201
+ -------
202
+ ET
203
+ XML Element representation of this object.
204
+ """
205
+
206
+ #attrs = {'xmlns': NS}
207
+ attrs = {'xmlns': 'http://cdaweb.gsfc.nasa.gov/schema'}
208
+
209
+ builder = ET.TreeBuilder()
210
+ builder.start('DataRequest', attrs)
211
+ request_name = next(iter(self._data_request))
212
+ builder.start(request_name, {})
213
+ data_request = self._data_request[request_name]
214
+ time_intervals = data_request['TimeInterval']
215
+ if isinstance(time_intervals, list):
216
+ for time_interval in time_intervals:
217
+ start = time_interval['Start']
218
+ end = time_interval['End']
219
+ TimeInterval(start, end).xml_element(builder)
220
+ else:
221
+ start = time_intervals['Start']
222
+ end = time_intervals['End']
223
+ TimeInterval(start, end).xml_element(builder)
224
+
225
+ builder.start('DatasetRequest', {})
226
+ dataset_request = data_request['DatasetRequest']
227
+ builder.start('DatasetId', {})
228
+ builder.data(dataset_request['DatasetId'])
229
+ builder.end('DatasetId')
230
+ variable_names = dataset_request['VariableName']
231
+ if isinstance(variable_names, list):
232
+ for variable_name in variable_names:
233
+ builder.start('VariableName', {})
234
+ builder.data(variable_name)
235
+ builder.end('VariableName')
236
+ else:
237
+ builder.start('VariableName', {})
238
+ builder.data(variable_names)
239
+ builder.end('VariableName')
240
+ builder.end('DatasetRequest')
241
+ if 'CdfVersion' in data_request:
242
+ builder.start('CdfVersion', {})
243
+ builder.data(str(data_request['CdfVersion']))
244
+ builder.end('CdfVersion')
245
+ if 'CdfFormat' in data_request:
246
+ builder.start('CdfFormat', {})
247
+ builder.data(data_request['CdfFormat'])
248
+ builder.end('CdfFormat')
249
+ if 'Compression' in data_request:
250
+ builder.start('Compression', {})
251
+ builder.data(data_request['Compression'])
252
+ builder.end('Compression')
253
+ if 'Format' in data_request:
254
+ builder.start('Format', {})
255
+ builder.data(data_request['Format'])
256
+ builder.end('Format')
257
+ if 'Thumbnail' in data_request:
258
+ builder.start('Thumbnail', {})
259
+ builder.data(str(data_request['Thumbnail']))
260
+ builder.end('Thumbnail')
261
+ if 'ThumbnailId' in data_request:
262
+ builder.start('ThumbnailId', {})
263
+ builder.data(data_request['ThumbnailId'])
264
+ builder.end('ThumbnailId')
265
+ if 'GraphOptions' in data_request:
266
+ graph_options = data_request['GraphOptions']
267
+ builder.start('GraphOptions', {})
268
+ if 'CoarseNoiseFilter' in graph_options:
269
+ builder.start('CoarseNoiseFilter', {})
270
+ builder.data(graph_options['CoarseNoiseFilter'])
271
+ builder.end('CoarseNoiseFilter')
272
+ if 'XAxisWidthFactor' in graph_options:
273
+ builder.start('XAxisWidthFactor', {})
274
+ builder.data(str(graph_options['XAxisWidthFactor']))
275
+ builder.end('XAxisWidthFactor')
276
+ if 'YAxisHeightFactor' in graph_options:
277
+ builder.start('YAxisHeightFactor', {})
278
+ builder.data(str(graph_options['YAxisHeightFactor']))
279
+ builder.end('YAxisHeightFactor')
280
+ if 'Combine' in graph_options:
281
+ builder.start('Combine', {})
282
+ builder.data(str(graph_options['Combine']).lower())
283
+ builder.end('Combine')
284
+ if 'Overplot' in graph_options:
285
+ builder.start('Overplot', {})
286
+ builder.data(str(graph_options['Overplot']))
287
+ builder.end('Overplot')
288
+ builder.end('GraphOptions')
289
+ if 'GraphOption' in data_request:
290
+ graph_options = data_request['GraphOption']
291
+ if isinstance(graph_options, list):
292
+ for graph_option in graph_options:
293
+ builder.start('GraphOption', {})
294
+ builder.data(graph_option)
295
+ builder.end('GraphOption')
296
+ else:
297
+ builder.start('GraphOption', {})
298
+ builder.data(graph_option)
299
+ builder.end('GraphOption')
300
+ if 'ImageFormat' in data_request:
301
+ image_formats = data_request['ImageFormat']
302
+ if isinstance(image_formats, list):
303
+ for image_format in image_formats:
304
+ builder.start('ImageFormat', {})
305
+ builder.data(image_format)
306
+ builder.end('ImageFormat')
307
+ else:
308
+ builder.start('ImageFormat', {})
309
+ builder.data(data_request['ImageFormat'])
310
+ builder.end('ImageFormat')
311
+ if 'BinData' in data_request:
312
+ bin_data = data_request['BinData']
313
+ builder.start('BinData')
314
+ if 'Interval' in bin_data:
315
+ builder.start('Interval', {})
316
+ builder.data(str(bin_data['Interval']))
317
+ builder.end('Interval')
318
+ if 'InterpolateMissingValues' in bin_data:
319
+ builder.start('InterpolateMissingValues', {})
320
+ builder.data(str(bin_data['InterpolateMissingValues']).lower())
321
+ builder.end('InterpolateMissingValues')
322
+ if 'SigmaMultiplier' in bin_data:
323
+ builder.start('SigmaMultiplier', {})
324
+ builder.data(str(bin_data['SigmaMultiplier']))
325
+ builder.end('SigmaMultiplier')
326
+ if 'OverrideDefaultBinning' in bin_data:
327
+ builder.start('OverrideDefaultBinning', {})
328
+ builder.data(str(bin_data['OverrideDefaultBinning']).lower())
329
+ builder.end('OverrideDefaultBinning')
330
+ builder.end('BinData')
331
+ builder.end(request_name)
332
+ builder.end('DataRequest')
333
+ xml_element = builder.close()
334
+
335
+ return xml_element
336
+ # pylint: enable=too-many-locals
337
+ # pylint: enable=too-many-branches
338
+ # pylint: enable=too-many-statements
339
+
340
+
341
+ def xml_str(self) -> str:
342
+ """
343
+ Produces an str xml representation of this object matching the
344
+ XML representation of a DataRequestEntity from
345
+ <https://cdaweb.gsfc.nasa.gov/WebServices/REST/CDAS.xsd>.
346
+
347
+ Returns
348
+ -------
349
+ str
350
+ string XML representation of this object.
351
+ """
352
+
353
+ #return ET.tostring(self.xml_element(), encoding="utf-8", method='xml', xml_declaration=True)
354
+ return ET.tostring(self.xml_element(), encoding="utf-8", method='xml')
355
+
356
+
183
357
  def json(self, **keywords) -> str:
184
358
  """
185
359
  Produces a JSON representation of this object matching the
@@ -211,6 +385,7 @@ class CdfFormat(enum.Enum):
211
385
  ZIP_CDFML = "ZipCDFML"
212
386
  ICDFML = "ICDFML"
213
387
  NETCDF = "NetCdf"
388
+ CDFJSON = "CdfJson"
214
389
 
215
390
 
216
391
  class CdfRequest(DataRequest): # pylint: disable=too-few-public-methods
@@ -631,6 +806,7 @@ class ThumbnailRequest(DataRequest): # pylint: disable=too-few-public-methods
631
806
  i_format.value)
632
807
 
633
808
 
809
+
634
810
  class AudioRequest(DataRequest): # pylint: disable=too-few-public-methods
635
811
  """
636
812
  Class representing an AudioRequest from
@@ -41,6 +41,8 @@ the United States under Title 17, U.S.Code. All Other Rights Reserved.
41
41
  """
42
42
 
43
43
 
44
+ import xml.etree.ElementTree as ET
45
+ from xml.etree.ElementTree import TreeBuilder
44
46
  from datetime import datetime, timezone
45
47
  from typing import Tuple, Union
46
48
  import dateutil.parser
@@ -132,6 +134,53 @@ class TimeInterval:
132
134
  self._end = TimeInterval.get_datetime(value)
133
135
 
134
136
 
137
+ def xml_element(self,
138
+ builder: TreeBuilder = None) -> ET:
139
+ """
140
+ Produces the XML Element representation of this object.
141
+
142
+ Parameters
143
+ ----------
144
+ builder
145
+ The TreeBuilder to use.
146
+
147
+ Returns
148
+ -------
149
+ ET
150
+ XML Element representation of this object.
151
+ """
152
+
153
+ if builder is None:
154
+ builder = ET.TreeBuilder()
155
+
156
+ builder.start('TimeInterval', {})
157
+ builder.start('Start', {})
158
+ builder.data(self._start.isoformat().replace('+00:00', '.000Z'))
159
+ builder.end('Start')
160
+ builder.start('End', {})
161
+ builder.data(self._end.isoformat().replace('+00:00', '.000Z'))
162
+ builder.end('End')
163
+
164
+ return builder.end('TimeInterval')
165
+
166
+
167
+ def xml_str(self) -> str:
168
+ """
169
+ Produces an str xml representation of this object matching the
170
+ XML representation of a DataRequestEntity from
171
+ <https://cdaweb.gsfc.nasa.gov/WebServices/REST/CDAS.xsd>.
172
+
173
+ Returns
174
+ -------
175
+ str
176
+ string XML representation of this object.
177
+ """
178
+
179
+ #return ET.tostring(self.xml_element(), encoding="utf-8", method='xml',
180
+ # xml_declaration=True)
181
+ return ET.tostring(self.xml_element(), encoding="utf-8", method='xml')
182
+
183
+
135
184
  def __str__(self):
136
185
  return self._start.isoformat() + ' ' + self._end.isoformat()
137
186
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cdasws
3
- Version: 1.8.4
3
+ Version: 1.8.6
4
4
  Summary: NASA's Coordinated Data Analysis System Web Service Client Library
5
5
  Home-page: https://cdaweb.gsfc.nasa.gov/WebServices/REST
6
6
  Author: Bernie Harris
@@ -118,12 +118,11 @@ Classifier: Environment :: Web Environment
118
118
  Classifier: Intended Audience :: End Users/Desktop
119
119
  Classifier: Intended Audience :: Developers
120
120
  Classifier: Intended Audience :: System Administrators
121
- Classifier: Operating System :: MacOS :: MacOS X
122
- Classifier: Operating System :: Microsoft :: Windows
123
- Classifier: Operating System :: POSIX
121
+ Classifier: License :: OSI Approved :: NASA Open Source Agreement v1.3 (NASA-1.3)
122
+ Classifier: Operating System :: OS Independent
124
123
  Classifier: Programming Language :: Python
125
124
  Classifier: Topic :: Scientific/Engineering :: Physics
126
125
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
127
126
  Description-Content-Type: text/markdown
128
- Provides-Extra: spdm
129
127
  Provides-Extra: xarray
128
+ Provides-Extra: spdm
@@ -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="cdasws",
13
- version="1.8.4",
13
+ version="1.8.6",
14
14
  description="NASA's Coordinated Data Analysis System Web Service Client Library",
15
15
  long_description=README,
16
16
  long_description_content_type="text/markdown",
@@ -37,10 +37,8 @@ setup(
37
37
  "Intended Audience :: End Users/Desktop",
38
38
  "Intended Audience :: Developers",
39
39
  "Intended Audience :: System Administrators",
40
- # "License :: OSI Approved :: NASA Open Source Agreement",
41
- "Operating System :: MacOS :: MacOS X",
42
- "Operating System :: Microsoft :: Windows",
43
- "Operating System :: POSIX",
40
+ "License :: OSI Approved :: NASA Open Source Agreement v1.3 (NASA-1.3)",
41
+ "Operating System :: OS Independent",
44
42
  "Programming Language :: Python",
45
43
  "Topic :: Scientific/Engineering :: Physics",
46
44
  "Topic :: Software Development :: Libraries :: Python Modules"
File without changes
File without changes