cdasws 1.8.2__tar.gz → 1.8.3__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.2
3
+ Version: 1.8.3
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
@@ -60,12 +60,14 @@ import os
60
60
  import platform
61
61
  import logging
62
62
  import re
63
+ from importlib.util import find_spec
63
64
  import urllib.parse
64
65
  from urllib.parse import urlparse
65
66
  import json
66
67
  from operator import itemgetter
67
68
  import time
68
69
  from datetime import datetime, timedelta, timezone
70
+ import xml.etree.ElementTree as ET
69
71
  from tempfile import mkstemp
70
72
  from typing import Any, Callable, Dict, List, Tuple, Union
71
73
 
@@ -79,11 +81,19 @@ from cdasws.datarequest import ImageFormat, GraphOptions, GraphRequest
79
81
  from cdasws.datarequest import TextFormat, TextRequest, ThumbnailRequest
80
82
  from cdasws.timeinterval import TimeInterval
81
83
 
82
- try:
84
+
85
+ # requires python >= 3.4
86
+ if find_spec('spacepy.datamodel') is not None:
83
87
  import spacepy.datamodel as spdm # type: ignore
84
88
  SPDM_AVAILABLE = True
85
- except ImportError:
89
+ else:
86
90
  SPDM_AVAILABLE = False
91
+ # python < 3.4
92
+ #try:
93
+ # import spacepy.datamodel as spdm # type: ignore
94
+ # SPDM_AVAILABLE = True
95
+ #except ImportError:
96
+ # SPDM_AVAILABLE = False
87
97
 
88
98
  try:
89
99
  from cdflib.xarray import cdf_to_xarray
@@ -127,7 +137,7 @@ except ImportError:
127
137
  CDF_XARRAY_AVAILABLE = False
128
138
 
129
139
 
130
- __version__ = "1.8.2"
140
+ __version__ = "1.8.3"
131
141
 
132
142
 
133
143
  #
@@ -136,6 +146,22 @@ __version__ = "1.8.2"
136
146
  #
137
147
  RETRY_LIMIT = 100
138
148
 
149
+ #
150
+ # XML schema namespace
151
+ #
152
+ NS = 'http://cdaweb.gsfc.nasa.gov/schema'
153
+ #
154
+ # XHTML schema namespace
155
+ #
156
+ XHTML_NS = 'http://www.w3.org/1999/xhtml'
157
+ #
158
+ # All namespaces found in responses.
159
+ #
160
+ NAMESPACES = {
161
+ 'cdas': NS,
162
+ 'xhtml': XHTML_NS
163
+ }
164
+
139
165
 
