sparclclient 1.2.2b10__py2.py3-none-any.whl → 1.2.3b1__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
@@ -31,4 +31,5 @@ __all__ = ["client", "align_records"]
31
31
  # __version__ = "1.2.1b3"
32
32
  # __version__ = "1.2.1"
33
33
  # FIRST uncommented value will be used! (so only leave one uncommented)
34
- __version__ = "1.2.2b10"
34
+ #__version__ = "1.2.2"
35
+ __version__ = "1.2.3b1"
sparcl/client.py CHANGED
@@ -24,6 +24,7 @@ from urllib.parse import urlencode, urlparse
24
24
  from warnings import warn
25
25
  import pickle
26
26
  import getpass
27
+ import datetime
27
28
 
28
29
  #!from pathlib import Path
29
30
  import tempfile
@@ -31,6 +32,7 @@ import tempfile
31
32
  ############################################
32
33
  # External Packages
33
34
  import requests
35
+ import jwt
34
36
 
35
37
  #!from requests.auth import HTTPBasicAuth
36
38
  from requests.auth import AuthBase
@@ -118,12 +120,15 @@ RESERVED = set([DEFAULT, ALL])
118
120
  class TokenAuth(AuthBase):
119
121
  """Attaches HTTP Token Authentication to the given Request object."""
120
122
 
121
- def __init__(self, token):
123
+ def __init__(self, token, renew_check):
122
124
  # setup any auth-related data here
123
125
  self.token = token
126
+ self.renew_check = renew_check # SparcClient Method
124
127
 
125
128
  def __call__(self, request):
126
129
  # modify and return the request
130
+ # check and renew token if needed
131
+ self.renew_check(renew=True)
127
132
  request.headers["Authorization"] = self.token
128
133
  return request
129
134
 
@@ -163,7 +168,7 @@ class SparclClient: # was SparclApi()
163
168
 
164
169
  """
165
170
 
166
- KNOWN_GOOD_API_VERSION = 11.0 # @@@ Change when Server version incremented
171
+ KNOWN_GOOD_API_VERSION = 12.0 # @@@ Change when Server version incremented
167
172
 
168
173
  def __init__(
169
174
  self,
@@ -182,6 +187,8 @@ class SparclClient: # was SparclApi()
182
187
  self.apiurl = f"{self.rooturl}/sparc"
183
188
  self.apiversion = None
184
189
  self.token = None
190
+ self.refresh_token = None
191
+ self.token_exp = None
185
192
  self.verbose = verbose
186
193
  self.show_curl = show_curl # Show CURL equivalent of client method
187
194
  #!self.internal_names = internal_names
@@ -243,6 +250,35 @@ class SparclClient: # was SparclApi()
243
250
  f" read_timeout={self.r_timeout})"
244
251
  )
245
252
 
253
+ def token_expired(self, renew=False):
254
+ """
255
+ POST http://localhost:8050/sparc/renew_token/
256
+ Content-Type: application/json
257
+ {
258
+ "refresh_token": "..."
259
+ }
260
+
261
+ Returns an 'access' token
262
+ """
263
+ now = datetime.datetime.now()
264
+ expired = True
265
+ if self.token_exp is None or self.token_exp <= now:
266
+ expired = True
267
+ else:
268
+ expired = False
269
+
270
+ if expired and renew:
271
+ url = f"{self.apiurl}/renew_token/"
272
+ resp = requests.post(url, json={"refresh_token": self.renew_token})
273
+ resp.raise_for_status()
274
+ data = resp.json()
275
+ #@print(f"{data=}")
276
+ self.token = data['access']
277
+ self.set_token_exp()
278
+ expired = False
279
+
280
+ return expired
281
+
246
282
  def login(self, email, password=None):
247
283
  """Login to the SPARCL service.
248
284
 
@@ -284,20 +320,32 @@ class SparclClient: # was SparclApi()
284
320
  try:
285
321
  res.raise_for_status()
286
322
  #!print(f"DBG: {res.content=}")
287
- self.token = res.json()
323
+ self.token = res.json()['access']
324
+ self.renew_token = res.json()['refresh']
288
325
  self.session.auth = (email, password)
289
326
  except Exception:
290
327
  self.session.auth = None
291
328
  self.token = None
329
+ self.renew_token = None
330
+ self.token_exp = None
292
331
  msg = (
293
332
  "Could not login with given credentials."
294
333
  ' Reverted to "Anonymous" user.'
295
334
  )
296
335
  return msg
297
336
 
337
+ self.set_token_exp()
298
338
  print(f"Logged in successfully with {email=}")
299
339
  return None
300
340
 
341
+ def set_token_exp(self):
342
+ decoded = jwt.decode(
343
+ self.token,
344
+ algorithms=['HS256',],
345
+ options={'verify_signature': False}
346
+ )
347
+ self.token_exp = datetime.datetime.fromtimestamp(decoded['exp'])
348
+
301
349
  def logout(self):
