30
30
import os
31
31
import netrc
32
32
import requests
33
- import numpy
34
33
import json
35
34
import struct
36
35
import ctypes
36
+ import time
37
37
import logging
38
38
from datetime import datetime , timedelta
39
39
49
49
50
50
ps_refresh_token = None
51
51
ps_access_token = None
52
+ ps_token_exp = None
52
53
53
54
verbose = False
54
55
82
83
}
83
84
84
85
basictypes = {
85
- "INT8" : { "fmt" : 'b' , "size" : 1 , "nptype" : numpy . int8 },
86
- "INT16" : { "fmt" : 'h' , "size" : 2 , "nptype" : numpy . int16 },
87
- "INT32" : { "fmt" : 'i' , "size" : 4 , "nptype" : numpy . int32 },
88
- "INT64" : { "fmt" : 'q' , "size" : 8 , "nptype" : numpy . int64 },
89
- "UINT8" : { "fmt" : 'B' , "size" : 1 , "nptype" : numpy . uint8 },
90
- "UINT16" : { "fmt" : 'H' , "size" : 2 , "nptype" : numpy . uint16 },
91
- "UINT32" : { "fmt" : 'I' , "size" : 4 , "nptype" : numpy . uint32 },
92
- "UINT64" : { "fmt" : 'Q' , "size" : 8 , "nptype" : numpy . uint64 },
93
- "BITFIELD" : { "fmt" : 'x' , "size" : 0 , "nptype" : numpy . byte }, # unsupported
94
- "FLOAT" : { "fmt" : 'f' , "size" : 4 , "nptype" : numpy . single },
95
- "DOUBLE" : { "fmt" : 'd' , "size" : 8 , "nptype" : numpy . double },
96
- "TIME8" : { "fmt" : 'Q' , "size" : 8 , "nptype" : numpy . byte },
97
- "STRING" : { "fmt" : 's' , "size" : 1 , "nptype" : numpy . byte }
86
+ "INT8" : { "fmt" : 'b' , "size" : 1 },
87
+ "INT16" : { "fmt" : 'h' , "size" : 2 },
88
+ "INT32" : { "fmt" : 'i' , "size" : 4 },
89
+ "INT64" : { "fmt" : 'q' , "size" : 8 },
90
+ "UINT8" : { "fmt" : 'B' , "size" : 1 },
91
+ "UINT16" : { "fmt" : 'H' , "size" : 2 },
92
+ "UINT32" : { "fmt" : 'I' , "size" : 4 },
93
+ "UINT64" : { "fmt" : 'Q' , "size" : 8 },
94
+ "BITFIELD" : { "fmt" : 'x' , "size" : 0 }, # unsupported
95
+ "FLOAT" : { "fmt" : 'f' , "size" : 4 },
96
+ "DOUBLE" : { "fmt" : 'd' , "size" : 8 },
97
+ "TIME8" : { "fmt" : 'Q' , "size" : 8 },
98
+ "STRING" : { "fmt" : 's' , "size" : 1 }
98
99
}
99
100
100
101
codedtype2str = {
@@ -342,7 +343,7 @@ def __exceptrec(rec):
342
343
#
343
344
# SOURCE
344
345
#
345
- def source (api , parm = {}, stream = False , callbacks = {}):
346
+ def source (api , parm = {}, stream = False , callbacks = {}, path = "/source" ):
346
347
'''
347
348
Perform API call to SlideRule service
348
349
@@ -354,10 +355,10 @@ def source (api, parm={}, stream=False, callbacks={}):
354
355
dictionary of request parameters
355
356
stream: bool
356
357
whether the request is a **normal** service or a **stream** service (see `De-serialization <./SlideRule.html#de-serialization>`_ for more details)
357
- format: str
358
- format of the data being returned in the response: native, json
359
358
callbacks: dict
360
359
record type callbacks (advanced use)
360
+ path: str
361
+ path to api being requested
361
362
362
363
Returns
363
364
-------
@@ -377,22 +378,32 @@ def source (api, parm={}, stream=False, callbacks={}):
377
378
>>> print(rsps)
378
379
{'time': 1300556199523.0, 'format': 'GPS'}
379
380
'''
380
- global service_url , service_org
381
+ global service_url , service_org , ps_access_token , ps_refresh_token , ps_token_exp
381
382
rqst = json .dumps (parm )
382
383
rsps = {}
383
384
headers = None
384
- # Build callbacks
385
+ # Build Callbacks
385
386
for c in __callbacks :
386
387
if c not in callbacks :
387
388
callbacks [c ] = __callbacks [c ]
388
- # Construct Request URL and Authorization #
389
+ # Construct Request URL and Authorization
389
390
if service_org :
390
- url = 'https://%s.%s/source/ %s' % (service_org , service_url , api )
391
+ url = 'https://%s.%s%s/ %s' % (service_org , service_url , path , api )
391
392
if ps_access_token :
393
+ # Check if Refresh Needed
394
+ if time .time () > ps_token_exp :
395
+ refresh_host = "https://ps." + url + "/api/org_token/refresh/"
396
+ refresh_rqst = {"refresh" : ps_refresh_token }
397
+ refresh_headers = {'Content-Type' : 'application/json' , 'Authorization' : 'Bearer ' + ps_access_token }
398
+ refresh_rsps = requests .post (refresh_host , data = json .dumps (refresh_rqst ), headers = refresh_headers , timeout = (60 ,10 )).json ()
399
+ ps_refresh_token = refresh_rsps ["refresh" ]
400
+ ps_access_token = refresh_rsps ["access" ]
401
+ ps_token_exp = time .time () + (refresh_rsps ["access_lifetime" ] / 2 )
402
+ # Build Authentication Header
392
403
headers = {'Authorization' : 'Bearer ' + ps_access_token }
393
404
else :
394
- url = 'http://%s/source/ %s' % (service_url , api )
395
- # Attempt Request #
405
+ url = 'http://%s%s/ %s' % (service_url , path , api )
406
+ # Attempt Request
396
407
try :
397
408
# Perform Request
398
409
if not stream :
@@ -404,6 +415,8 @@ def source (api, parm={}, stream=False, callbacks={}):
404
415
format = data .headers ['Content-Type' ]
405
416
if format == 'text/plain' :
406
417
rsps = __parse_json (data )
418
+ elif format == 'application/json' :
419
+ rsps = __parse_json (data )
407
420
elif format == 'application/octet-stream' :
408
421
rsps = __parse_native (data , callbacks )
409
422
else :
@@ -534,8 +547,10 @@ def update_available_servers (desired_nodes=None):
534
547
>>> import sliderule
535
548
>>> num_servers, max_workers = sliderule.update_available_servers(10)
536
549
'''
537
- # placeholder until functionality implemented
538
- return 7 ,7
550
+
551
+ rsps = source ("status" , parm = {"service" :"sliderule" }, path = "/discovery" )
552
+ available_servers = rsps ["nodes" ]
553
+ return available_servers , available_servers
539
554
540
555
#
541
556
# AUTHENTICATE
@@ -569,7 +584,7 @@ def authenticate (ps_organization, ps_username=None, ps_password=None):
569
584
>>> sliderule.authenticate("myorg")
570
585
True
571
586
'''
572
- global service_org , ps_refresh_token , ps_access_token
587
+ global service_org , ps_refresh_token , ps_access_token , ps_token_exp
573
588
login_status = False
574
589
ps_url = "ps." + service_url
575
590
@@ -604,6 +619,7 @@ def authenticate (ps_organization, ps_username=None, ps_password=None):
604
619
rsps = requests .post (api , data = json .dumps (rqst ), headers = headers , timeout = request_timeout ).json ()
605
620
ps_refresh_token = rsps ["refresh" ]
606
621
ps_access_token = rsps ["access" ]
622
+ ps_token_exp = time .time () + (rsps ["access_lifetime" ] / 2 )
607
623
login_status = True
608
624
except :
609
625
logger .error ("Unable to authenticate user %s to %s" % (ps_username , api ))
0 commit comments