sparclclient 1.2.6b11__py2.py3-none-any.whl → 1.2.6b13__py2.py3-none-any.whl

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.
sparcl/__init__.py CHANGED
@@ -35,4 +35,4 @@ __all__ = ["client", "align_records"]
35
35
  #__version__ = "1.2.3"
36
36
  #__version__ = "1.2.4"
37
37
  #__version__ = "1.2.5"
38
- __version__ = "1.2.6b11"
38
+ __version__ = "1.2.6b13"
sparcl/client.py CHANGED
@@ -197,9 +197,8 @@ class SparclClient: # was SparclApi()
197
197
  self.verbose = verbose
198
198
  self.show_curl = show_curl # Show CURL equivalent of client method
199
199
  #!self.internal_names = internal_names
200
- self.c_timeout = min(
201
- MAX_CONNECT_TIMEOUT, float(connect_timeout)
202
- ) # seconds
200
+ self.c_timeout = min(MAX_CONNECT_TIMEOUT,
201
+ float(connect_timeout)) # seconds
203
202
  self.r_timeout = min(MAX_READ_TIMEOUT, float(read_timeout)) # seconds
204
203
 
205
204
  # require response within this num seconds
@@ -267,13 +266,13 @@ class SparclClient: # was SparclApi()
267
266
 
268
267
  def token_expired(self, renew=False):
269
268
  """
270
- POST http://localhost:8050/sparc/renew_token/
271
- Content-Type: application/json
272
- {
273
- "refresh_token": "..."
274
- }
269
+ POST http://localhost:8050/sparc/renew_token/
270
+ Content-Type: application/json
271
+ {
272
+ "refresh_token": "..."
273
+ }
275
274
 
276
- Returns an 'access' token
275
+ Returns an 'access' token
277
276
  """
278
277
  now = datetime.datetime.now()
279
278
  expired = True
@@ -287,8 +286,8 @@ class SparclClient: # was SparclApi()
287
286
  resp = requests.post(url, json={"refresh_token": self.renew_token})
288
287
  resp.raise_for_status()
289
288
  data = resp.json()
290
- #@print(f"{data=}")
291
- self.token = data['access']
289
+ # @print(f"{data=}")
290
+ self.token = data["access"]
292
291
  self.set_token_exp()
293
292
  expired = False
294
293
 
@@ -335,8 +334,8 @@ class SparclClient: # was SparclApi()
335
334
  try:
336
335
  res.raise_for_status()
337
336
  #!print(f"DBG: {res.content=}")
338
- self.token = res.json()['access']
339
- self.renew_token = res.json()['refresh']
337
+ self.token = res.json()["access"]
338
+ self.renew_token = res.json()["refresh"]
340
339
  self.session.auth = (email, password)
341
340
  except Exception:
342
341
  self.session.auth = None
@@ -344,8 +343,8 @@ class SparclClient: # was SparclApi()
344
343
  self.renew_token = None
345
344
  self.token_exp = None
346
345
  msg = (
347
- "Could not login with given credentials."
348
- ' Reverted to "Anonymous" user.'
346
+ 'Could not login with given credentials. '
347
+ 'Reverted to "Anonymous" user.'
349
348
  )
350
349
  return msg
351
350
 
@@ -356,10 +355,12 @@ class SparclClient: # was SparclApi()
356
355
  def set_token_exp(self):
357
356
  decoded = jwt.decode(
358
357
  self.token,
359
- algorithms=['HS256',],
360
- options={'verify_signature': False}
358
+ algorithms=[
359
+ "HS256",
360
+ ],
361
+ options={"verify_signature": False},
361
362
  )
362
- self.token_exp = datetime.datetime.fromtimestamp(decoded['exp'])
363
+ self.token_exp = datetime.datetime.fromtimestamp(decoded["exp"])
363
364
 
364
365
  def logout(self):