140
166
  def _get_data_progress(
141
167
  progress: float,
@@ -257,7 +283,7 @@ class CdasWs:
257
283
 
258
284
  self._request_headers = {
259
285
  'Content-Type' : 'application/json',
260
- 'Accept' : 'application/json',
286
+ 'Accept' : 'application/xml',
261
287
  'User-Agent' : self._user_agent,
262
288
  #'Accept-Encoding' : 'gzip' # only beneficial for icdfml responses
263
289
  }
@@ -339,17 +365,28 @@ class CdasWs:
339
365
  self.logger.info('response.text: %s', response.text)
340
366
  return []
341
367
 
342
- observatory_groups = response.json()
343
-
344
368
  if self.logger.level <= logging.DEBUG:
345
- self.logger.debug('observatory_groups: %s',
346
- json.dumps(observatory_groups,
347
- indent=4, sort_keys=True))
369
+ self.logger.debug('response.text = %s', response.text)
348
370
 
349
- if not observatory_groups:
350
- return []
371
+ observatory_response = ET.fromstring(response.text)
372
+
373
+ observatory_group_descriptions = []
374
+ for description in observatory_response.findall(\
375
+ 'cdas:ObservatoryGroupDescription', namespaces=NAMESPACES):
376
+
377
+ observatory_ids = []
378
+ for observatory_id in description.findall(\
379
+ 'cdas:ObservatoryId', namespaces=NAMESPACES):
380
+
381
+ observatory_ids.append(observatory_id.text)
351
382
 
352
- return observatory_groups['ObservatoryGroupDescription']
383
+ observatory_group_descriptions.append({
384
+ 'Name': description.find(\
385
+ 'cdas:Name', namespaces=NAMESPACES).text,
386
+ 'ObservatoryId': observatory_ids
387
+ })
388
+
389
+ return observatory_group_descriptions
353
390
 
354
391
 
355
392
  def get_instrument_types(
@@ -399,17 +436,24 @@ class CdasWs:
399
436
  self.logger.info('response.text: %s', response.text)
400
437
  return []
401
438
 
402
- instrument_types = response.json()
439
+ if self.logger.level <= logging.DEBUG:
440
+ self.logger.debug('response.text = %s', response.text)
441
+
442
+ instrument_response = ET.fromstring(response.text)
403
443
 
404
444
  if self.logger.level <= logging.DEBUG:
405
- self.logger.debug('instrument_types = %s',
406
- json.dumps(instrument_types, indent=4,
407
- sort_keys=True))
445
+ self.logger.debug('instrument_response = %s',
446
+ ET.tostring(instrument_response))
408
447
 
409
- if not instrument_types:
410
- return []
448
+ instrument_types = []
449
+ for description in instrument_response.findall(\
450
+ 'cdas:InstrumentTypeDescription', namespaces=NAMESPACES):
411
451
 
412
- return instrument_types['InstrumentTypeDescription']
452
+ instrument_types.append({
453
+ 'Name': description.find('cdas:Name',
454
+ namespaces=NAMESPACES).text
455
+ })
456
+ return instrument_types
413
457
 
414
458
 
415
459
  def get_instruments(
@@ -459,17 +503,29 @@ class CdasWs:
459
503
  self.logger.info('response.text: %s', response.text)
460
504
  return []
461
505
 
462
- instruments = response.json()
506
+ if self.logger.level <= logging.DEBUG:
507
+ self.logger.debug('response.text = %s', response.text)
508
+
509
+ instruments_response = ET.fromstring(response.text)
463
510
 
464
511
  if self.logger.level <= logging.DEBUG:
465
- self.logger.debug('instruments = %s',
466
- json.dumps(instruments, indent=4,
467
- sort_keys=True))
512
+ self.logger.debug('instruments = %s', response.text)
513
+ #ET.indent(instruments_response, space=' '))
468
514
 
469
- if not instruments:
470
- return []
515
+ instruments = []
516
+ for instrument_description in instruments_response.findall(\
517
+ 'cdas:InstrumentDescription', namespaces=NAMESPACES):
471
518
 
472
- return instruments['InstrumentDescription']
519
+ instruments.append({
520
+ 'Name': instrument_description.find(\
521
+ 'cdas:Name', namespaces=NAMESPACES).text,
522
+ 'ShortDescription': instrument_description.find(\
523
+ 'cdas:ShortDescription', namespaces=NAMESPACES).text,
524
+ 'LongDescription': instrument_description.find(\
525
+ 'cdas:LongDescription', namespaces=NAMESPACES).text
526
+ })
527
+
528
+ return instruments
473
529
 
474
530
 
475
531
  def get_observatories(
@@ -519,17 +575,28 @@ class CdasWs:
519
575
  self.logger.info('response.text: %s', response.text)
520
576
  return []
521
577
 
522
- observatories = response.json()
578
+ if self.logger.level <= logging.DEBUG:
579
+ self.logger.debug('response.text = %s', response.text)
580
+
581
+ observatory_response = ET.fromstring(response.text)
523
582
 
524
583
  if self.logger.level <= logging.DEBUG:
525
- self.logger.debug('observatories = %s',
526
- json.dumps(observatories, indent=4,
527
- sort_keys=True))
584
+ self.logger.debug('observatories = %s', response.text)
528
585
 
529
- if not observatories:
530
- return []
586
+ observatories = []
587
+
588
+ for observatory in observatory_response.findall(\
589
+ 'cdas:ObservatoryDescription', namespaces=NAMESPACES):
590
+ observatories.append({
591
+ 'Name': observatory.find(\
592
+ 'cdas:Name', namespaces=NAMESPACES).text,
593
+ 'ShortDescription': observatory.find(\
594
+ 'cdas:ShortDescription', namespaces=NAMESPACES).text,
595
+ 'LongDescription': observatory.find(\
596
+ 'cdas:LongDescription', namespaces=NAMESPACES).text
597
+ })
531
598
 
532
- return observatories['ObservatoryDescription']
599
+ return observatories
533
600
 
534
601
 
535
602
  def get_observatory_groups_and_instruments(
@@ -574,17 +641,55 @@ class CdasWs:
574
641
  self.logger.info('response.text: %s', response.text)
575
642
  return []
576
643
 
577
- observatories = response.json()
578
-
579
644
  if self.logger.level <= logging.DEBUG:
580
- self.logger.debug('observatories = %s',
581
- json.dumps(observatories, indent=4,
582
- sort_keys=True))
645
+ self.logger.debug('response.text = %s', response.text)
583
646
 
584
- if not observatories:
585
- return []
647
+ observatories_response = ET.fromstring(response.text)
586
648
 
587
- return observatories['ObservatoryGroupInstrumentDescription']
649
+ if self.logger.level <= logging.DEBUG:
650
+ self.logger.debug('observatories = %s', response.text)
651
+
652
+ o_g_i_ds = []
653
+
654
+ for o_g_i_d in observatories_response.findall(\
655
+ 'cdas:ObservatoryGroupInstrumentDescription',\
656
+ namespaces=NAMESPACES):
657
+
658
+ o_g_i_d_name = o_g_i_d.find('cdas:Name',
659
+ namespaces=NAMESPACES).text
660
+ o_is = []
661
+ for o_i in o_g_i_d.findall('cdas:ObservatoryInstruments',
662
+ namespaces=NAMESPACES):
663
+
664
+ o_i_name = o_i.find('cdas:Name',
665
+ namespaces=NAMESPACES).text
666
+ i_ds = []
667
+ for i_d in o_i.findall('cdas:InstrumentDescription',
668
+ namespaces=NAMESPACES):
669
+ i_d_name = i_d.find('cdas:Name',
670
+ namespaces=NAMESPACES).text
671
+ i_d_short_description = \
672
+ i_d.find('cdas:ShortDescription',
673
+ namespaces=NAMESPACES).text
674
+ i_d_long_description = \
675
+ i_d.find('cdas:LongDescription',
676
+ namespaces=NAMESPACES).text
677
+ i_ds.append({
678
+ 'Name': i_d_name,
679
+ 'ShortDescription': i_d_short_description,
680
+ 'LongDescription': i_d_long_description
681
+ })
682
+ o_is.append({
683
+ 'Name': o_i_name,
684
+ 'InstrumentDescription': i_ds
685
+ })
686
+
687
+ o_g_i_ds.append({
688
+ 'Name': o_g_i_d_name,
689
+ 'ObservatoryInstruments': o_is
690
+ })
691
+
692
+ return o_g_i_ds
588
693
 
589
694
 
590
695
  # pylint: disable=too-many-branches
@@ -711,16 +816,97 @@ class CdasWs:
711
816
  self.logger.info('response.text: %s', response.text)
712
817
  return []
713
818
 
714
- datasets = response.json()
715
-
716
819
  if self.logger.level <= logging.DEBUG:
717
- self.logger.debug('datasets = %s',
718
- json.dumps(datasets, indent=4, sort_keys=True))
820
+ self.logger.debug('response.text = %s', response.text)
719
821
 
720
- if not datasets:
721
- return []
822
+ dss = ET.fromstring(response.text)
722
823
 
723
- return sorted(datasets['DatasetDescription'], key=itemgetter('Id'))
824
+ if self.logger.level <= logging.DEBUG:
825
+ self.logger.debug('datasets = %s', response.text)
826
+
827
+ datasets = []
828
+ for ds in dss.findall('cdas:DatasetDescription',
829
+ namespaces=NAMESPACES):
830
+
831
+ observatory_groups = []
832
+ for o_g in ds.findall('cdas:ObservatoryGroup',
833
+ namespaces=NAMESPACES):
834
+ observatory_groups.append(o_g.text)
835
+
836
+ instrument_types = []
837
+ for i_t in ds.findall('cdas:InstrumentType',
838
+ namespaces=NAMESPACES):
839
+ instrument_types.append(i_t.text)
840
+
841
+ dataset_links = []
842
+ for d_l in ds.findall('cdas:DatasetLink',
843
+ namespaces=NAMESPACES):
844
+ dataset_links.append({
845
+ 'Title': d_l.find('cdas:Title',
846
+ namespaces=NAMESPACES).text,
847
+ 'Text': d_l.find('cdas:Text',
848
+ namespaces=NAMESPACES).text,
849
+ 'Url': d_l.find('cdas:Url',
850
+ namespaces=NAMESPACES).text,
851
+ })
852
+
853
+ observatories = []
854
+ for obs_elem in ds.findall('cdas:Observatory',
855
+ namespaces=NAMESPACES):
856
+ observatories.append(obs_elem.text)
857
+
858
+ instruments = []
859
+ for instr_elem in ds.findall('cdas:Instrument',
860
+ namespaces=NAMESPACES):
861
+ instruments.append(instr_elem.text)
862
+
863
+ dataset = {
864
+ 'Id': ds.find('cdas:Id', namespaces=NAMESPACES).text,
865
+ 'Observatory': observatories,
866
+ 'Instrument': instruments,
867
+ 'ObservatoryGroup': observatory_groups,
868
+ 'InstrumentType': instrument_types,
869
+ 'Label': ds.find('cdas:Label',
870
+ namespaces=NAMESPACES).text,
871
+ 'TimeInterval': {
872
+ 'Start': ds.find('cdas:TimeInterval/cdas:Start',
873
+ namespaces=NAMESPACES).text,
874
+ 'End': ds.find('cdas:TimeInterval/cdas:End',
875
+ namespaces=NAMESPACES).text
876
+ },
877
+ 'PiName': ds.find('cdas:PiName',
878
+ namespaces=NAMESPACES).text,
879
+ 'PiAffiliation': ds.find('cdas:PiAffiliation',
880
+ namespaces=NAMESPACES).text,
881
+ 'Notes': ds.find('cdas:Notes',
882
+ namespaces=NAMESPACES).text,
883
+ 'DatasetLink': dataset_links
884
+ }
885
+ doi = ds.find('cdas:Doi', namespaces=NAMESPACES)
886
+ if doi is not None:
887
+ dataset['Doi'] = doi.text
888
+
889
+ spase_resource_id = ds.find('cdas:SpaseResourceId',
890
+ namespaces=NAMESPACES)
891
+ if spase_resource_id is not None:
892
+ dataset['SpaseResourceId'] = spase_resource_id.text
893
+
894
+ additional_metadata = []
895
+ for add_meta in ds.findall('cdas:AdditionalMetadata',
896
+ namespaces=NAMESPACES):
897
+ meta_type = add_meta.attrib['Type']
898
+ value = add_meta.text
899
+ additional_metadata.append({
900
+ 'Type': meta_type,
901
+ 'value': value
902
+ })
903
+
904
+ if len(additional_metadata) > 0:
905
+ dataset['AdditionalMetadata'] = additional_metadata
906
+
907
+ datasets.append(dataset)
908
+
909
+ return sorted(datasets, key=itemgetter('Id'))
724
910
  # pylint: enable=too-many-branches
725
911
 
726
912
 
@@ -791,24 +977,23 @@ class CdasWs:
791
977
  self.logger.info('response.text: %s', response.text)
792
978
  return []
793
979
 
794
- inventory = response.json()
795
-
796
980
  if self.logger.level <= logging.DEBUG:
797
- self.logger.debug('inventory = %s',
798
- json.dumps(inventory, indent=4, sort_keys=True))
981
+ self.logger.debug('response.text = %s', response.text)
799
982
 
983
+ inventory = ET.fromstring(response.text)
800
984
  intervals = []
801
-
802
- data_intervals = inventory['InventoryDescription'][0]
803
-
804
- if 'TimeInterval' in data_intervals:
805
-
806
- for time_interval in data_intervals['TimeInterval']:
807
-
985
+ for inventory_desc in inventory.findall(\
986
+ 'cdas:InventoryDescription',
987
+ namespaces=NAMESPACES):
988
+ for time_interval in inventory_desc.findall(\
989
+ 'cdas:TimeInterval',
990
+ namespaces=NAMESPACES):
808
991
  intervals.append(
809
992
  TimeInterval(
810
- time_interval['Start'],
811
- time_interval['End']
993
+ time_interval.find('cdas:Start',
994
+ namespaces=NAMESPACES).text,
995
+ time_interval.find('cdas:End',
996
+ namespaces=NAMESPACES).text
812
997
  )
813
998
  )
814
999
 
@@ -881,12 +1066,36 @@ class CdasWs:
881
1066
  self.logger.info('response.text: %s', response.text)
882
1067
  return []
883
1068
 
884
- variables = response.json()
1069
+ if self.logger.level <= logging.DEBUG:
1070
+ self.logger.debug('response.text = %s', response.text)
885
1071
 
886
- if not variables:
887
- return []
1072
+ var_descriptions = ET.fromstring(response.text)
1073
+
1074
+ variables = []
1075
+ for var_description in var_descriptions.findall(\
1076
+ 'cdas:VariableDescription',
1077
+ namespaces=NAMESPACES):
1078
+ name = var_description.find('cdas:Name',
1079
+ namespaces=NAMESPACES).text
1080
+ short_description = var_description.find(\
1081
+ 'cdas:ShortDescription',
1082
+ namespaces=NAMESPACES).text
1083
+ if short_description is None:
1084
+ short_description = ''
1085
+
1086
+ long_description = var_description.find(\
1087
+ 'cdas:LongDescription',
1088
+ namespaces=NAMESPACES).text
1089
+ if long_description is None:
1090
+ long_description = ''
888
1091
 
889
- return variables['VariableDescription']
1092
+ variables.append({
1093
+ 'Name': name,
1094
+ 'ShortDescription': short_description,
1095
+ 'LongDescription': long_description
1096
+ })
1097
+
1098
+ return variables
890
1099
 
891
1100
 
892
1101
  def get_variable_names(
@@ -915,6 +1124,143 @@ class CdasWs:
915
1124
  return variable_names
916
1125
 
917
1126
 
1127
+ @staticmethod
1128
+ def _get_thumbnail_description_dict(
1129
+ file_description_elem: ET.Element
1130
+ ) -> Dict:
1131
+ """
1132
+ Gets ThumbnailDescription dictionary representation from the
1133
+ given FileDescription element.
1134
+
1135
+ Parameters
1136
+ ----------
1137
+ file_description_elem
1138
+ a FileDescription Element.
1139
+ Returns
1140
+ -------
1141
+ Dict
1142
+ a Dictionary representation of the ThumbnailDescription
1143
+ contained in the given FileDescription element.
1144
+ """
1145
+ thumbnail_desc = file_description_elem.find(\
1146
+ 'cdas:ThumbnailDescription',
1147
+ namespaces=NAMESPACES)
1148
+ if thumbnail_desc is not None:
1149
+ time_interval = thumbnail_desc.find('cdas:TimeInterval',
1150
+ namespaces=NAMESPACES)
1151
+ start = time_interval.find('cdas:Start',
1152
+ namespaces=NAMESPACES).text
1153
+ end = time_interval.find('cdas:End',
1154
+ namespaces=NAMESPACES).text
1155
+ return {
1156
+ 'Name': thumbnail_desc.find('cdas:Name',
1157
+ namespaces=NAMESPACES).text,
1158
+ 'Dataset': thumbnail_desc.find('cdas:Dataset',
1159
+ namespaces=NAMESPACES).text,
1160
+ 'TimeInterval': {
1161
+ 'Start': start,
1162
+ 'End': end
1163
+ },
1164
+ 'VarName': thumbnail_desc.find('cdas:VarName',
1165
+ namespaces=NAMESPACES).text,
1166
+ 'Options': int(thumbnail_desc.find(\
1167
+ 'cdas:Options',
1168
+ namespaces=NAMESPACES).text),
1169
+ 'NumFrames': int(thumbnail_desc.find(\
1170
+ 'cdas:NumFrames',
1171
+ namespaces=NAMESPACES).text),
1172
+ 'NumRows': int(thumbnail_desc.find(\
1173
+ 'cdas:NumRows',
1174
+ namespaces=NAMESPACES).text),
1175
+ 'NumCols': int(thumbnail_desc.find(\
1176
+ 'cdas:NumCols',
1177
+ namespaces=NAMESPACES).text),
1178
+ 'TitleHeight': int(thumbnail_desc.find(\
1179
+ 'cdas:TitleHeight',
1180
+ namespaces=NAMESPACES).text),
1181
+ 'ThumbnailHeight': int(thumbnail_desc.find(\
1182
+ 'cdas:ThumbnailHeight',
1183
+ namespaces=NAMESPACES).text),
1184
+ 'ThumbnailWidth': int(thumbnail_desc.find(\
1185
+ 'cdas:ThumbnailWidth',
1186
+ namespaces=NAMESPACES).text),
1187
+ 'StartRecord': int(thumbnail_desc.find(\
1188
+ 'cdas:StartRecord',
1189
+ namespaces=NAMESPACES).text),
1190
+ 'MyScale': float(thumbnail_desc.find(\
1191
+ 'cdas:MyScale',
1192
+ namespaces=NAMESPACES).text),
1193
+ 'XyStep': float(thumbnail_desc.find(\
1194
+ 'cdas:XyStep',
1195
+ namespaces=NAMESPACES).text)
1196
+ }
1197
+ return None
1198
+
1199
+
1200
+ @staticmethod
1201
+ def _get_data_result_dict(
1202
+ xml_data_result: str
1203
+ ) -> Dict:
1204
+ """
1205
+ Gets DataResult dictionary representation from the
1206
+ given XML DataResult element.
1207
+
1208
+ Parameters
1209
+ ----------
1210
+ xml_data_result
1211
+ XML representation of a DataResult.
1212
+ Returns
1213
+ -------
1214
+ Dict
1215
+ a Dictionary representation of the given XML representation
1216
+ of a DataResult.
1217
+ """
1218
+ data_result = ET.fromstring(xml_data_result)
1219
+ file_descriptions = []
1220
+ for file_description in data_result.findall(\
1221
+ 'cdas:FileDescription', namespaces=NAMESPACES):
1222
+
1223
+ dict_file_description = {
1224
+ 'Name': file_description.find('cdas:Name',
1225
+ namespaces=NAMESPACES).text,
1226
+ 'MimeType': file_description.find(\
1227
+ 'cdas:MimeType',
1228
+ namespaces=NAMESPACES).text,
1229
+ 'StartTime': file_description.find(\
1230
+ 'cdas:StartTime',
1231
+ namespaces=NAMESPACES).text,
1232
+ 'EndTime': file_description.find(\
1233
+ 'cdas:EndTime',
1234
+ namespaces=NAMESPACES).text,
1235
+ 'Length': int(file_description.find(\
1236
+ 'cdas:Length',
1237
+ namespaces=NAMESPACES).text),
1238
+ 'LastModified': file_description.find(\
1239
+ 'cdas:LastModified',
1240
+ namespaces=NAMESPACES).text
1241
+ }
1242
+ thumbnail_dict = CdasWs._get_thumbnail_description_dict(\
1243
+ file_description)
1244
+ if thumbnail_dict is not None:
1245
+ dict_file_description['ThumbnailDescription'] = \
1246
+ thumbnail_dict
1247
+
1248
+ thumbnail_id_elem = file_description.find(\
1249
+ 'cdas:ThumbnailId',
1250
+ namespaces=NAMESPACES)
1251
+ if thumbnail_id_elem is not None:
1252
+ dict_file_description['ThumbnailId'] = \
1253
+ thumbnail_id_elem.text
1254
+
1255
+ file_descriptions.append(dict_file_description)
1256
+
1257
+ if len(file_descriptions) > 0:
1258
+ return {
1259
+ 'FileDescription': file_descriptions
1260
+ }
1261
+ return None
1262
+
1263
+
918
1264
  def get_data_result(
919
1265
  self,
920
1266
  data_request: DataRequest,
@@ -962,18 +1308,10 @@ class CdasWs:
962
1308
  response = self._session.post(url, data=data_request.json(),
963
1309
  timeout=self._timeout)
964
1310
 
965
- try:
966
- data_result = response.json()
967
- except ValueError:
968
- # for example, a 503 from apache will not be json
969
- self.logger.debug('Non-JSON response: %s', response.text)
970
-
971
- if self.logger.level <= logging.DEBUG:
972
- self.logger.debug('data_result = %s',
973
- json.dumps(data_result, indent=4,
974
- sort_keys=True))
975
1311
  if response.status_code == 200:
976
1312
 
1313
+ data_result = CdasWs._get_data_result_dict(response.text)
1314
+
977
1315
  if not data_result:
978
1316
  return (response.status_code, None)
979
1317
 
@@ -1074,7 +1412,7 @@ class CdasWs:
1074
1412
  --------
1075
1413
  CdasWs.get_data : In addition to what get_data_file does,
1076
1414
  get_data also downloads and reads the data file into memory
1077
- (SpaceData object).
1415
+ (SpaceData or xarray.Dataset object).
1078
1416
  """
1079
1417
  # pylint: disable=too-many-locals
1080
1418
  # pylint: disable=too-many-return-statements
@@ -1308,7 +1646,7 @@ class CdasWs:
1308
1646
  Tuple
1309
1647
  [0] contains a dictionary of HTTP and CDAS status information.
1310
1648
  When successful, ['http']['status_code'] will be 200.<br>
1311
- [1] contains the requested data (SpaceData or xarray.Dateset
1649
+ [1] contains the requested data (SpaceData or xarray.Dataset
1312
1650
  object) or None.
1313
1651
  Raises
1314
1652
  ------
@@ -1972,14 +2310,20 @@ class CdasWs:
1972
2310
  self.logger.info('response.text: %s', response.text)
1973
2311
  return (response.status_code, None)
1974
2312
 
1975
- results = response.json()
1976
-
1977
2313
  if self.logger.level <= logging.DEBUG:
1978
- self.logger.debug('results: %s',
1979
- json.dumps(results,
1980
- indent=4, sort_keys=True))
2314
+ self.logger.debug('response.text = %s', response.text)
1981
2315
 
1982
- if not results:
1983
- return (response.status_code, None)
2316
+ results = ET.fromstring(response.text)
2317
+
2318
+ ssc_id = []
2319
+ for ssc_id_elem in results.findall('SscId'):
2320
+ ssc_id.append(ssc_id_elem.text)
2321
+
2322
+ if len(ssc_id) == 0:
2323
+ result = None
2324
+ elif len(ssc_id) == 1:
2325
+ result = ssc_id[0]
2326
+ else:
2327
+ result = ssc_id
1984
2328
 
1985
- return (response.status_code, results.get('SscId', None))
2329
+ return (response.status_code, result)
@@ -24,7 +24,7 @@
24
24
  #
25
25
  # NOSA HEADER END
26
26
  #
27
- # Copyright (c) 2019-2023 United States Government as represented by
27
+ # Copyright (c) 2019-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.
@@ -36,7 +36,7 @@ Package defining classes to represent the DataRequestEntity and its
36
36
  sub-classes from
37
37
  <https://cdaweb.gsfc.nasa.gov/WebServices/REST/CDAS.xsd>.<br>
38
38
 
39
- Copyright &copy; 2019-2023 United States Government as represented by the
39
+ Copyright &copy; 2019-2024 United States Government as represented by the
40
40
  National Aeronautics and Space Administration. No copyright is claimed in
41
41
  the United States under Title 17, U.S.Code. All Other Rights Reserved.
42
42
  """
@@ -378,6 +378,7 @@ class GraphOptions:
378
378
  related variables from different datasets will result in the
379
379
  same graphs being produced as when the option is not included.
380
380
  """
381
+ # pylint: disable=too-many-arguments
381
382
  def __init__(self,
382
383
  coarse_noise_filter: bool = False,
383
384
  x_axis_width_factor: int = 3,
@@ -391,6 +392,7 @@ class GraphOptions:
391
392
  self._y_axis_height_factor = y_axis_height_factor
392
393
  self._combine = combine
393
394
  self._overplot = overplot
395
+ # pylint: enable=too-many-arguments
394
396
 
395
397
 
396
398
  @property
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cdasws
3
- Version: 1.8.2
3
+ Version: 1.8.3
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
@@ -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.2",
13
+ version="1.8.3",
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",
@@ -19,6 +19,7 @@ setup(
19
19
  author_email="NASA-SPDF-Support@nasa.onmicrosoft.com",
20
20
  license="NOSA",
21
21
  packages=["cdasws"],
22
+ # python_requires=[">3.4"]
22
23
  # packages=find_packages(exclude=["tests"]),
23
24
  # packages=find_packages(),
24
25
  include_package_data=True,
File without changes
File without changes
File without changes
File without changes