sparclclient 1.2.5b1__tar.gz → 1.2.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.
Files changed (39) hide show
  1. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/PKG-INFO +1 -1
  2. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/source/conf.py +2 -2
  3. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/__init__.py +2 -1
  4. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/client.py +124 -102
  5. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/tests/expected_pat.py +11 -8
  6. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/tests/tests_api.py +16 -25
  7. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/.github/workflows/django.yml +0 -0
  8. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/.gitignore +0 -0
  9. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/.pre-commit-config.yaml +0 -0
  10. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/.readthedocs.yaml +0 -0
  11. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/LICENSE +0 -0
  12. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/Makefile +0 -0
  13. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/README.md +0 -0
  14. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/make.bat +0 -0
  15. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/pyproject.toml +0 -0
  16. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/requirements-client.txt +0 -0
  17. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/requirements-internal.txt +0 -0
  18. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/requirements.txt +0 -0
  19. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/source/index.rst +0 -0
  20. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/source/sparcl.rst +0 -0
  21. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/Results.py +0 -0
  22. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/benchmarks/Benchmark_SPARCL_example.ipynb +0 -0
  23. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/benchmarks/__init__.py +0 -0
  24. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/benchmarks/benchmarks.py +0 -0
  25. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/benchmarks/sparcl_benchmarking.ipynb +0 -0
  26. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/conf.py +0 -0
  27. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/exceptions.py +0 -0
  28. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/fields.py +0 -0
  29. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/gather_2d.py +0 -0
  30. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/notebooks/sparcl-examples.ipynb +0 -0
  31. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/resample_spectra.py +0 -0
  32. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/sparc.ini +0 -0
  33. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/type_conversion.py +0 -0
  34. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/unsupported.py +0 -0
  35. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/sparcl/utils.py +0 -0
  36. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/tests/expected_dev1.py +0 -0
  37. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/tests/methods_tests.py +0 -0
  38. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/tests/utils.py +0 -0
  39. {sparclclient-1.2.5b1 → sparclclient-1.2.6}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sparclclient
3
- Version: 1.2.5b1
3
+ Version: 1.2.6
4
4
  Summary: A client for getting spectra and meta-data from NOIRLab.
5
5
  Author-email: "S. Pothier" <datalab-spectro@noirlab.edu>
6
6
  Description-Content-Type: text/markdown
@@ -11,11 +11,11 @@
11
11
  # add these directories to sys.path here. If the directory is relative to the
12
12
  # documentation root, use os.path.abspath to make it absolute, like shown here.
13
13
 
14
+ from sparcl import __version__
14
15
  import os
15
16
  import re
16
17
  import sys
17
18
  sys.path.insert(0, os.path.abspath(".."))
18
- from sparcl import __version__
19
19
 
20
20
  # -- Project information -----------------------------------------------------
21
21
 
@@ -26,7 +26,7 @@ author = "S.Pothier, A.Jacques"
26
26
  #!version = client_version
27
27
  sver = __version__
28
28
  mo = re.match(
29
- "^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$",
29
+ "^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$", # noqa: E501, W605
30
30
  sver,
31
31
  )
32
32
  release = sver
@@ -34,4 +34,5 @@ __all__ = ["client", "align_records"]
34
34
  #__version__ = "1.2.2"
35
35
  #__version__ = "1.2.3"
36
36
  #__version__ = "1.2.4"
37
- __version__ = "1.2.5b1"
37
+ #__version__ = "1.2.5"
38
+ __version__ = "1.2.6"
@@ -159,6 +159,9 @@ class SparclClient: # was SparclApi()
159
159
  wait for server to send a response. Generally time to
160
160
  wait for first byte. Defaults to 5400.
161
161
 
162
+ announcement (:obj:`bool`, optional): SPARCL announcements.
163
+ Defaults to True.
164
+
162
165
  Example:
163
166
  >>> client = SparclClient()
164
167
 
@@ -179,6 +182,7 @@ class SparclClient: # was SparclApi()
179
182
  show_curl=False,
180
183
  connect_timeout=1.1, # seconds
181
184
  read_timeout=90 * 60, # seconds
185
+ announcement=True,
182
186
  ):
183
187
  """Create client instance."""
184
188
  session = requests.Session()
@@ -193,9 +197,8 @@ class SparclClient: # was SparclApi()
193
197
  self.verbose = verbose
194
198
  self.show_curl = show_curl # Show CURL equivalent of client method
195
199
  #!self.internal_names = internal_names
196
- self.c_timeout = min(
197
- MAX_CONNECT_TIMEOUT, float(connect_timeout)
198
- ) # seconds
200
+ self.c_timeout = min(MAX_CONNECT_TIMEOUT,
201
+ float(connect_timeout)) # seconds
199
202
  self.r_timeout = min(MAX_READ_TIMEOUT, float(read_timeout)) # seconds