365
366
  """Logout of the SPARCL service.
@@ -411,10 +412,10 @@ class SparclClient: # was SparclApi()
411
412
  parameter of client.retrieve().
412
413
 
413
414
  Args:
414
- dataset_list (:obj:`list`, optional): List of data sets from
415
- which to get the default fields. Defaults to None, which
416
- will return the intersection of default fields in all
417
- 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.
418
419
 
419
420
  Returns:
420
421
  List of fields tagged as 'default' from DATASET_LIST.
@@ -428,9 +429,9 @@ class SparclClient: # was SparclApi()
428
429
  if dataset_list is None:
429
430
  dataset_list = self.fields.all_drs
430
431
 
431
- assert isinstance(
432
- dataset_list, (list, set)
433
- ), 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
+ )
434
435
 
435
436
  common = set(self.fields.common(dataset_list))
436
437
  union = self.fields.default_retrieve_fields(dataset_list=dataset_list)
@@ -442,10 +443,10 @@ class SparclClient: # was SparclApi()
442
443
  of client.retrieve().
443
444
 
444
445
  Args:
445
- dataset_list (:obj:`list`, optional): List of data sets from
446
- which to get all fields. Defaults to None, which
447
- will return the intersection of all fields in all
448
- 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.
449
450
 
450
451
  Returns:
451
452
  List of fields tagged as 'all' from DATASET_LIST.
@@ -471,16 +472,15 @@ class SparclClient: # was SparclApi()
471
472
  drs = self.fields.all_drs if dataset_list is None else dataset_list
472
473
  msg = (
473
474
  f'Unknown fields "{",".join(unk)}" given '
474
- f'for DataSets {",".join(drs)}. '
475
- f'Allowed fields are: {",".join(all)}. '
475
+ f"for DataSets {','.join(drs)}. "
476
+ f"Allowed fields are: {','.join(all)}. "
476
477
  )
477
478
  raise ex.UnknownField(msg)
478
479
  return True
479
480
 
480
481
  def _common_internal(self, *, science_fields=None, dataset_list=None):
481
- self._validate_science_fields(
482
- science_fields, dataset_list=dataset_list
483
- )
482
+ self._validate_science_fields(science_fields,
483
+ dataset_list=dataset_list)
484
484
 
485
485
  if dataset_list is None:
486
486
  dataset_list = self.fields.all_drs
@@ -500,10 +500,10 @@ class SparclClient: # was SparclApi()
500
500
  client.retreive().
501
501
 
502
502
  Args:
503
- dataset_list (:obj:`list`, optional): List of data sets from
504
- which to get available fields. Defaults to None, which
505
- will return the intersection of all available fields in
506
- 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.
507
507
 
508
508
  Returns:
509
509
  Set of fields available from data sets in DATASET_LIST.
@@ -556,10 +556,10 @@ class SparclClient: # was SparclApi()
556
556
  """Find records in the SPARCL database.
557
557
 
558
558
  Args:
559
- outfields (:obj:`list`, optional): List of fields to return.
560
- Only CORE fields may be passed to this parameter.
561
- Defaults to None, which will return only the sparcl_id
562
- 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.
563
563
 
564
564
  constraints (:obj:`dict`, optional): Key-Value pairs of
565
565
  constraints to place on the record selection. The Key
@@ -604,12 +604,10 @@ class SparclClient: # was SparclApi()
604
604
  #! dataset_list=dataset_list) # DLS-401
605
605
  dr = list(dataset_list)[0]
606
606
  if len(constraints) > 0:
607
- self._validate_science_fields(
608
- constraints.keys(), dataset_list=dataset_list
609
- )
607
+ self._validate_science_fields(constraints.keys(),
608
+ dataset_list=dataset_list)
610
609
  constraints = {
611
- self.fields._internal_name(k, dr): v
612
- for k, v in constraints.items()
610
+ self.fields._internal_name(k, dr): v for k, v in constraints.items() # noqa: E501
613
611
  }