302
350
  """Logout of the SPARCL service.
303
351
 
@@ -317,7 +365,7 @@ class SparclClient: # was SparclApi()
317
365
 
318
366
  @property
319
367
  def authorized(self):
320
- auth = TokenAuth(self.token) if self.token else None
368
+ auth = TokenAuth(self.token, self.token_expired) if self.token else None # noqa: E501
321
369
  response = requests.get(
322
370
  f"{self.apiurl}/auth_status/", auth=auth, timeout=self.timeout
323
371
  )
@@ -468,7 +516,7 @@ class SparclClient: # was SparclApi()
468
516
  Example:
469
517
  >>> client = SparclClient()
470
518
  >>> client.version
471
- 11.0
519
+ 12.0
472
520
  """
473
521
 
474
522
  if self.apiversion is None:
@@ -567,7 +615,7 @@ class SparclClient: # was SparclApi()
567
615
  cmd = ut.curl_find_str(sspec, self.rooturl, qstr=qstr)
568
616
  print(cmd)
569
617
 
570
- auth = TokenAuth(self.token) if self.token else None
618
+ auth = TokenAuth(self.token, self.token_expired) if self.token else None # noqa: E501
571
619
  res = requests.post(url, json=sspec, auth=auth, timeout=self.timeout)
572
620
 
573
621
  if res.status_code != 200:
@@ -833,7 +881,7 @@ class SparclClient: # was SparclApi()
833
881
  print(cmd)
834
882
 
835
883
  try:
836
- auth = TokenAuth(self.token) if self.token else None
884
+ auth = TokenAuth(self.token, self.token_expired) if self.token else None # noqa: E501
837
885
  res = requests.post(url, json=ids, auth=auth, timeout=self.timeout)
838
886
  except requests.exceptions.ConnectTimeout as reCT:
839
887
  raise ex.UnknownSparcl(f"ConnectTimeout: {reCT}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sparclclient
3
- Version: 1.2.2b10
3
+ Version: 1.2.3b1
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=YFh7HmiAfjxQv1y55OHhXsJbpKBh7mn92zPJZ56gJxw,8477
2
- sparcl/__init__.py,sha256=faXU81TTMWX4deehOfYWi9N0SChnm7Kpbw91TuoIJsI,1033
3
- sparcl/client.py,sha256=GJR9eB9LqQ0zYw0ertjh5yh-dIGOP0svNm4R0MdhxfY,36169
2
+ sparcl/__init__.py,sha256=SoVK228J3AOFNJdbvqekR6My_zZar8aXOCF08EiJb4I,1055
3
+ sparcl/client.py,sha256=jQXbJGIxId2azVjzONrR3TiGEb1x1SEk5-sGgd-Bgdw,37772
4
4
  sparcl/conf.py,sha256=GFNDelaiVIAkjNjvFlG7HAlPpU39nqZmTPohQGmOcgI,928
5
5
  sparcl/exceptions.py,sha256=ODtoGCi1HI4xwXBbbLT-gQqd9Jjb_8TmVj-Jz_b1tg4,4040
6
6
  sparcl/fields.py,sha256=NZUBqDidpbXfeX5F4b306F323xZY2CRIx8eVv-HWTVU,5127
@@ -13,7 +13,7 @@ sparcl/utils.py,sha256=pDAk9roe7ezfVohnKcLMxFjjXHkp7EQLbgVNe5sSTrk,6259
13
13
  sparcl/benchmarks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  sparcl/benchmarks/benchmarks.py,sha256=OmlSdnAPLmcvGXsr-HzGyfAAcnoqlO0JQ4EIA7JGhZc,9424
15
15
  sparcl/notebooks/sparcl-examples.ipynb,sha256=gEwMKI1x7A1YsVeCsQn1QoMO0ZuIhMUAu3qedTiQ7hM,169268
16
- sparclclient-1.2.2b10.dist-info/LICENSE,sha256=y10EluGMCzGs9X4oYCYyix3l6u-lawB_vlGR8qe442Q,1576
17
- sparclclient-1.2.2b10.dist-info/WHEEL,sha256=Sgu64hAMa6g5FdzHxXv9Xdse9yxpGGMeagVtPMWpJQY,99
18
- sparclclient-1.2.2b10.dist-info/METADATA,sha256=0LHoWuKG9Y-AimI-BI-tz7FZ_9PpUN-jHirsbCiBHbk,567
19
- sparclclient-1.2.2b10.dist-info/RECORD,,
16
+ sparclclient-1.2.3b1.dist-info/LICENSE,sha256=y10EluGMCzGs9X4oYCYyix3l6u-lawB_vlGR8qe442Q,1576
17
+ sparclclient-1.2.3b1.dist-info/WHEEL,sha256=Sgu64hAMa6g5FdzHxXv9Xdse9yxpGGMeagVtPMWpJQY,99
18
+ sparclclient-1.2.3b1.dist-info/METADATA,sha256=AXPIvQVuOmLK5FDdXkr-cLFZUMtUc-uuJIkCFzdXMBY,566
19
+ sparclclient-1.2.3b1.dist-info/RECORD,,