200
203
 
201
204
  # require response within this num seconds
@@ -203,10 +206,18 @@ class SparclClient: # was SparclApi()
203
206
  # (connect timeout, read timeout) in seconds
204
207
  self.timeout = (self.c_timeout, self.r_timeout)
205
208
  # @@@ read timeout should be a function of the POST payload size
209
+ self.announcement = announcement
206
210
 
207
211
  if verbose:
208
212
  print(f"apiurl={self.apiurl}")
209
213
 
214
+ if announcement:
215
+ ann = f"{self.apiurl}/announcement/"
216
+ annres = requests.get(ann, timeout=self.timeout)
217
+ annstr = annres.json()['announcement']
218
+ if annstr:
219
+ print(f"announcement={annstr}")
220
+
210
221
  # Get API Version
211
222
  try:
212
223
  endpoint = f"{self.apiurl}/version/"
@@ -249,18 +260,19 @@ class SparclClient: # was SparclApi()
249
260
  f" client_hash={ut.githash()},"
250
261
  f" verbose={self.verbose},"
251
262
  f" connect_timeout={self.c_timeout},"
252
- f" read_timeout={self.r_timeout})"
263
+ f" read_timeout={self.r_timeout},"
264
+ f" announcement={self.announcement})"
253
265
  )
254
266
 
255
267
  def token_expired(self, renew=False):
256
268
  """
257
- POST http://localhost:8050/sparc/renew_token/
258
- Content-Type: application/json
259
- {
260
- "refresh_token": "..."
261
- }
269
+ POST http://localhost:8050/sparc/renew_token/
270
+ Content-Type: application/json
271
+ {
272
+ "refresh_token": "..."
273
+ }
262
274
 
263
- Returns an 'access' token
275
+ Returns an 'access' token
264
276
  """
265
277
  now = datetime.datetime.now()
266
278
  expired = True
@@ -274,8 +286,8 @@ class SparclClient: # was SparclApi()
274
286
  resp = requests.post(url, json={"refresh_token": self.renew_token})
275
287
  resp.raise_for_status()
276
288
  data = resp.json()
277
- #@print(f"{data=}")
278
- self.token = data['access']
289
+ # @print(f"{data=}")
290
+ self.token = data["access"]
279
291
  self.set_token_exp()
280
292
  expired = False
281
293
 
@@ -322,8 +334,8 @@ class SparclClient: # was SparclApi()
322
334
  try:
323
335
  res.raise_for_status()
324
336
  #!print(f"DBG: {res.content=}")
325
- self.token = res.json()['access']
326
- self.renew_token = res.json()['refresh']
337
+ self.token = res.json()["access"]
338
+ self.renew_token = res.json()["refresh"]
327
339
  self.session.auth = (email, password)
328
340
  except Exception:
329
341
  self.session.auth = None
@@ -331,8 +343,8 @@ class SparclClient: # was SparclApi()
331
343
  self.renew_token = None
332
344
  self.token_exp = None
333
345
  msg = (
334
- "Could not login with given credentials."
335
- ' Reverted to "Anonymous" user.'
346
+ 'Could not login with given credentials. '
347
+ 'Reverted to "Anonymous" user.'
336
348
  )
337
349
  return msg
338
350
 
@@ -343,10 +355,12 @@ class SparclClient: # was SparclApi()
343
355
  def set_token_exp(self):
344
356
  decoded = jwt.decode(
345
357
  self.token,
346
- algorithms=['HS256',],
347
- options={'verify_signature': False}
358
+ algorithms=[
359
+ "HS256",
360
+ ],
361
+ options={"verify_signature": False},
348
362
  )
349
- self.token_exp = datetime.datetime.fromtimestamp(decoded['exp'])
363
+ self.token_exp = datetime.datetime.fromtimestamp(decoded["exp"])
350
364
 
351
365
  def logout(self):
