@@ -127,27 +127,35 @@ def close(self, save: str = None) -> None:
127127 def has_connections (self ) -> bool :
128128 """
129129 Check if some connections were opened.
130+
131+ :return: True if some connections were opened, False otherwise
130132 """
131133 return len (self .conns ) > 0
132134
133135 def get_connection_names (self ) -> list [str ]:
134136 """
135137 Get the opened connection names.
138+
139+ :return: The list of opened connection names
136140 """
137141 if self .conns :
138142 return [conn .name for conn in self .conns ]
139143 else :
140- return None
144+ return []
141145
142146 def has_errors (self ) -> bool :
143147 """
144148 Check if last command execution has produced errors.
149+
150+ :return: True if last command execution has produced errors, False otherwise
145151 """
146152 return len (self .errors ) > 0
147153
148154 def get_errors (self ) -> dict :
149155 """
150156 Get the last command execution errors, per remote server name.
157+
158+ :return: The last command execution errors, per remote server name
151159 """
152160 return self .errors
153161
@@ -158,6 +166,8 @@ def get_errors(self) -> dict:
158166 def tables (self ) -> dict :
159167 """
160168 List available table names from the data repository.
169+
170+ :return: The available table names from the data repository, per remote server name
161171 """
162172 rval = {}
163173 for conn in self .conns :
@@ -167,6 +177,8 @@ def tables(self) -> dict:
167177 def resources (self ) -> dict :
168178 """
169179 List available resource names from the data repository.
180+
181+ :return: The available resource names from the data repository, per remote server name
170182 """
171183 rval = {}
172184 for conn in self .conns :
@@ -176,6 +188,8 @@ def resources(self) -> dict:
176188 def profiles (self ) -> dict :
177189 """
178190 List available DataSHIELD profile names in the data repository.
191+
192+ :return: The available DataSHIELD profile names in the data repository, per remote server name
179193 """
180194 rval = {}
181195 for conn in self .conns :
@@ -185,6 +199,8 @@ def profiles(self) -> dict:
185199 def packages (self ) -> dict :
186200 """
187201 Get the list of DataSHIELD packages with their version, that have been configured on the remote data repository.
202+
203+ :return: The list of DataSHIELD packages with their version, that have been configured on the remote data repository, per remote server name
188204 """
189205 rval = {}
190206 for conn in self .conns :
@@ -196,6 +212,7 @@ def methods(self, type: str = "aggregate") -> dict:
196212 Get the list of DataSHIELD methods that have been configured on the remote data repository.
197213
198214 :param type: The type of method, either "aggregate" (default) or "assign"
215+ :return: The list of DataSHIELD methods that have been configured on the remote data repository, per remote server name
199216 """
200217 rval = {}
201218 for conn in self .conns :
@@ -209,6 +226,8 @@ def methods(self, type: str = "aggregate") -> dict:
209226 def workspaces (self ) -> dict :
210227 """
211228 Get the list of DataSHIELD workspaces, that have been saved on the remote data repository.
229+
230+ :return: The list of DataSHIELD workspaces, that have been saved on the remote data repository, per remote server name
212231 """
213232 rval = {}
214233 for conn in self .conns :
@@ -220,39 +239,66 @@ def workspace_save(self, name: str) -> dict:
220239 Save the DataSHIELD R session in a workspace on the remote data repository.
221240
222241 :param name: The name of the workspace
242+ :return: The list of DataSHIELD workspaces, that have been saved on the remote data repository after saving the workspace, per remote server name
223243 """
224244 for conn in self .conns :
225245 conn .save_workspace (f"{ conn .name } :{ name } " )
246+ return self .workspaces ()
226247
227248 def workspace_restore (self , name : str ) -> dict :
228249 """
229250 Restore a saved DataSHIELD R session from the remote data repository. When restoring a workspace,
230251 any existing symbol or file with same name will be overridden.
231252
232253 :param name: The name of the workspace
254+ :return: The list of DataSHIELD workspaces, that have been saved on the remote data repository after restoring the workspace, per remote server name
233255 """
234256 for conn in self .conns :
235257 conn .restore_workspace (f"{ conn .name } :{ name } " )
258+ return self .workspaces ()
236259
237260 def workspace_rm (self , name : str ) -> dict :
238261 """
239262 Remove a DataSHIELD workspace from the remote data repository. Ignored if no
240263 such workspace exists.
241264
242265 :param name: The name of the workspace
266+ :return: The list of DataSHIELD workspaces, that have been saved on the remote data repository after removing the workspace, per remote server name
243267 """
244268 for conn in self .conns :
245269 conn .rm_workspace (f"{ conn .name } :{ name } " )
270+ return self .workspaces ()
246271
247272 #
248273 # R session
249274 #
250275
276+ def sessions (self ) -> dict :
277+ """
278+ Ensure R sessions are started on the remote servers and get their information.
279+
280+ :return: The R session information, per remote server name
281+ """
282+ rval = {}
283+ for conn in self .conns :
284+ if not conn .has_session ():
285+ conn .start_session (asynchronous = True )
286+ # check for session status and wait until all are complete
287+ while any (conn .get_session ().is_pending () for conn in self .conns ):
288+ time .sleep (0.1 )
289+ for conn in self .conns :
290+ rval [conn .name ] = conn .get_session ()
291+ self ._check_errors ()
292+ return rval
293+
251294 def ls (self ) -> dict :
252295 """
253296 After assignments have been performed, list the symbols that live in the DataSHIELD R session on the server side.
297+
298+ :return: The symbols that live in the DataSHIELD R session on the server side, per remote server name
254299 """
255300 self ._init_errors ()
301+ self .sessions () # ensure sessions are started and available
256302 rval = {}
257303 for conn in self .conns :
258304 try :
@@ -263,11 +309,14 @@ def ls(self) -> dict:
263309 self ._check_errors ()
264310 return rval
265311
266- def rm (self , symbol : str ):
312+ def rm (self , symbol : str ) -> None :
267313 """
268314 Remove a symbol from remote servers.
315+
316+ :param symbol: The name of the symbol to remove
269317 """
270318 self ._init_errors ()
319+ self .sessions () # ensure sessions are started and available
271320 for conn in self .conns :
272321 try :
273322 conn .rm_symbol (symbol )
@@ -295,6 +344,7 @@ def assign_table(
295344 :param asynchronous: Whether the operation is asynchronous (if supported by the DataSHIELD server)
296345 """
297346 self ._init_errors ()
347+ self .sessions () # ensure sessions are started and available
298348 cmd = {}
299349 for conn in self .conns :
300350 name = table
@@ -321,6 +371,7 @@ def assign_resource(
321371 :param asynchronous: Whether the operation is asynchronous (if supported by the DataSHIELD server)
322372 """
323373 self ._init_errors ()
374+ self .sessions () # ensure sessions are started and available
324375 cmd = {}
325376 for conn in self .conns :
326377 name = resource
@@ -344,6 +395,7 @@ def assign_expr(self, symbol: str, expr: str, asynchronous: bool = True) -> None
344395 :param asynchronous: Whether the operation is asynchronous (if supported by the DataSHIELD server)
345396 """
346397 self ._init_errors ()
398+ self .sessions () # ensure sessions are started and available
347399 cmd = {}
348400 for conn in self .conns :
349401 try :
@@ -361,8 +413,10 @@ def aggregate(self, expr: str, asynchronous: bool = True) -> dict:
361413
362414 :param expr: The R expression to evaluate and which result will be returned
363415 :param asynchronous: Whether the operation is asynchronous (if supported by the DataSHIELD server)
416+ :return: The result of the aggregation expression evaluation, per remote server name
364417 """
365418 self ._init_errors ()
419+ self .sessions () # ensure sessions are started and available
366420 cmd = {}
367421 rval = {}
368422 for conn in self .conns :
0 commit comments