614
612
  uparams = dict(
615
613
  limit=limit,
@@ -635,7 +633,7 @@ class SparclClient: # was SparclApi()
635
633
 
636
634
  if res.status_code != 200:
637
635
  if verbose and ("traceback" in res.json()):
638
- print(f'DBG: Server traceback=\n{res.json()["traceback"]}')
636
+ print(f"DBG: Server traceback=\n{res.json()['traceback']}")
639
637
  raise ex.genSparclException(res, verbose=self.verbose)
640
638
 
641
639
  found = Found(res.json(), client=self)
@@ -650,11 +648,11 @@ class SparclClient: # was SparclApi()
650
648
  NOT stored in the SPARCL database.
651
649
 
652
650
  Args:
653
- uuid_list (:obj:`list`): List of sparcl_ids.
651
+ uuid_list (:obj:`list` of :obj:`str`): List of sparcl_ids.
654
652
 
655
- dataset_list (:obj:`list`, optional): List of data sets from
656
- which to find missing sparcl_ids. Defaults to None, meaning
657
- 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.
658
656
 
659
657
  countOnly (:obj:`bool`, optional): Set to True to return only
660
658
  a count of the missing sparcl_ids from the uuid_list.
@@ -669,16 +667,16 @@ class SparclClient: # was SparclApi()
669
667
 
670
668
  Example:
671
669
  >>> client = SparclClient()
672
- >>> ids = ['ddbb57ee-8e90-4a0d-823b-0f5d97028076',]
673
- >>> client.missing(ids)
670
+ >>> sparcl_ids = ['ddbb57ee-8e90-4a0d-823b-0f5d97028076',]
671
+ >>> client.missing(uuid_list=sparcl_ids)
674
672
  ['ddbb57ee-8e90-4a0d-823b-0f5d97028076']
675
673
  """
676
674
 
677
675
  if dataset_list is None:
678
676
  dataset_list = self.fields.all_drs
679
- assert isinstance(
680
- dataset_list, (list, set)
681
- ), 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
+ )
682
680
 
683
681
  verbose = verbose or self.verbose
684
682
  uparams = dict(dataset_list=",".join(dataset_list))
@@ -705,11 +703,11 @@ class SparclClient: # was SparclApi()
705
703
  NOT stored in the SPARCL database.
706
704
 
707
705
  Args:
708
- specid_list (:obj:`list`): List of specids.
706
+ specid_list (:obj:`list` of :obj:`int`): List of specids.
709
707
 
710
- dataset_list (:obj:`list`, optional): List of data sets from
711
- which to find missing specids. Defaults to None, meaning
712
- 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.
713
711
 
714
712
  countOnly (:obj:`bool`, optional): Set to True to return only
715
713
  a count of the missing specids from the specid_list.
@@ -724,16 +722,15 @@ class SparclClient: # was SparclApi()
724
722
 
725
723
  Example:
726
724
  >>> client = SparclClient()
727
- >>> found = client.find(outfields=['specid'], limit=2)
728
- >>> specids = [f.specid for f in found.records]
729
- >>> client.missing_specids(specids + ['bad_id'])
730
- ['bad_id']
725
+ >>> specids = [398913623742323421, 6181239242670493696]
726
+ >>> client.missing_specids(specid_list=specids)
727
+ [398913623742323421]
731
728
  """
732
729
  if dataset_list is None:
733
730
  dataset_list = self.fields.all_drs
734
- assert isinstance(
735
- dataset_list, (list, set)
736
- ), 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
+ )
737
734
 
738
735
  verbose = verbose or self.verbose
739
736
  uparams = dict(dataset_list=",".join(dataset_list))
@@ -769,13 +766,13 @@ class SparclClient: # was SparclApi()
769
766
  unknown = inc_set.difference(avail_science)
770
767
  if len(unknown) > 0:
771
768
  msg = (
772
- f'The INCLUDE list ({",".join(sorted(include_list))}) '
769
+ f"The INCLUDE list ({','.join(sorted(include_list))}) "
773
770
  f"contains invalid data field names "
774
- f'for Data Sets ({",".join(sorted(dataset_list))}). '
771
+ f"for Data Sets ({','.join(sorted(dataset_list))}). "
775
772
  f"Unknown fields are: "
776
- f'{", ".join(sorted(list(unknown)))}. '
773
+ f"{', '.join(sorted(list(unknown)))}. "
777
774
  f"Available fields are: "
778
- f'{", ".join(sorted(avail_science))}.'
775
+ f"{', '.join(sorted(avail_science))}."
779
776
  )
780
777
  raise ex.BadInclude(msg)
781
778
  return True
@@ -793,15 +790,15 @@ class SparclClient: # was SparclApi()
793
790
  sparcl_ids.
794
791
 
795
792
  Args:
796
- uuid_list (:obj:`list`): List of sparcl_ids.
793
+ uuid_list (:obj:`list` of :obj:`str`): List of sparcl_ids.
797
794
 