352
366
  """Logout of the SPARCL service.
@@ -398,10 +412,10 @@ class SparclClient: # was SparclApi()
398
412
  parameter of client.retrieve().
399
413
 
400
414
  Args:
401
- dataset_list (:obj:`list`, optional): List of data sets from
402
- which to get the default fields. Defaults to None, which
403
- will return the intersection of default fields in all
404
- data sets hosted on the SPARCL database.
415
+ dataset_list (:obj:`list` of :obj:`str`, optional): List of
416
+ data sets from which to get the default fields. Defaults
417
+ to None, which will return the intersection of default
418
+ fields in all data sets hosted on the SPARCL database.
405
419
 
406
420
  Returns:
407
421
  List of fields tagged as 'default' from DATASET_LIST.
@@ -415,9 +429,9 @@ class SparclClient: # was SparclApi()
415
429
  if dataset_list is None:
416
430
  dataset_list = self.fields.all_drs
417
431
 
418
- assert isinstance(
419
- dataset_list, (list, set)
420
- ), f"DATASET_LIST must be a list. Found {dataset_list}"
432
+ assert isinstance(dataset_list, (list, set)), (
433
+ f"DATASET_LIST must be a list. Found {dataset_list}"
434
+ )
421
435
 
422
436
  common = set(self.fields.common(dataset_list))
423
437
  union = self.fields.default_retrieve_fields(dataset_list=dataset_list)
@@ -429,10 +443,10 @@ class SparclClient: # was SparclApi()
429
443
  of client.retrieve().
430
444
 
431
445
  Args:
432
- dataset_list (:obj:`list`, optional): List of data sets from
433
- which to get all fields. Defaults to None, which
434
- will return the intersection of all fields in all
435
- data sets hosted on the SPARCL database.
446
+ dataset_list (:obj:`list` of :obj:`str`, optional): List of data
447
+ sets from which to get all fields. Defaults to None, which
448
+ will return the intersection of all fields in all data sets
449
+ hosted on the SPARCL database.
436
450
 
437
451
  Returns:
438
452
  List of fields tagged as 'all' from DATASET_LIST.
@@ -458,16 +472,15 @@ class SparclClient: # was SparclApi()
458
472
  drs = self.fields.all_drs if dataset_list is None else dataset_list
459
473
  msg = (
460
474
  f'Unknown fields "{",".join(unk)}" given '
461
- f'for DataSets {",".join(drs)}. '
462
- f'Allowed fields are: {",".join(all)}. '
475
+ f"for DataSets {','.join(drs)}. "
476
+ f"Allowed fields are: {','.join(all)}. "
463
477
  )
464
478
  raise ex.UnknownField(msg)
465
479
  return True
466
480
 
467
481
  def _common_internal(self, *, science_fields=None, dataset_list=None):
468
- self._validate_science_fields(
469
- science_fields, dataset_list=dataset_list
470
- )
482
+ self._validate_science_fields(science_fields,
483
+ dataset_list=dataset_list)
471
484
 
472
485
  if dataset_list is None:
473
486
  dataset_list = self.fields.all_drs
@@ -487,10 +500,10 @@ class SparclClient: # was SparclApi()
487
500
  client.retreive().
488
501
 
489
502
  Args:
490
- dataset_list (:obj:`list`, optional): List of data sets from
491
- which to get available fields. Defaults to None, which
492
- will return the intersection of all available fields in
493
- all data sets hosted on the SPARCL database.
503
+ dataset_list (:obj:`list` of :obj:`str`, optional): List of data
504
+ sets from which to get available fields. Defaults to None,
505
+ which will return the intersection of all available fields
506
+ in all data sets hosted on the SPARCL database.
494
507
 
495
508
  Returns:
496
509
  Set of fields available from data sets in DATASET_LIST.
@@ -543,10 +556,10 @@ class SparclClient: # was SparclApi()
543
556
  """Find records in the SPARCL database.
544
557
 
545
558
  Args:
546
- outfields (:obj:`list`, optional): List of fields to return.
547
- Only CORE fields may be passed to this parameter.
548
- Defaults to None, which will return only the sparcl_id
549
- and _dr fields.
559
+ outfields (:obj:`list` of :obj:`str`, optional): List of
560
+ fields to return. Only CORE fields may be passed to
561
+ this parameter. Defaults to None, which will return
562
+ only the sparcl_id and _dr fields.
550
563
 
551
564
  constraints (:obj:`dict`, optional): Key-Value pairs of
552
565
  constraints to place on the record selection. The Key
@@ -591,12 +604,10 @@ class SparclClient: # was SparclApi()
591
604
  #! dataset_list=dataset_list) # DLS-401
592
605
  dr = list(dataset_list)[0]
593
606
  if len(constraints) > 0:
594
- self._validate_science_fields(
595
- constraints.keys(), dataset_list=dataset_list
596
- )
607
+ self._validate_science_fields(constraints.keys(),
608
+ dataset_list=dataset_list)
597
609
  constraints = {
598
- self.fields._internal_name(k, dr): v
599
- for k, v in constraints.items()
610
+ self.fields._internal_name(k, dr): v for k, v in constraints.items() # noqa: E501
600
611
  }
