1- """This module provides static functions to handle multiple sessions of SAP.
1+ """This module provides static function to handle multiple sessions of SAP.
22Using this module you can spawn multiple sessions and automatically execute
33a function in parallel on the sessions."""
44
55import time
66import threading
7- import math
87from typing import Callable
9-
108import pythoncom
119import win32com .client
1210import win32gui
1311
1412def run_with_session (session_index :int , func :Callable , args :tuple ) -> None :
15- """Run a function in a specific session based on the sessions index.
16- This function is meant to be run inside a separate thread.
13+ """Run a function in a sepcific session based on the sessions index.
14+ This function is meant to be run inside a seperate thread.
1715 The function must take a session object as its first argument.
1816 Note that this function will not spawn the sessions before running,
1917 use spawn_sessions to do that.
2018 """
2119
2220 pythoncom .CoInitialize ()
2321
24- sap = win32com .client .GetObject ("SAPGUI" )
25- app = sap .GetScriptingEngine
22+ SAP = win32com .client .GetObject ("SAPGUI" )
23+ app = SAP .GetScriptingEngine
2624 connection = app .Connections (0 )
2725 session = connection .Sessions (session_index )
2826
2927 func (session , * args )
3028
3129 pythoncom .CoUninitialize ()
3230
33-
3431def run_batch (func :Callable , args :tuple [tuple ], num_sessions = 6 ) -> None :
3532 """Run a function in parallel sessions.
3633 The function will be run {num_sessions} times with args[i] as input.
@@ -43,7 +40,7 @@ def run_batch(func:Callable, args:tuple[tuple], num_sessions=6) -> None:
4340 for i in range (num_sessions ):
4441 t = ExThread (target = run_with_session , args = (i , func , args [i ]))
4542 threads .append (t )
46-
43+
4744 for t in threads :
4845 t .start ()
4946 for t in threads :
@@ -52,7 +49,6 @@ def run_batch(func:Callable, args:tuple[tuple], num_sessions=6) -> None:
5249 if t .error :
5350 raise t .error
5451
55-
5652def run_batches (func :Callable , args :tuple [tuple ], num_sessions = 6 ):
5753 """Run a function in parallel batches.
5854 This function runs the input function for each set of arguments in args.
@@ -66,26 +62,16 @@ def run_batches(func:Callable, args:tuple[tuple], num_sessions=6):
6662 batch = args [b :b + num_sessions ]
6763 run_batch (func , args , len (batch ))
6864
69-
70- def spawn_sessions (num_sessions = 6 ) -> tuple :
65+ def spawn_sessions (num_sessions = 6 ) -> list :
7166 """A function to spawn multiple sessions of SAP.
7267 This function will attempt to spawn the desired number of sessions.
73- If the current number of already open sessions exceeds the desired number of sessions
68+ If the current number of open sessions exceeds the desired number of sessions
7469 the already open sessions will not be closed to match the desired number.
7570 The number of sessions must be between 1 and 6.
76-
77- Args:
78- num_sessions: The number of sessions desired. Defaults to 6.
79-
80- Raises:
81- ValueError: If the number of sessions is not between 1 and 6.
82-
83- Returns:
84- tuple: A tuple of all currently open sessions.
71+ Returns a list of all open sessions.
8572 """
86-
87- sap = win32com .client .GetObject ("SAPGUI" )
88- app = sap .GetScriptingEngine
73+ SAP = win32com .client .GetObject ("SAPGUI" )
74+ app = SAP .GetScriptingEngine
8975 connection = app .Connections (0 )
9076 session = connection .Sessions (0 )
9177
@@ -96,17 +82,25 @@ def spawn_sessions(num_sessions=6) -> tuple:
9682
9783 for _ in range (num_sessions - connection .Sessions .count ):
9884 session .CreateSession ()
99-
85+
10086 # Wait for the sessions to spawn
10187 while connection .Sessions .count < num_sessions :
10288 time .sleep (0.1 )
10389
104- sessions = tuple (connection .Sessions )
90+ sessions = list (connection .Sessions )
10591 num_sessions = len (sessions )
10692
107- # Calculate number of columns and rows
108- c = math .ceil (math .sqrt (num_sessions ))
109- r = math .ceil (num_sessions / c )
93+ if num_sessions == 1 :
94+ c = 1
95+ elif num_sessions <= 4 :
96+ c = 2
97+ elif num_sessions <= 6 :
98+ c = 3
99+
100+ if num_sessions < 3 :
101+ r = 1
102+ else :
103+ r = 2
110104
111105 w , h = 1920 // c , 1040 // r
112106
@@ -117,22 +111,20 @@ def spawn_sessions(num_sessions=6) -> tuple:
117111 x = i % c * w
118112 y = i // c * h
119113 win32gui .MoveWindow (hwnd , x , y , w , h , True )
120-
114+
121115 return sessions
122116
123-
124- def get_all_SAP_sessions () -> tuple : # pylint: disable=invalid-name
117+ def get_all_SAP_sessions () -> tuple :
125118 """Returns a tuple of all open SAP sessions (on connection index 0).
126119
127120 Returns:
128121 tuple: A tuple of SAP GuiSession objects.
129122 """
130- sap = win32com .client .GetObject ("SAPGUI" )
131- app = sap .GetScriptingEngine
123+ SAP = win32com .client .GetObject ("SAPGUI" )
124+ app = SAP .GetScriptingEngine
132125 connection = app .Connections (0 )
133126 return tuple (connection .Sessions )
134127
135-
136128class ExThread (threading .Thread ):
137129 """A thread with a handle to get an exception raised inside the thread: ExThread.error"""
138130 def __init__ (self , * args , ** kwargs ):
@@ -144,3 +136,5 @@ def run(self):
144136 self ._target (* self ._args , ** self ._kwargs )
145137 except Exception as e : # pylint: disable=broad-exception-caught
146138 self .error = e
139+
140+
0 commit comments