sparclclient 1.2.1.dev7__py2.py3-none-any.whl → 1.2.2__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/Results.py +11 -2
- sparcl/__init__.py +4 -11
- sparcl/client.py +162 -32
- sparcl/exceptions.py +10 -2
- sparcl/fields.py +1 -0
- sparcl/gather_2d.py +2 -1
- sparcl/notebooks/sparcl-examples.ipynb +1321 -789
- sparcl/utils.py +13 -0
- {sparclclient-1.2.1.dev7.dist-info → sparclclient-1.2.2.dist-info}/METADATA +2 -2
- sparclclient-1.2.2.dist-info/RECORD +19 -0
- sparclclient-1.2.1.dev7.dist-info/RECORD +0 -19
- {sparclclient-1.2.1.dev7.dist-info → sparclclient-1.2.2.dist-info}/LICENSE +0 -0
- {sparclclient-1.2.1.dev7.dist-info → sparclclient-1.2.2.dist-info}/WHEEL +0 -0
sparcl/Results.py
CHANGED
|
@@ -21,6 +21,15 @@ class Results(UserList):
|
|
|
21
21
|
self.fields = client.fields
|
|
22
22
|
self.to_science_fields()
|
|
23
23
|
|
|
24
|
+
# HACK 12/14/2023 -sp- to fix UUID problem presumably
|
|
25
|
+
# produced on stack version upgrade (to Django 4.2, postgres 13+)
|
|
26
|
+
# Done per AB for expediency since real solution will be easier
|
|
27
|
+
# after field-renaming is removed.
|
|
28
|
+
for rec in self.recs:
|
|
29
|
+
if "sparcl_id" in rec:
|
|
30
|
+
rec["sparcl_id"] = str(rec["sparcl_id"])
|
|
31
|
+
# END __init__()
|
|
32
|
+
|
|
24
33
|
# https://docs.python.org/3/library/collections.html#collections.deque.clear
|
|
25
34
|
def clear(self):
|
|
26
35
|
"""Delete the contents of this collection."""
|
|
@@ -132,9 +141,9 @@ class Results(UserList):
|
|
|
132
141
|
# Transform science fields to internal fields
|
|
133
142
|
new_recs = self.science_to_internal_fields()
|
|
134
143
|
# Get the ids or specids from retrieved records
|
|
135
|
-
if type(ids_og[0])
|
|
144
|
+
if type(ids_og[0]) is str:
|
|
136
145
|
ids_re = [f["sparcl_id"] for f in new_recs]
|
|
137
|
-
elif type(ids_og[0])
|
|
146
|
+
elif type(ids_og[0]) is int:
|
|
138
147
|
ids_re = [f["specid"] for f in new_recs]
|
|
139
148
|
# Enumerate the original ids
|
|
140
149
|
dict_og = {x: i for i, x in enumerate(ids_og)}
|
sparcl/__init__.py
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
A client for getting spectra and meta-data from NOIRLab.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
# List of packages to import when "from sparcl import *" is used
|
|
7
6
|
__all__ = ["client", "align_records"]
|
|
8
7
|
|
|
@@ -26,16 +25,10 @@ __all__ = ["client", "align_records"]
|
|
|
26
25
|
|
|
27
26
|
# must mach: [N!]N(.N)*[{a|b|rc}N][.postN][.devN]
|
|
28
27
|
# Example of a correct version string: '0.4.0a3.dev35'
|
|
29
|
-
# __version__ = '0.4.0b1.dev8'
|
|
30
|
-
# __version__ = '0.4.0b1.dev10'
|
|
31
|
-
# __version__ = '1.0.0'
|
|
32
|
-
# __version__ = '1.0.0b1.dev7'
|
|
33
|
-
# __version__ = '1.0.0b1.dev8'
|
|
34
|
-
# __version__ = '1.0.0b1.dev9'
|
|
35
|
-
# __version__ = '1.0.1b2.dev1'
|
|
36
|
-
# __version__ = '1.1rc1'
|
|
37
|
-
# __version__ = '1.1rc2'
|
|
38
28
|
# __version__ = '1.1'
|
|
39
29
|
# __version__ = '1.2.0b4'
|
|
40
30
|
# __version__ = '1.2.0' # Release
|
|
41
|
-
__version__ = "1.2.
|
|
31
|
+
# __version__ = "1.2.1b3"
|
|
32
|
+
# __version__ = "1.2.1"
|
|
33
|
+
# FIRST uncommented value will be used! (so only leave one uncommented)
|
|
34
|
+
__version__ = "1.2.2"
|
sparcl/client.py
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
"""Client module for SPARCL.
|
|
2
2
|
This module interfaces to the SPARC-Server to get spectra data.
|
|
3
3
|
"""
|
|
4
|
+
|
|
4
5
|
# python -m unittest tests.tests_api
|
|
6
|
+
|
|
7
|
+
# ### Run tests against DEV
|
|
8
|
+
# serverurl=http://localhost:8050 python -m unittest tests.tests_api
|
|
9
|
+
#
|
|
10
|
+
# ### Run tests Against PAT Server.
|
|
11
|
+
# export serverurl=https://sparc1.datalab.noirlab.edu/
|
|
12
|
+
# python -m unittest tests.tests_api
|
|
13
|
+
|
|
5
14
|
#
|
|
6
15
|
# Doctest example:
|
|
7
16
|
# cd ~/sandbox/sparclclient
|
|
@@ -14,6 +23,7 @@ This module interfaces to the SPARC-Server to get spectra data.
|
|
|
14
23
|
from urllib.parse import urlencode, urlparse
|
|
15
24
|
from warnings import warn
|
|
16
25
|
import pickle
|
|
26
|
+
import getpass
|
|
17
27
|
|
|
18
28
|
#!from pathlib import Path
|
|
19
29
|
import tempfile
|
|
@@ -22,6 +32,9 @@ import tempfile
|
|
|
22
32
|
# External Packages
|
|
23
33
|
import requests
|
|
24
34
|
|
|
35
|
+
#!from requests.auth import HTTPBasicAuth
|
|
36
|
+
from requests.auth import AuthBase
|
|
37
|
+
|
|
25
38
|
############################################
|
|
26
39
|
# Local Packages
|
|
27
40
|
from sparcl.fields import Fields
|
|
@@ -102,6 +115,19 @@ RESERVED = set([DEFAULT, ALL])
|
|
|
102
115
|
#! return set(lists[0]).intersection(*lists[1:])
|
|
103
116
|
|
|
104
117
|
|
|
118
|
+
class TokenAuth(AuthBase):
|
|
119
|
+
"""Attaches HTTP Token Authentication to the given Request object."""
|
|
120
|
+
|
|
121
|
+
def __init__(self, token):
|
|
122
|
+
# setup any auth-related data here
|
|
123
|
+
self.token = token
|
|
124
|
+
|
|
125
|
+
def __call__(self, request):
|
|
126
|
+
# modify and return the request
|
|
127
|
+
request.headers["Authorization"] = self.token
|
|
128
|
+
return request
|
|
129
|
+
|
|
130
|
+
|
|
105
131
|
###########################
|
|
106
132
|
# ## The Client class
|
|
107
133
|
|
|
@@ -113,7 +139,7 @@ class SparclClient: # was SparclApi()
|
|
|
113
139
|
about the Client and Server that is usefule to Developers.
|
|
114
140
|
|
|
115
141
|
Args:
|
|
116
|
-
url (:obj:`str`, optional): Base URL of
|
|
142
|
+
url (:obj:`str`, optional): Base URL of SPARCL Server. Defaults
|
|
117
143
|
to 'https://astrosparcl.datalab.noirlab.edu'.
|
|
118
144
|
|
|
119
145
|
verbose (:obj:`bool`, optional): Default verbosity is set to
|
|
@@ -137,13 +163,11 @@ class SparclClient: # was SparclApi()
|
|
|
137
163
|
|
|
138
164
|
"""
|
|
139
165
|
|
|
140
|
-
KNOWN_GOOD_API_VERSION =
|
|
166
|
+
KNOWN_GOOD_API_VERSION = 12.0 # @@@ Change when Server version incremented
|
|
141
167
|
|
|
142
168
|
def __init__(
|
|
143
169
|
self,
|
|
144
170
|
*,
|
|
145
|
-
email=None,
|
|
146
|
-
password=None,
|
|
147
171
|
url=_PROD,
|
|
148
172
|
verbose=False,
|
|
149
173
|
show_curl=False,
|
|
@@ -153,11 +177,11 @@ class SparclClient: # was SparclApi()
|
|
|
153
177
|
"""Create client instance."""
|
|
154
178
|
session = requests.Session()
|
|
155
179
|
self.session = session
|
|
156
|
-
|
|
157
|
-
self.session.auth = (email, password) if email and password else None
|
|
180
|
+
self.session.auth = None
|
|
158
181
|
self.rooturl = url.rstrip("/") # eg. "http://localhost:8050"
|
|
159
182
|
self.apiurl = f"{self.rooturl}/sparc"
|
|
160
183
|
self.apiversion = None
|
|
184
|
+
self.token = None
|
|
161
185
|
self.verbose = verbose
|
|
162
186
|
self.show_curl = show_curl # Show CURL equivalent of client method
|
|
163
187
|
#!self.internal_names = internal_names
|
|
@@ -199,7 +223,6 @@ class SparclClient: # was SparclApi()
|
|
|
199
223
|
f"at {self.apiurl}."
|
|
200
224
|
)
|
|
201
225
|
raise Exception(msg)
|
|
202
|
-
# self.session = requests.Session() #@@@
|
|
203
226
|
|
|
204
227
|
self.clientversion = client_version
|
|
205
228
|
self.fields = Fields(self.apiurl)
|
|
@@ -214,11 +237,106 @@ class SparclClient: # was SparclApi()
|
|
|
214
237
|
f"(sparclclient:{self.clientversion},"
|
|
215
238
|
f" api:{self.apiversion},"
|
|
216
239
|
f" {self.apiurl},"
|
|
240
|
+
f" client_hash={ut.githash()},"
|
|
217
241
|
f" verbose={self.verbose},"
|
|
218
242
|
f" connect_timeout={self.c_timeout},"
|
|
219
243
|
f" read_timeout={self.r_timeout})"
|
|
220
244
|
)
|
|
221
245
|
|
|
246
|
+
def login(self, email, password=None):
|
|
247
|
+
"""Login to the SPARCL service.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
email (:obj:`str`): User login email.
|
|
251
|
+
|
|
252
|
+
password (:obj:`str`, optional): User SSO password.
|
|
253
|
+
If not given, the output will prompt the user
|
|
254
|
+
to enter in their SSO password.
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
None.
|
|
258
|
+
|
|
259
|
+
Example:
|
|
260
|
+
>>>
|
|
261
|
+
>> client = SparclClient()
|
|
262
|
+
>> client.login('test_user@noirlab.edu', 'testpw')
|
|
263
|
+
Logged in successfully with email='test_user@noirlab.edu'
|
|
264
|
+
"""
|
|
265
|
+
|
|
266
|
+
if email is None: # "logout"
|
|
267
|
+
old_email = self.session.auth[0] if self.session.auth else None
|
|
268
|
+
self.session.auth = None
|
|
269
|
+
self.token = None
|
|
270
|
+
print(
|
|
271
|
+
f"Logged-out successfully. "
|
|
272
|
+
f" Previously logged-in with email {old_email}."
|
|
273
|
+
)
|
|
274
|
+
return None
|
|
275
|
+
if password is None:
|
|
276
|
+
password = getpass.getpass(prompt="SSO Password: ")
|
|
277
|
+
url = f"{self.apiurl}/get_token/"
|
|
278
|
+
# print(f'login: get_token {url=}')
|
|
279
|
+
res = requests.post(
|
|
280
|
+
url,
|
|
281
|
+
json=dict(email=email, password=password),
|
|
282
|
+
timeout=self.timeout,
|
|
283
|
+
)
|
|
284
|
+
try:
|
|
285
|
+
res.raise_for_status()
|
|
286
|
+
#!print(f"DBG: {res.content=}")
|
|
287
|
+
self.token = res.json()
|
|
288
|
+
self.session.auth = (email, password)
|
|
289
|
+
except Exception:
|
|
290
|
+
self.session.auth = None
|
|
291
|
+
self.token = None
|
|
292
|
+
msg = (
|
|
293
|
+
"Could not login with given credentials."
|
|
294
|
+
' Reverted to "Anonymous" user.'
|
|
295
|
+
)
|
|
296
|
+
return msg
|
|
297
|
+
|
|
298
|
+
print(f"Logged in successfully with {email=}")
|
|
299
|
+
return None
|
|
300
|
+
|
|
301
|
+
def logout(self):
|
|
302
|
+
"""Logout of the SPARCL service.
|
|
303
|
+
|
|
304
|
+
Args:
|
|
305
|
+
None.
|
|
306
|
+
|
|
307
|
+
Returns:
|
|
308
|
+
None.
|
|
309
|
+
|
|
310
|
+
Example:
|
|
311
|
+
>>> client = SparclClient()
|
|
312
|
+
>>> client.logout()
|
|
313
|
+
Logged-out successfully. Previously logged-in with email None.
|
|
314
|
+
"""
|
|
315
|
+
|
|
316
|
+
return self.login(None)
|
|
317
|
+
|
|
318
|
+
@property
|
|
319
|
+
def authorized(self):
|
|
320
|
+
auth = TokenAuth(self.token) if self.token else None
|
|
321
|
+
response = requests.get(
|
|
322
|
+
f"{self.apiurl}/auth_status/", auth=auth, timeout=self.timeout
|
|
323
|
+
)
|
|
324
|
+
auth_status = response.json()
|
|
325
|
+
#! print(f"DBG authorized: {auth_status=}")
|
|
326
|
+
|
|
327
|
+
username = auth_status.get("Loggedin_User")
|
|
328
|
+
#! all_private_drs = set(auth_status.get("All_Private_Datasets"))
|
|
329
|
+
all_public_drs = set(auth_status.get("All_Public_Datasets"))
|
|
330
|
+
auth_drs = set(auth_status.get("Authorized_Private_Datasets"))
|
|
331
|
+
res = dict(
|
|
332
|
+
Loggedin_As=username, # email
|
|
333
|
+
Authorized_Datasets=auth_drs | all_public_drs,
|
|
334
|
+
#! Unauthorized_Datasets=all_private_drs - auth_drs,
|
|
335
|
+
#! All_Private_Datasets=all_private_drs,
|
|
336
|
+
#! All_Datasets=all_drs,
|
|
337
|
+
)
|
|
338
|
+
return res
|
|
339
|
+
|
|
222
340
|
@property
|
|
223
341
|
def all_datasets(self):
|
|
224
342
|
"""Set of all DataSets available from Server"""
|
|
@@ -233,7 +351,7 @@ class SparclClient: # was SparclApi()
|
|
|
233
351
|
dataset_list (:obj:`list`, optional): List of data sets from
|
|
234
352
|
which to get the default fields. Defaults to None, which
|
|
235
353
|
will return the intersection of default fields in all
|
|
236
|
-
data sets hosted on the
|
|
354
|
+
data sets hosted on the SPARCL database.
|
|
237
355
|
|
|
238
356
|
Returns:
|
|
239
357
|
List of fields tagged as 'default' from DATASET_LIST.
|
|
@@ -264,7 +382,7 @@ class SparclClient: # was SparclApi()
|
|
|
264
382
|
dataset_list (:obj:`list`, optional): List of data sets from
|
|
265
383
|
which to get all fields. Defaults to None, which
|
|
266
384
|
will return the intersection of all fields in all
|
|
267
|
-
data sets hosted on the
|
|
385
|
+
data sets hosted on the SPARCL database.
|
|
268
386
|
|
|
269
387
|
Returns:
|
|
270
388
|
List of fields tagged as 'all' from DATASET_LIST.
|
|
@@ -322,7 +440,7 @@ class SparclClient: # was SparclApi()
|
|
|
322
440
|
dataset_list (:obj:`list`, optional): List of data sets from
|
|
323
441
|
which to get available fields. Defaults to None, which
|
|
324
442
|
will return the intersection of all available fields in
|
|
325
|
-
all data sets hosted on the
|
|
443
|
+
all data sets hosted on the SPARCL database.
|
|
326
444
|
|
|
327
445
|
Returns:
|
|
328
446
|
Set of fields available from data sets in DATASET_LIST.
|
|
@@ -330,7 +448,8 @@ class SparclClient: # was SparclApi()
|
|
|
330
448
|
Example:
|
|
331
449
|
>>> client = SparclClient()
|
|
332
450
|
>>> sorted(client.get_available_fields())
|
|
333
|
-
['data_release', 'datasetgroup', 'dateobs', 'dateobs_center', 'dec', '
|
|
451
|
+
['data_release', 'datasetgroup', 'dateobs', 'dateobs_center', 'dec', 'exptime', 'extra_files', 'file', 'flux', 'instrument', 'ivar', 'mask', 'model', 'ra', 'redshift', 'redshift_err', 'redshift_warning', 'site', 'sparcl_id', 'specid', 'specprimary', 'spectype', 'survey', 'targetid', 'telescope', 'updated', 'wave_sigma', 'wavelength', 'wavemax', 'wavemin']
|
|
452
|
+
|
|
334
453
|
""" # noqa: E501
|
|
335
454
|
|
|
336
455
|
drs = self.fields.all_drs if dataset_list is None else dataset_list
|
|
@@ -349,7 +468,7 @@ class SparclClient: # was SparclApi()
|
|
|
349
468
|
Example:
|
|
350
469
|
>>> client = SparclClient()
|
|
351
470
|
>>> client.version
|
|
352
|
-
|
|
471
|
+
12.0
|
|
353
472
|
"""
|
|
354
473
|
|
|
355
474
|
if self.apiversion is None:
|
|
@@ -364,12 +483,14 @@ class SparclClient: # was SparclApi()
|
|
|
364
483
|
outfields=None,
|
|
365
484
|
*,
|
|
366
485
|
constraints={}, # dict(fname) = [op, param, ...]
|
|
367
|
-
|
|
486
|
+
#! exclude_unauth = True, # Not implemented yet
|
|
368
487
|
limit=500,
|
|
369
488
|
sort=None,
|
|
489
|
+
# count=False,
|
|
490
|
+
# dataset_list=None,
|
|
370
491
|
verbose=None,
|
|
371
492
|
):
|
|
372
|
-
"""Find records in the
|
|
493
|
+
"""Find records in the SPARCL database.
|
|
373
494
|
|
|
374
495
|
Args:
|
|
375
496
|
outfields (:obj:`list`, optional): List of fields to return.
|
|
@@ -429,6 +550,7 @@ class SparclClient: # was SparclApi()
|
|
|
429
550
|
}
|
|
430
551
|
uparams = dict(
|
|
431
552
|
limit=limit,
|
|
553
|
+
#! count='Y' if count else 'N'
|
|
432
554
|
)
|
|
433
555
|
if sort is not None:
|
|
434
556
|
uparams["sort"] = sort
|
|
@@ -445,7 +567,8 @@ class SparclClient: # was SparclApi()
|
|
|
445
567
|
cmd = ut.curl_find_str(sspec, self.rooturl, qstr=qstr)
|
|
446
568
|
print(cmd)
|
|
447
569
|
|
|
448
|
-
|
|
570
|
+
auth = TokenAuth(self.token) if self.token else None
|
|
571
|
+
res = requests.post(url, json=sspec, auth=auth, timeout=self.timeout)
|
|
449
572
|
|
|
450
573
|
if res.status_code != 200:
|
|
451
574
|
if verbose and ("traceback" in res.json()):
|
|
@@ -461,14 +584,14 @@ class SparclClient: # was SparclApi()
|
|
|
461
584
|
self, uuid_list, *, dataset_list=None, countOnly=False, verbose=False
|
|
462
585
|
):
|
|
463
586
|
"""Return the subset of sparcl_ids in the given uuid_list that are
|
|
464
|
-
NOT stored in the
|
|
587
|
+
NOT stored in the SPARCL database.
|
|
465
588
|
|
|
466
589
|
Args:
|
|
467
590
|
uuid_list (:obj:`list`): List of sparcl_ids.
|
|
468
591
|
|
|
469
592
|
dataset_list (:obj:`list`, optional): List of data sets from
|
|
470
593
|
which to find missing sparcl_ids. Defaults to None, meaning
|
|
471
|
-
all data sets hosted on the
|
|
594
|
+
all data sets hosted on the SPARCL database.
|
|
472
595
|
|
|
473
596
|
countOnly (:obj:`bool`, optional): Set to True to return only
|
|
474
597
|
a count of the missing sparcl_ids from the uuid_list.
|
|
@@ -479,7 +602,7 @@ class SparclClient: # was SparclApi()
|
|
|
479
602
|
|
|
480
603
|
Returns:
|
|
481
604
|
A list of the subset of sparcl_ids in the given uuid_list that
|
|
482
|
-
are NOT stored in the
|
|
605
|
+
are NOT stored in the SPARCL database.
|
|
483
606
|
|
|
484
607
|
Example:
|
|
485
608
|
>>> client = SparclClient()
|
|
@@ -514,14 +637,14 @@ class SparclClient: # was SparclApi()
|
|
|
514
637
|
self, specid_list, *, dataset_list=None, countOnly=False, verbose=False
|
|
515
638
|
):
|
|
516
639
|
"""Return the subset of specids in the given specid_list that are
|
|
517
|
-
NOT stored in the
|
|
640
|
+
NOT stored in the SPARCL database.
|
|
518
641
|
|
|
519
642
|
Args:
|
|
520
643
|
specid_list (:obj:`list`): List of specids.
|
|
521
644
|
|
|
522
645
|
dataset_list (:obj:`list`, optional): List of data sets from
|
|
523
646
|
which to find missing specids. Defaults to None, meaning
|
|
524
|
-
all data sets hosted on the
|
|
647
|
+
all data sets hosted on the SPARCL database.
|
|
525
648
|
|
|
526
649
|
countOnly (:obj:`bool`, optional): Set to True to return only
|
|
527
650
|
a count of the missing specids from the specid_list.
|
|
@@ -532,11 +655,12 @@ class SparclClient: # was SparclApi()
|
|
|
532
655
|
|
|
533
656
|
Returns:
|
|
534
657
|
A list of the subset of specids in the given specid_list that
|
|
535
|
-
are NOT stored in the
|
|
658
|
+
are NOT stored in the SPARCL database.
|
|
536
659
|
|
|
537
660
|
Example:
|
|
538
|
-
>>> client = SparclClient(
|
|
539
|
-
>>>
|
|
661
|
+
>>> client = SparclClient()
|
|
662
|
+
>>> found = client.find(outfields=['specid'], limit=2)
|
|
663
|
+
>>> specids = [f.specid for f in found.records]
|
|
540
664
|
>>> client.missing_specids(specids + ['bad_id'])
|
|
541
665
|
['bad_id']
|
|
542
666
|
"""
|
|
@@ -598,7 +722,7 @@ class SparclClient: # was SparclApi()
|
|
|
598
722
|
limit=500,
|
|
599
723
|
verbose=None,
|
|
600
724
|
):
|
|
601
|
-
"""Retrieve spectra records from the
|
|
725
|
+
"""Retrieve spectra records from the SPARCL database by list of
|
|
602
726
|
sparcl_ids.
|
|
603
727
|
|
|
604
728
|
Args:
|
|
@@ -610,7 +734,7 @@ class SparclClient: # was SparclApi()
|
|
|
610
734
|
|
|
611
735
|
dataset_list (:obj:`list`, optional): List of data sets from
|
|
612
736
|
which to retrieve spectra data. Defaults to None, meaning all
|
|
613
|
-
data sets hosted on the
|
|
737
|
+
data sets hosted on the SPARCL database.
|
|
614
738
|
|
|
615
739
|
limit (:obj:`int`, optional): Maximum number of records to
|
|
616
740
|
return. Defaults to 500. Maximum allowed is 24,000.
|
|
@@ -623,7 +747,7 @@ class SparclClient: # was SparclApi()
|
|
|
623
747
|
|
|
624
748
|
Example:
|
|
625
749
|
>>> client = SparclClient()
|
|
626
|
-
>>> ids =
|
|
750
|
+
>>> ids = client.find(limit=1).ids
|
|
627
751
|
>>> inc = ['sparcl_id', 'flux', 'wavelength', 'model']
|
|
628
752
|
>>> ret = client.retrieve(uuid_list=ids, include=inc)
|
|
629
753
|
>>> type(ret.records[0].wavelength)
|
|
@@ -646,6 +770,7 @@ class SparclClient: # was SparclApi()
|
|
|
646
770
|
format = "pkl" # 'json',
|
|
647
771
|
chunk = 500
|
|
648
772
|
|
|
773
|
+
orig_dataset_list = dataset_list
|
|
649
774
|
if dataset_list is None:
|
|
650
775
|
dataset_list = self.fields.all_drs
|
|
651
776
|
assert isinstance(
|
|
@@ -687,8 +812,13 @@ class SparclClient: # was SparclApi()
|
|
|
687
812
|
#! "chunk_len": chunk,
|
|
688
813
|
"format": format,
|
|
689
814
|
#! "1thread": "yes", # @@@ 7.3.2023
|
|
690
|
-
"dataset_list": ",".join(dataset_list),
|
|
815
|
+
#!"dataset_list": ",".join(dataset_list),
|
|
691
816
|
}
|
|
817
|
+
# Do not put dataset_list in server call if it wasn't in client call.
|
|
818
|
+
# Else will interfer with defaulting behavior of AUTH (DLS-504).
|
|
819
|
+
if orig_dataset_list is not None:
|
|
820
|
+
uparams["dataset_list"] = ",".join(dataset_list)
|
|
821
|
+
|
|
692
822
|
qstr = urlencode(uparams)
|
|
693
823
|
|
|
694
824
|
#!url = f'{self.apiurl}/retrieve/?{qstr}'
|
|
@@ -703,9 +833,8 @@ class SparclClient: # was SparclApi()
|
|
|
703
833
|
print(cmd)
|
|
704
834
|
|
|
705
835
|
try:
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
)
|
|
836
|
+
auth = TokenAuth(self.token) if self.token else None
|
|
837
|
+
res = requests.post(url, json=ids, auth=auth, timeout=self.timeout)
|
|
709
838
|
except requests.exceptions.ConnectTimeout as reCT:
|
|
710
839
|
raise ex.UnknownSparcl(f"ConnectTimeout: {reCT}")
|
|
711
840
|
except requests.exceptions.ReadTimeout as reRT:
|
|
@@ -782,7 +911,8 @@ class SparclClient: # was SparclApi()
|
|
|
782
911
|
limit=500,
|
|
783
912
|
verbose=False,
|
|
784
913
|
):
|
|
785
|
-
"""Retrieve spectra records from the
|
|
914
|
+
"""Retrieve spectra records from the SPARCL database by list of
|
|
915
|
+
specids.
|
|
786
916
|
|
|
787
917
|
Args:
|
|
788
918
|
specid_list (:obj:`list`): List of specids.
|
|
@@ -793,7 +923,7 @@ class SparclClient: # was SparclApi()
|
|
|
793
923
|
|
|
794
924
|
dataset_list (:obj:`list`, optional): List of data sets from
|
|
795
925
|
which to retrieve spectra data. Defaults to None, meaning all
|
|
796
|
-
data sets hosted on the
|
|
926
|
+
data sets hosted on the SPARCL database.
|
|
797
927
|
|
|
798
928
|
limit (:obj:`int`, optional): Maximum number of records to
|
|
799
929
|
return. Defaults to 500. Maximum allowed is 24,000.
|
sparcl/exceptions.py
CHANGED
|
@@ -21,9 +21,13 @@ def genSparclException(response, verbose=False):
|
|
|
21
21
|
return UnknownField(status.get("errorMessage"))
|
|
22
22
|
elif status.get("errorCode") == "BADCONST":
|
|
23
23
|
return BadSearchConstraint(status.get("errorMessage"))
|
|
24
|
+
elif status.get("errorCode") == "NODRACCESS":
|
|
25
|
+
return AccessNotAllowed(status.get("errorMessage"))
|
|
24
26
|
else:
|
|
25
27
|
return UnknownServerError(
|
|
26
|
-
f"{status.get('errorMessage')} "
|
|
28
|
+
f"{status.get('errorMessage')} "
|
|
29
|
+
f"[{status.get('errorCode')}] "
|
|
30
|
+
f"{status.get('traceback')}"
|
|
27
31
|
)
|
|
28
32
|
|
|
29
33
|
|
|
@@ -32,7 +36,7 @@ class BaseSparclException(Exception):
|
|
|
32
36
|
|
|
33
37
|
error_code = "UNKNOWN"
|
|
34
38
|
error_message = "<NA>"
|
|
35
|
-
traceback =
|
|
39
|
+
traceback = True
|
|
36
40
|
|
|
37
41
|
def get_subclass_name(self):
|
|
38
42
|
return self.__class__.__name__
|
|
@@ -138,4 +142,8 @@ class NoIDs(BaseSparclException):
|
|
|
138
142
|
error_code = "NOIDS"
|
|
139
143
|
|
|
140
144
|
|
|
145
|
+
class AccessNotAllowed(BaseSparclException):
|
|
146
|
+
error_code = "DSDENIED"
|
|
147
|
+
|
|
148
|
+
|
|
141
149
|
# error_code values should be no bigger than 8 characters 12345678
|
sparcl/fields.py
CHANGED
sparcl/gather_2d.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Align or resample spectra related fields across multiple records."""
|
|
2
|
+
|
|
2
3
|
# See client.py for Doctest example
|
|
3
4
|
#
|
|
4
5
|
# For info about problems with floating point,
|
|
@@ -194,7 +195,7 @@ def align_records(records, fields=["flux", "wavelength"], precision=7):
|
|
|
194
195
|
>>> got = client.retrieve(found.ids, include=specflds)
|
|
195
196
|
>>> ar_dict, grid = align_records(got.records, fields=specflds)
|
|
196
197
|
>>> ar_dict['model'].shape
|
|
197
|
-
(21,
|
|
198
|
+
(21, 4669)
|
|
198
199
|
|
|
199
200
|
"""
|
|
200
201
|
# Report Garbage In
|