601
612
  uparams = dict(
602
613
  limit=limit,
@@ -622,7 +633,7 @@ class SparclClient: # was SparclApi()
622
633
 
623
634
  if res.status_code != 200:
624
635
  if verbose and ("traceback" in res.json()):
625
- print(f'DBG: Server traceback=\n{res.json()["traceback"]}')
636
+ print(f"DBG: Server traceback=\n{res.json()['traceback']}")
626
637
  raise ex.genSparclException(res, verbose=self.verbose)
627
638
 
628
639
  found = Found(res.json(), client=self)
@@ -637,11 +648,11 @@ class SparclClient: # was SparclApi()
637
648
  NOT stored in the SPARCL database.
638
649
 
639
650
  Args:
640
- uuid_list (:obj:`list`): List of sparcl_ids.
651
+ uuid_list (:obj:`list` of :obj:`str`): List of sparcl_ids.
641
652
 
642
- dataset_list (:obj:`list`, optional): List of data sets from
643
- which to find missing sparcl_ids. Defaults to None, meaning
644
- all data sets hosted on the SPARCL database.
653
+ dataset_list (:obj:`list` of :obj:`str`, optional): List of data
654
+ sets from which to find missing sparcl_ids. Defaults to None,
655
+ meaning all data sets hosted on the SPARCL database.
645
656
 
646
657
  countOnly (:obj:`bool`, optional): Set to True to return only
647
658
  a count of the missing sparcl_ids from the uuid_list.
@@ -656,16 +667,16 @@ class SparclClient: # was SparclApi()
656
667
 
657
668
  Example:
658
669
  >>> client = SparclClient()
659
- >>> ids = ['ddbb57ee-8e90-4a0d-823b-0f5d97028076',]
660
- >>> client.missing(ids)
670
+ >>> sparcl_ids = ['ddbb57ee-8e90-4a0d-823b-0f5d97028076',]
671
+ >>> client.missing(uuid_list=sparcl_ids)
661
672
  ['ddbb57ee-8e90-4a0d-823b-0f5d97028076']
662
673
  """
663
674
 
664
675
  if dataset_list is None:
665
676
  dataset_list = self.fields.all_drs
666
- assert isinstance(
667
- dataset_list, (list, set)
668
- ), f"DATASET_LIST must be a list. Found {dataset_list}"
677
+ assert isinstance(dataset_list, (list, set)), (
678
+ f"DATASET_LIST must be a list. Found {dataset_list}"
679
+ )
669
680
 
670
681
  verbose = verbose or self.verbose
671
682
  uparams = dict(dataset_list=",".join(dataset_list))
@@ -692,11 +703,11 @@ class SparclClient: # was SparclApi()
692
703
  NOT stored in the SPARCL database.
693
704
 
694
705
  Args:
695
- specid_list (:obj:`list`): List of specids.
706
+ specid_list (:obj:`list` of :obj:`int`): List of specids.
696
707
 
697
- dataset_list (:obj:`list`, optional): List of data sets from
698
- which to find missing specids. Defaults to None, meaning
699
- all data sets hosted on the SPARCL database.
708
+ dataset_list (:obj:`list` of :obj:`str`, optional): List of data
709
+ sets from which to find missing specids. Defaults to None,
710
+ meaning all data sets hosted on the SPARCL database.
700
711
 
701
712
  countOnly (:obj:`bool`, optional): Set to True to return only
702
713
  a count of the missing specids from the specid_list.
@@ -711,16 +722,15 @@ class SparclClient: # was SparclApi()
711
722
 
712
723
  Example:
713
724
  >>> client = SparclClient()
714
- >>> found = client.find(outfields=['specid'], limit=2)
715
- >>> specids = [f.specid for f in found.records]
716
- >>> client.missing_specids(specids + ['bad_id'])
717
- ['bad_id']
725
+ >>> specids = [398913623742323421, 6181239242670493696]
726
+ >>> client.missing_specids(specid_list=specids)
727
+ [398913623742323421]
718
728
  """
719
729
  if dataset_list is None:
720
730
  dataset_list = self.fields.all_drs
721
- assert isinstance(
722
- dataset_list, (list, set)
723
- ), f"DATASET_LIST must be a list. Found {dataset_list}"
731
+ assert isinstance(dataset_list, (list, set)), (
732
+ f"DATASET_LIST must be a list. Found {dataset_list}"
733
+ )
724
734
 
725
735
  verbose = verbose or self.verbose
726
736
  uparams = dict(dataset_list=",".join(dataset_list))
@@ -756,13 +766,13 @@ class SparclClient: # was SparclApi()
756
766
  unknown = inc_set.difference(avail_science)
757
767
  if len(unknown) > 0:
758
768
  msg = (
759
- f'The INCLUDE list ({",".join(sorted(include_list))}) '
769
+ f"The INCLUDE list ({','.join(sorted(include_list))}) "
760
770
  f"contains invalid data field names "
761
- f'for Data Sets ({",".join(sorted(dataset_list))}). '
771
+ f"for Data Sets ({','.join(sorted(dataset_list))}). "
762
772
  f"Unknown fields are: "
763
- f'{", ".join(sorted(list(unknown)))}. '
773
+ f"{', '.join(sorted(list(unknown)))}. "
764
774
  f"Available fields are: "
765
- f'{", ".join(sorted(avail_science))}.'
775
+ f"{', '.join(sorted(avail_science))}."
766
776
  )
767
777
  raise ex.BadInclude(msg)
768
778
  return True
@@ -780,15 +790,15 @@ class SparclClient: # was SparclApi()
780
790
  sparcl_ids.
781
791
 
782
792
  Args:
783
- uuid_list (:obj:`list`): List of sparcl_ids.
793
+ uuid_list (:obj:`list` of :obj:`str`): List of sparcl_ids.
784
794
 
785
- include (:obj:`list`, optional): List of field names to include
786
- in each record. Defaults to 'DEFAULT', which will return
787
- the fields tagged as 'default'.
795
+ include (:obj:`list` of :obj:`str`, optional): List of field
796
+ names to include in each record. Defaults to 'DEFAULT',
797
+ which will return the fields tagged as 'default'.
788
798
 
789
- dataset_list (:obj:`list`, optional): List of data sets from
790
- which to retrieve spectra data. Defaults to None, meaning all
791
- data sets hosted on the SPARCL database.
799
+ dataset_list (:obj:`list` of :obj:`str`, optional): List of data
800
+ sets from which to retrieve spectra data. Defaults to None,
801
+ meaning all data sets hosted on the SPARCL database.
792
802
 
793
803
  limit (:obj:`int`, optional): Maximum number of records to
794
804
  return. Defaults to 500. Maximum allowed is 24,000.
@@ -827,9 +837,9 @@ class SparclClient: # was SparclApi()
827
837
  orig_dataset_list = dataset_list
828
838
  if dataset_list is None:
829
839
  dataset_list = self.fields.all_drs
830
- assert isinstance(
831
- dataset_list, (list, set)
832
- ), f"DATASET_LIST must be a list. Found {dataset_list}"
840
+ assert isinstance(dataset_list, (list, set)), (
841
+ f"DATASET_LIST must be a list. Found {dataset_list}"
842
+ )
833
843
 
834
844
  verbose = self.verbose if verbose is None else verbose
835
845
 
@@ -920,7 +930,7 @@ class SparclClient: # was SparclApi()
920
930
  print(f"DBG: Server response=\n{res.text}")
921
931
  # @@@ FAILS on invalid JSON. Maybe not json at all !!!
922
932
  if verbose and ("traceback" in res.json()):
923
- print(f'DBG: Server traceback=\n{res.json()["traceback"]}')
933
+ print(f"DBG: Server traceback=\n{res.json()['traceback']}")
924
934
  raise ex.genSparclException(res, verbose=verbose)
925
935
 
926
936
  if format == "json":
@@ -944,26 +954,26 @@ class SparclClient: # was SparclApi()
944
954
  count = len(results) - 1
945
955
  print(
946
956
  f"Got {count} spectra in "
947
- f"{elapsed:.2f} seconds ({count/elapsed:.0f} "
957
+ f"{elapsed:.2f} seconds ({count / elapsed:.0f} "
948
958
  "spectra/sec)"
949
959
  )
950
- print(f'{meta["status"]}')
951
-
952
- # Format/consolodate the server messages to one message with the count of missing
953
- # files
960
+ print(f"{meta['status']}")
961
+
962
+ # Format/consolodate the server messages to one message with
963
+ # the count of missing files
954
964
  if len(meta["status"].get("warnings", [])) > 0:
955
965
  warnings = meta["status"].get("warnings")
956
966
  if verbose:
957
967
  print(f"There are {len(warnings)} warnings")
958
968
  missingcount = 0
959
- missing_message = re.sub(r' [0-9]+ ', ' %s ', warnings[0])
969
+ missing_message = re.sub(r" [0-9]+ ", " %s ", warnings[0])
960
970
  for i in warnings:
961
- matches = re.match(r'.* ([0-9]+) out of the ([0-9]+).*', i)
971
+ matches = re.match(r".* ([0-9]+) out of the ([0-9]+).*", i)
962
972
  if matches:
963
973
  missingcount += int(matches.groups()[0])
964
974
 
965
975
  # using old style substitution to avoid issue with the {} in the message # noqa: E501
966
- warning_message = missing_message % (missingcount, req_num, missingcount) # noqa: E501
976
+ warning_message = missing_message % (missingcount, req_num, missingcount) # noqa: E501
967
977
  warn(warning_message, stacklevel=2)
968
978
 
969
979
  return Retrieved(results, client=self)
@@ -983,15 +993,15 @@ class SparclClient: # was SparclApi()
983
993
  specids.
984
994
 
985
995
  Args:
986
- specid_list (:obj:`list`): List of specids.
996
+ specid_list (:obj:`list` of :obj:`int`): List of specids.
987
997
 
988
- include (:obj:`list`, optional): List of field names to include
989
- in each record. Defaults to 'DEFAULT', which will return
990
- the fields tagged as 'default'.
998
+ include (:obj:`list` of :obj:`str`, optional): List of field
999
+ names to include in each record. Defaults to 'DEFAULT',
1000
+ which will return the fields tagged as 'default'.
991
1001
 
992
- dataset_list (:obj:`list`, optional): List of data sets from
993
- which to retrieve spectra data. Defaults to None, meaning all
994
- data sets hosted on the SPARCL database.
1002
+ dataset_list (:obj:`list` of :obj:`str`, optional): List of data
1003
+ sets from which to retrieve spectra data. Defaults to None,
1004
+ meaning all data sets hosted on the SPARCL database.
995
1005
 
996
1006
  limit (:obj:`int`, optional): Maximum number of records to
997
1007
  return. Defaults to 500. Maximum allowed is 24,000.
@@ -1016,9 +1026,9 @@ class SparclClient: # was SparclApi()
1016
1026
  f'The "specid_list" parameter must be a python list. '
1017
1027
  f"You used a value of type {type(specid_list)}."
1018
1028
  )
