@@ -133,9 +133,15 @@ class RsConnectApi:
133133 api_key : "str | None"
134134 server_url : "str"
135135
136- def __init__ (self , server_url , api_key = None ):
136+ def __init__ (
137+ self ,
138+ server_url : "str | None" ,
139+ api_key : "str | None" = None ,
140+ session : "requests.Session | None" = None ,
141+ ):
137142 self .server_url = server_url
138143 self .api_key = api_key
144+ self .session = requests .Session () if session is None else session
139145
140146 # utility functions -------------------------------------------------------
141147
@@ -165,10 +171,16 @@ def _get_api_key(self):
165171 if self .api_key is not None :
166172 return self .api_key
167173
168- return os .environ [ RSC_API_KEY ]
174+ return os .environ . get ( RSC_API_KEY )
169175
170176 def _get_headers (self ):
171- return {"Authorization" : f"key { self ._get_api_key ()} " }
177+ api_key = self ._get_api_key ()
178+ rsc_xsrf = self .session .cookies .get ("RSC-XSRF" )
179+
180+ d_key = {"Authorization" : f"key { api_key } " } if api_key is not None else {}
181+ d_rsc = {"X-RSC-XSRF" : rsc_xsrf } if rsc_xsrf is not None else {}
182+
183+ return {** d_key , ** d_rsc }
172184
173185 def _validate_json_response (self , data : "dict | list" ):
174186 if isinstance (data , list ):
@@ -209,7 +221,7 @@ def _raw_query(self, url, method="GET", return_request=False, **kwargs):
209221
210222 headers = self ._get_headers ()
211223
212- r = requests .request (method , url , headers = headers , ** kwargs )
224+ r = self . session .request (method , url , headers = headers , ** kwargs )
213225
214226 if return_request :
215227 return r
@@ -418,46 +430,28 @@ def misc_get_applications(
418430
419431
420432# ported from github.com/rstudio/connectapi
433+ # TODO: could just move these methods into RsConnectApi?
421434class _HackyConnect (RsConnectApi ):
422435 """Handles logging in to connect, rather than using an API key.
423436
424437 This class allows you to create users and generate API keys on a fresh
425438 RStudio Connect service.
426439 """
427440
428- xsrf : "None | str"
429-
430- def __init__ (self , * args , ** kwargs ):
431- self .xsrf = None
432- super ().__init__ (* args , ** kwargs )
433-
434- def _get_headers (self ):
435- return {"X-RSC-XSRF" : self .xsrf }
436-
437441 def login (self , user , password ):
438442 res = self .query (
439443 "__login__" ,
440444 "POST" ,
441445 return_request = True ,
442446 json = {"username" : user , "password" : password },
443447 )
444- self .xsrf = res .cookies ["RSC-XSRF" ]
445448 return res
446449
447450 def create_first_admin (self , user , password , email , keyname = "first-key" ):
448- # TODO(question): this is run in the R rsconnect, but it returns json
449- # error codes. tests run okay without it...
450- # self.query_v1(
451- # "users", "POST", json=dict(username=user, password=password, email=email)
452- #
453- # )
451+ self .login (user , password )
454452
455- res = self .login ( user , password )
453+ self .query ( "me" )
456454
457- self .query ("me" , cookies = res .cookies )
458-
459- api_key = self .query (
460- "keys" , "POST" , json = dict (name = keyname ), cookies = res .cookies
461- )
455+ api_key = self .query ("keys" , "POST" , json = dict (name = keyname ))
462456
463457 return RsConnectApi (self .server_url , api_key = api_key ["key" ])
0 commit comments