798
- include (:obj:`list`, optional): List of field names to include
799
- in each record. Defaults to 'DEFAULT', which will return
800
- 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'.
801
798
 
802
- dataset_list (:obj:`list`, optional): List of data sets from
803
- which to retrieve spectra data. Defaults to None, meaning all
804
- 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.
805
802
 
806
803
  limit (:obj:`int`, optional): Maximum number of records to
807
804
  return. Defaults to 500. Maximum allowed is 24,000.
@@ -840,9 +837,9 @@ class SparclClient: # was SparclApi()
840
837
  orig_dataset_list = dataset_list
841
838
  if dataset_list is None:
842
839
  dataset_list = self.fields.all_drs
843
- assert isinstance(
844
- dataset_list, (list, set)
845
- ), 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
+ )
846
843
 
847
844
  verbose = self.verbose if verbose is None else verbose
848
845
 
@@ -933,7 +930,7 @@ class SparclClient: # was SparclApi()
933
930
  print(f"DBG: Server response=\n{res.text}")
934
931
  # @@@ FAILS on invalid JSON. Maybe not json at all !!!
935
932
  if verbose and ("traceback" in res.json()):
936
- print(f'DBG: Server traceback=\n{res.json()["traceback"]}')
933
+ print(f"DBG: Server traceback=\n{res.json()['traceback']}")
937
934
  raise ex.genSparclException(res, verbose=verbose)
938
935
 
939
936
  if format == "json":
@@ -957,10 +954,10 @@ class SparclClient: # was SparclApi()
957
954
  count = len(results) - 1
958
955
  print(
959
956
  f"Got {count} spectra in "
960
- f"{elapsed:.2f} seconds ({count/elapsed:.0f} "
957
+ f"{elapsed:.2f} seconds ({count / elapsed:.0f} "
961
958
  "spectra/sec)"
962
959
  )
963
- print(f'{meta["status"]}')
960
+ print(f"{meta['status']}")
964
961
 
965
962
  # Format/consolodate the server messages to one message with
966
963
  # the count of missing files
@@ -969,14 +966,14 @@ class SparclClient: # was SparclApi()
969
966
  if verbose:
970
967
  print(f"There are {len(warnings)} warnings")
971
968
  missingcount = 0
972
- missing_message = re.sub(r' [0-9]+ ', ' %s ', warnings[0])
969
+ missing_message = re.sub(r" [0-9]+ ", " %s ", warnings[0])
973
970
  for i in warnings:
974
- 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)
975
972
  if matches:
976
973
  missingcount += int(matches.groups()[0])
977
974
 
978
975
  # using old style substitution to avoid issue with the {} in the message # noqa: E501
979
- warning_message = missing_message % (missingcount, req_num, missingcount) # noqa: E501
976
+ warning_message = missing_message % (missingcount, req_num, missingcount) # noqa: E501
980
977
  warn(warning_message, stacklevel=2)
981
978
 
982
979
  return Retrieved(results, client=self)
@@ -996,15 +993,15 @@ class SparclClient: # was SparclApi()
996
993
  specids.
997
994
 
998
995
  Args:
999
- specid_list (:obj:`list`): List of specids.
996
+ specid_list (:obj:`list` of :obj:`int`): List of specids.
1000
997
 
1001
- include (:obj:`list`, optional): List of field names to include
1002
- in each record. Defaults to 'DEFAULT', which will return
1003
- 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'.
1004
1001
 
1005
- dataset_list (:obj:`list`, optional): List of data sets from
1006
- which to retrieve spectra data. Defaults to None, meaning all
1007
- 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.
1008
1005
 
1009
1006
  limit (:obj:`int`, optional): Maximum number of records to
1010
1007
  return. Defaults to 500. Maximum allowed is 24,000.
@@ -1029,9 +1026,9 @@ class SparclClient: # was SparclApi()
1029
1026
  f'The "specid_list" parameter must be a python list. '
1030
1027
  f"You used a value of type {type(specid_list)}."
1031
1028
  )
1032
- assert (
1033
- len(specid_list) > 0
1034
- ), 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
+ )
1035
1032
  assert isinstance(specid_list[0], int), (
1036
1033
  f'The "specid_list" parameter must be a python list of INTEGERS. '
1037
1034
  f"You used an element value of type {type(specid_list[0])}."
@@ -1039,8 +1036,10 @@ class SparclClient: # was SparclApi()
1039
1036
 
1040
1037
  if dataset_list is None:
1041
1038
  constraints = {"specid": specid_list}
1039
+ dr_list = self.fields.all_drs
1042
1040
  else:
1043
1041
  constraints = {"specid": specid_list, "data_release": dataset_list}
1042
+ dr_list = dataset_list
1044
1043
 
1045
1044
  # Science Field Name for uuid.
1046
1045
  dr = list(self.fields.all_drs)[0]
@@ -1049,6 +1048,16 @@ class SparclClient: # was SparclApi()
1049
1048
  found = self.find([idfld], constraints=constraints, limit=limit)
1050
1049
  if verbose:
1051
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)
1052
1061
  res = self.retrieve(
1053
1062
  found.ids,
1054
1063
  #! svc=svc,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sparclclient
3
- Version: 1.2.6b11
3
+ Version: 1.2.6b13
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
@@ -1,6 +1,6 @@
1
1
  sparcl/Results.py,sha256=vnACjm8sp7MrsJ_5LTuKMuyRWqeBJxOxQM302cHmAlk,9159
2
- sparcl/__init__.py,sha256=G2xAxxMBXc07LFo7lYLNN3P61GqPoCVJwT_38SdjR4E,1125
3
- sparcl/client.py,sha256=7MxNUS9gOWGQ0dnEgjySgKj1OB7h48rkWt4obln5hq8,39136
2
+ sparcl/__init__.py,sha256=nzI5cO-Rr3chwX0dScwd-8pzeEigrpiyu-Vh_psbFic,1125
3
+ sparcl/client.py,sha256=a3uUD19yi_hHAkRtpk-A2gXQ_w1l1LktDFLCrUUAcV0,39876
4
4
  sparcl/conf.py,sha256=GFNDelaiVIAkjNjvFlG7HAlPpU39nqZmTPohQGmOcgI,928
5
5
  sparcl/exceptions.py,sha256=sznmOMGENHvxutSXlRVWqi87bR2Qiebka7LyR3mAII0,4244
6
6
  sparcl/fields.py,sha256=NZUBqDidpbXfeX5F4b306F323xZY2CRIx8eVv-HWTVU,5127
@@ -15,7 +15,7 @@ sparcl/benchmarks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
15
15
  sparcl/benchmarks/benchmarks.py,sha256=OmlSdnAPLmcvGXsr-HzGyfAAcnoqlO0JQ4EIA7JGhZc,9424
16
16
  sparcl/benchmarks/sparcl_benchmarking.ipynb,sha256=gwof2hqM9Qb49qzRX-mky7WNqXZCMSB7ry8bX8dImxc,17559
17
17
  sparcl/notebooks/sparcl-examples.ipynb,sha256=gEwMKI1x7A1YsVeCsQn1QoMO0ZuIhMUAu3qedTiQ7hM,169268
18
- sparclclient-1.2.6b11.dist-info/LICENSE,sha256=y10EluGMCzGs9X4oYCYyix3l6u-lawB_vlGR8qe442Q,1576
19
- sparclclient-1.2.6b11.dist-info/WHEEL,sha256=ssQ84EZ5gH1pCOujd3iW7HClo_O_aDaClUbX4B8bjKY,100
20
- sparclclient-1.2.6b11.dist-info/METADATA,sha256=nQNGT1eb7ntDUJownl9JuMkzlsWkqiNcAJhKappsq_I,681
21
- sparclclient-1.2.6b11.dist-info/RECORD,,
18
+ sparclclient-1.2.6b13.dist-info/LICENSE,sha256=y10EluGMCzGs9X4oYCYyix3l6u-lawB_vlGR8qe442Q,1576
19
+ sparclclient-1.2.6b13.dist-info/WHEEL,sha256=ssQ84EZ5gH1pCOujd3iW7HClo_O_aDaClUbX4B8bjKY,100
20
+ sparclclient-1.2.6b13.dist-info/METADATA,sha256=IGZU4IteE-oPqmbyRJMlWC4Gx9QzHKQK4MeeYDlG8hA,681
21
+ sparclclient-1.2.6b13.dist-info/RECORD,,