1019
- assert (
1020
- len(specid_list) > 0
1021
- ), f'The "specid_list" parameter value must be a non-empty list'
1029
+ assert len(specid_list) > 0, (
1030
+ f'The "specid_list" parameter value must be a non-empty list'
1031
+ )
1022
1032
  assert isinstance(specid_list[0], int), (
1023
1033
  f'The "specid_list" parameter must be a python list of INTEGERS. '
1024
1034
  f"You used an element value of type {type(specid_list[0])}."
@@ -1026,8 +1036,10 @@ class SparclClient: # was SparclApi()
1026
1036
 
1027
1037
  if dataset_list is None:
1028
1038
  constraints = {"specid": specid_list}
1039
+ dr_list = self.fields.all_drs
1029
1040
  else:
1030
1041
  constraints = {"specid": specid_list, "data_release": dataset_list}
1042
+ dr_list = dataset_list
1031
1043
 
1032
1044
  # Science Field Name for uuid.
1033
1045
  dr = list(self.fields.all_drs)[0]
@@ -1036,6 +1048,16 @@ class SparclClient: # was SparclApi()
1036
1048
  found = self.find([idfld], constraints=constraints, limit=limit)
1037
1049
  if verbose:
1038
1050
  print(f"Found {found.count} matches.")
1051
+ if found.count < len(specid_list):
1052
+ usrcount = len(specid_list)
1053
+ dbcount = found.count
1054
+ warn = (
1055
+ f"UserWarning: Some specIDs were not found. "
1056
+ f"{usrcount - dbcount} out of the {usrcount} requested "
1057
+ f"specids have no records available in the SPARCL database "
1058
+ f"associated with DataSets {dr_list}."
1059
+ )
1060
+ print(warn)
1039
1061
  res = self.retrieve(
1040
1062
  found.ids,
1041
1063
  #! svc=svc,
@@ -98,30 +98,33 @@ authorized_1 = {
98
98
 
99
99
  authorized_2 = {
100
100
  "Loggedin_As": "test_user_2@noirlab.edu",
101
- "Authorized_Datasets": {"BOSS-DR16", "DESI-EDR", "SDSS-DR16"},
101
+ "Authorized_Datasets": {"BOSS-DR16", "DESI-DR1", "DESI-EDR", "SDSS-DR16"},
102
102
  }
103
103
 
104
104
  authorized_3 = {
105
105
  "Loggedin_As": "Anonymous",
106
- "Authorized_Datasets": {"BOSS-DR16", "DESI-EDR", "SDSS-DR16"},
106
+ "Authorized_Datasets": {"BOSS-DR16", "DESI-DR1", "DESI-EDR", "SDSS-DR16"},
107
107
  }
108
108
 
109
109
  # Private and Public
110
110
  pub_1 = ["BOSS-DR16"]
111
- pub_all = ["BOSS-DR16", "DESI-EDR", "SDSS-DR16"]
112
- priv = ["DESI-DR1", "SDSS-DR17-test", "BOSS-DR17", "SDSS-DR17"]
111
+ pub_all = ["BOSS-DR16", "DESI-DR1", "DESI-EDR", "SDSS-DR16"]
112
+ priv = ["SDSS-DR17-test", "BOSS-DR17", "SDSS-DR17"]
113
113
  all_all = pub_all + priv
114
114
  all_all.sort()
115
115
  privpub1 = [pub_all[0], priv[0]]
116
116
  unauth = "test_user_2@noirlab.edu"
117
- #
118
- auth_find_1 = privpub1
119
- auth_find_2 = ['DESI-DR1', 'DESI-EDR']
117
+ msg = "Find Results: 1000 records"
118
+ # OLD as of July 9, 2025
119
+ #auth_find_1 = privpub1
120
+ #auth_find_2 = ['DESI-DR1', 'DESI-EDR']
121
+ auth_find_1 = auth_find_2 = auth_find_4 = auth_find_6 = msg
120
122
  auth_find_3 = auth_retrieve_3 = (f"[DSDENIED] uname='{unauth}' is declined "
121
123
  f"access to datasets={[priv[0]]}; "
122
124
  f"drs_requested={privpub1} "
123
125
  f"my_auth={pub_all}")
124
- auth_find_4 = auth_find_6 = pub_all
126
+ # OLD as of July 9, 2025
127
+ #auth_find_4 = auth_find_6 = pub_all
125
128
  auth_find_5 = auth_retrieve_6 = ("[DSDENIED] uname='ANONYMOUS' is declined "
126
129
  f"access to datasets={[priv[0]]}; "
127
130
  f"drs_requested={privpub1} "
@@ -175,6 +175,7 @@ class SparclClientTest(unittest.TestCase):
175
175
  url=serverurl,
176
176
  verbose=clverb,
177
177
  show_curl=showcurl,
178
+ announcement=False,
178
179
  )
179
180
  cls.timing = dict()
180
181
  cls.doc = dict()
@@ -286,7 +287,7 @@ class SparclClientTest(unittest.TestCase):
286
287
 
287
288
  def test_missing_specids_1(self):
288
289
  """Specids (not UUID) missing"""
289
- badid = "NOT_SPEC_ID"
290
+ badid = 0
290
291
  specids = set([badid] + self.specid_list0[:1])
291
292
  missing = set(self.client.missing_specids(specids, verbose=False))
292
293
  if showact:
@@ -296,11 +297,9 @@ class SparclClientTest(unittest.TestCase):
296
297
 
297
298
  def test_retrieve_0(self):
298
299
  """Get spectra using small list of SPECIDS."""
299
- drs = ["SDSS-DR16", "BOSS-DR16", "DESI-EDR"]
300
300
  res = self.client.retrieve_by_specid(
301
301
  self.specid_list0,
302
- include=["sparcl_id", "specid", "flux"],
303
- dataset_list=drs,
302
+ include=["sparcl_id", "specid", "flux"]
304
303
  )
305
304
  actual = sorted(res.records[0].keys())
306
305
  if showact:
@@ -312,10 +311,9 @@ class SparclClientTest(unittest.TestCase):
312
311
  """Get spectra using small list of uuids."""
313
312
  name = "retrieve_0b"
314
313
  uuids = self.uuid_list0
315
- drs = ["SDSS-DR16", "BOSS-DR16", "DESI-EDR"]
316
314
 
317
315
  tic()
318
- res = self.client.retrieve(uuids, dataset_list=drs)
316
+ res = self.client.retrieve(uuids)
319
317
  self.timing[name] = toc()
320
318
  actual = sorted(res.records[0].keys())
321
319
 
@@ -356,11 +354,9 @@ class SparclClientTest(unittest.TestCase):
356
354
 
357
355
  def test_retrieve_5(self):
358
356
  """Limit number of records returned by retrieve_by_specid."""
359
- drs = ["SDSS-DR16", "BOSS-DR16", "DESI-EDR"]
360
357
  res = self.client.retrieve_by_specid(
361
358
  self.specid_list5,
362
359
  include=["specid", "ivar"],
363
- dataset_list=drs,
364
360
  limit=2,
365
361
  )
366
362
  actual = len(res.records)
@@ -485,8 +481,7 @@ class SparclClientTest(unittest.TestCase):
485
481
  ids = self.uuid_list2
486
482
 
487
483
  tic()
488
- drs = ["SDSS-DR16", "BOSS-DR16", "DESI-EDR"]
489
- res = self.client.retrieve(ids, dataset_list=drs)
484
+ res = self.client.retrieve(ids)
490
485
  self.timing[name] = toc()
491
486
  res_reorder = res.reorder(ids)
492
487
  actual = [f["sparcl_id"] for f in res_reorder.records]
@@ -500,8 +495,7 @@ class SparclClientTest(unittest.TestCase):
500
495
  specids = self.specid_list2
501
496
 
502
497
  tic()
503
- drs = ["SDSS-DR16", "BOSS-DR16", "DESI-EDR"]
504
- res = self.client.retrieve_by_specid(specids, dataset_list=drs)
498
+ res = self.client.retrieve_by_specid(specids)
505
499
  self.timing[name] = toc()
506
500
  res_reorder = res.reorder(specids)
507
501
  actual = [f["specid"] for f in res_reorder.records]
@@ -516,9 +510,8 @@ class SparclClientTest(unittest.TestCase):
516
510
  ids = self.uuid_list3
517
511
 
518
512
  tic()
519
- drs = ["SDSS-DR16", "BOSS-DR16", "DESI-EDR"]
520
513
  with self.assertWarns(Warning):
521
- res = self.client.retrieve(ids, dataset_list=drs)
514
+ res = self.client.retrieve(ids)
522
515
  self.timing[name] = toc()
523
516
  with self.assertWarns(Warning):
524
517
  res_reorder = res.reorder(ids)
@@ -534,8 +527,7 @@ class SparclClientTest(unittest.TestCase):
534
527
  specids = self.specid_list3
535
528
 
536
529
  tic()
537
- drs = ["SDSS-DR16", "BOSS-DR16", "DESI-EDR"]
538
- res = self.client.retrieve_by_specid(specids, dataset_list=drs)
530
+ res = self.client.retrieve_by_specid(specids)
539
531
  self.timing[name] = toc()
540
532
  with self.assertWarns(Warning):
541
533
  res_reorder = res.reorder(specids)
@@ -554,8 +546,7 @@ class SparclClientTest(unittest.TestCase):
554
546
  og_ids = []
555
547
 
556
548
  tic()
557
- drs = ["SDSS-DR16", "BOSS-DR16", "DESI-EDR"]
558
- res = self.client.retrieve(ids, dataset_list=drs)
549
+ res = self.client.retrieve(ids)
559
550
  self.timing[name] = toc()
560
551
  with self.assertRaises(ex.NoIDs):
561
552
  res.reorder(og_ids)
@@ -568,8 +559,7 @@ class SparclClientTest(unittest.TestCase):
568
559
  og_specids = []
569
560
 
570
561
  tic()
571
- drs = ["SDSS-DR16", "BOSS-DR16", "DESI-EDR"]
572
- res = self.client.retrieve_by_specid(specids, dataset_list=drs)
562
+ res = self.client.retrieve_by_specid(specids)
573
563
  self.timing[name] = toc()
574
564
  with self.assertRaises(ex.NoIDs):
575
565
  res.reorder(og_specids)
@@ -739,7 +729,7 @@ class AuthTest(unittest.TestCase):
739
729
  )
740
730
 
741
731
  cls.client = sparcl.client.SparclClient(
742
- url=serverurl, verbose=clverb, show_curl=showcurl
732
+ url=serverurl, verbose=clverb, show_curl=showcurl,
743
733
  )
744
734
 
745
735
  global show_run_context
@@ -756,8 +746,8 @@ class AuthTest(unittest.TestCase):
756
746
  cls.unauth_user = "test_user_2@noirlab.edu"
757
747
 
758
748
  # Dataset lists
759
- cls.Pub = ["BOSS-DR16", "DESI-EDR", "SDSS-DR16"]
760
- cls.Priv = ["DESI-DR1", "SDSS-DR17-test", "BOSS-DR17", "SDSS-DR17"]
749
+ cls.Pub = ["BOSS-DR16", "DESI-DR1", "DESI-EDR", "SDSS-DR16"]
750
+ cls.Priv = ["SDSS-DR17-test", "BOSS-DR17", "SDSS-DR17"]
761
751
  cls.PrivPub = cls.Priv + cls.Pub
762
752
  cls.PrivPub.sort()
763
753
  cls.PrivPub1 = [cls.Priv[0], cls.Pub[0]]
@@ -921,7 +911,7 @@ class AuthTest(unittest.TestCase):
921
911
  print(f"authorized_3: actual={actual}")
922
912
  self.assertEqual(actual, exp.authorized_3, msg="Actual to Expected")
923
913
 
924
- def auth_find(self, user, drs, expvar, cons={}, limit=21000):
914
+ def auth_find(self, user, drs, expvar, cons={}, limit=1000):
925
915
  expected = eval(expvar) # e.g. 'ep.retrieve_N'
926
916
  #!print(f'{expvar}: {user=} {drs=} ')
927
917
  self.silent_login(user, usrpw)
@@ -943,7 +933,8 @@ class AuthTest(unittest.TestCase):
943
933
  #!if showact:
944
934
  #! print(f"{expvar}: {found.records=}")
945
935
 
946
- actual = sorted(set([r._dr for r in found.records]))
936
+ #actual = sorted(set([r._dr for r in found.records]))
937
+ actual = str(found)
947
938
  except Exception as err:
948
939
  actual = str(err)
949
940
  finally:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes