rpa-suite 1.4.8__py3-none-any.whl → 1.4.9__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.
@@ -33,6 +33,7 @@ from .print import Print
33
33
  from .regex import Regex
34
34
  from .validate import Validate
35
35
  from .parallel import ParallelRunner
36
+ from .asyncrun import AsyncRunner
36
37
 
37
38
 
38
39
 
@@ -0,0 +1,140 @@
1
+ # rpa_suite/core/asyncrun.py
2
+
3
+ # imports third-party
4
+ from typing import Any, Callable, Dict, Optional, TypeVar, Generic
5
+ import asyncio
6
+ import time
7
+ import traceback
8
+ from functools import wraps
9
+
10
+
11
+ T = TypeVar('T')
12
+
13
+
14
+ class AsyncRunner(Generic[T]):
15
+ """
16
+ Class to execute asynchronous functions while maintaining the main application flow.
17
+
18
+ Allows executing asynchronous functions and retrieving their results later.
19
+ Optimized for I/O bound operations (network, files, etc).
20
+ """
21
+
22
+ def __init__(self):
23
+ """Start AsyncRunner."""
24
+ self._task = None
25
+ self._start_time = None
26
+ self._result = {}
27
+
28
+ @staticmethod
29
+ def _to_async(func: Callable) -> Callable:
30
+ """
31
+ Converts a synchronous function into an asynchronous one if necessary.
32
+
33
+ Args:
34
+ func: The function to be converted.
35
+
36
+ Returns:
37
+ A callable that is asynchronous.
38
+ """
39
+ @wraps(func)
40
+ async def wrapper(*args, **kwargs):
41
+ if asyncio.iscoroutinefunction(func):
42
+ return await func(*args, **kwargs)
43
+ return await asyncio.to_thread(func, *args, **kwargs)
44
+ return wrapper
45
+
46
+ async def _execute_function(self, function, args, kwargs):
47
+ """
48
+ Executes the function and manages results/errors.
49
+
50
+ Args:
51
+ function: The function to be executed.
52
+ args: Positional arguments for the function.
53
+ kwargs: Keyword arguments for the function.
54
+ """
55
+ try:
56
+ async_func = self._to_async(function)
57
+ result = await async_func(*args, **kwargs)
58
+
59
+ self._result = {
60
+ 'status': 'success',
61
+ 'result': result,
62
+ 'success': True
63
+ }
64
+
65
+ except Exception as e:
66
+ self._result = {
67
+ 'status': 'error',
68
+ 'error': str(e),
69
+ 'traceback': traceback.format_exc(),
70
+ 'success': False
71
+ }
72
+
73
+ def run(self, function: Callable[..., T], *args, **kwargs) -> 'AsyncRunner[T]':
74
+ """
75
+ Starts the execution of the function asynchronously.
76
+
77
+ Args:
78
+ function: The function to be executed.
79
+ *args: Positional arguments for the function.
80
+ **kwargs: Keyword arguments for the function.
81
+
82
+ Returns:
83
+ self: Returns the instance itself.
84
+ """
85
+ self._result.clear()
86
+ self._start_time = time.time()
87
+
88
+ # Creates and schedules the asynchronous task
89
+ loop = asyncio.get_event_loop()
90
+ self._task = loop.create_task(self._execute_function(function, args, kwargs))
91
+
92
+ return self
93
+
94
+ def is_running(self) -> bool:
95
+ """
96
+ Checks if the task is still running.
97
+
98
+ Returns:
99
+ True if the task is running, False otherwise.
100
+ """
101
+ return self._task is not None and not self._task.done()
102
+
103
+ async def get_result(self, timeout: Optional[float] = None) -> Dict[str, Any]:
104
+ """
105
+ Retrieves the result of the asynchronous execution.
106
+
107
+ Args:
108
+ timeout: Maximum time (in seconds) to wait.
109
+
110
+ Returns:
111
+ A dictionary with the result or error information.
112
+ """
113
+ if self._task is None:
114
+ return {
115
+ 'success': False,
116
+ 'error': 'No task has been started',
117
+ 'execution_time': 0
118
+ }
119
+
120
+ try:
121
+ await asyncio.wait_for(self._task, timeout=timeout)
122
+
123
+ except asyncio.TimeoutError:
124
+ self._task.cancel()
125
+ return {
126
+ 'success': False,
127
+ 'error': f'Operation canceled due to timeout after {time.time() - self._start_time:.2f} seconds',
128
+ 'execution_time': time.time() - self._start_time
129
+ }
130
+
131
+ result = dict(self._result)
132
+ result['execution_time'] = time.time() - self._start_time
133
+ return result
134
+
135
+ def cancel(self) -> None:
136
+ """
137
+ Cancels the running task.
138
+ """
139
+ if self.is_running():
140
+ self._task.cancel()
rpa_suite/core/browser.py CHANGED
@@ -16,7 +16,6 @@ from time import sleep
16
16
  import os, requests
17
17
 
18
18
 
19
-
20
19
  class Browser():
21
20
 
22
21
  """
rpa_suite/core/date.py CHANGED
@@ -10,6 +10,7 @@ from typing import Tuple
10
10
 
11
11
 
12
12
  class Date():
13
+
13
14
  """
14
15
  Class that provides utilities for date manipulation and formatting.
15
16
 
rpa_suite/core/file.py CHANGED
@@ -13,7 +13,6 @@ from datetime import datetime
13
13
  from typing import Dict, List, Union
14
14
 
15
15
 
16
-
17
16
  class File():
18
17
  """
19
18
  Class that provides utilities for file management, including creation, deletion, and manipulation of files.
@@ -1,31 +1,60 @@
1
1
  # rpa_suite/core/parallel.py
2
2
 
3
+ # imports third-party
3
4
  from multiprocessing import Process, Manager
4
5
  from typing import Any, Callable, Dict, Optional, TypeVar, Generic
5
6
  import time
6
7
  import traceback
7
8
 
8
- # Definir tipo genérico para o retorno da função
9
+ # Define a generic type for the function return
9
10
  T = TypeVar('T')
10
11
 
12
+
11
13
  class ParallelRunner(Generic[T]):
12
14
 
13
15
  """
16
+ Class to execute functions in parallel while maintaining the main application flow.
17
+
18
+ Allows starting a function in a separate process and retrieving its result later.
19
+
20
+ pt-br
21
+ ------
14
22
  Classe para executar funções em paralelo mantendo o fluxo principal da aplicação.
15
23
 
16
24
  Permite iniciar uma função em um processo separado e obter seu resultado posteriormente.
17
25
  """
18
26
 
19
- def __init__(self):
20
- """Inicializa o ParallelRunner."""
27
+ display_message = None
28
+
29
+ def __init__(self, display_message: bool = False):
30
+ """
31
+ Initializes the ParallelRunner.
32
+
33
+ Args:
34
+ display_message (bool): If True, displays debug messages during execution.
35
+
36
+ pt-br
37
+ ------
38
+ Inicializa o ParallelRunner.
39
+
40
+ Args:
41
+ display_message (bool): Se True, exibe mensagens de debug durante a execução.
42
+ """
43
+
21
44
  self._manager = Manager()
22
45
  self._result_dict = self._manager.dict()
23
46
  self._process = None
24
47
  self._start_time = None
25
-
48
+ self.display_message = display_message
49
+
26
50
  @staticmethod
27
51
  def _execute_function(function, args, kwargs, result_dict):
28
52
  """
53
+ Static method that executes the target function and stores the result.
54
+ This function needs to be defined at the module level to be "picklable".
55
+
56
+ pt-br
57
+ ------
29
58
  Função estática que executa a função alvo e armazena o resultado.
30
59
  Esta função precisa ser definida no nível do módulo para ser "picklable".
31
60
  """
@@ -38,8 +67,8 @@ class ParallelRunner(Generic[T]):
38
67
  result_dict['result'] = result
39
68
 
40
69
  # Para debug
41
- print(f"[Processo Filho] Resultado calculado: {result}")
42
- print(f"[Processo Filho] Dicionário de resultados: {dict(result_dict)}")
70
+ #print(f"[Processo Filho] Resultado calculado: {result}")
71
+ #print(f"[Processo Filho] Dicionário de resultados: {dict(result_dict)}")
43
72
 
44
73
  except Exception as e:
45
74
  # Em caso de erro, armazena informações sobre o erro
@@ -50,8 +79,53 @@ class ParallelRunner(Generic[T]):
50
79
  # Para debug
51
80
  print(f"[Processo Filho] Erro ocorrido: {str(e)}")
52
81
 
82
+ @staticmethod
83
+ def _execute_function_w_disp_msg(function, args, kwargs, result_dict):
84
+ """
85
+ Static method that executes the target function and stores the result.
86
+ This function needs to be defined at the module level to be "picklable".
87
+
88
+ pt-br
89
+ ------
90
+ Função estática que executa a função alvo e armazena o resultado.
91
+ Esta função precisa ser definida no nível do módulo para ser "picklable".
92
+ """
93
+ try:
94
+ # Executa a função do usuário com os argumentos fornecidos
95
+ result = function(*args, **kwargs)
96
+
97
+ # Armazena o resultado no dicionário compartilhado
98
+ result_dict['status'] = 'success'
99
+ result_dict['result'] = result
100
+
101
+ # Para debug
102
+ print(f"[Processo Filho] Resultado calculado: {result}")
103
+ print(f"[Processo Filho] Dicionário de resultados: {dict(result_dict)}")
104
+
105
+ except Exception as e:
106
+ # Em caso de erro, armazena informações sobre o erro
107
+ result_dict['status'] = 'error'
108
+ result_dict['error'] = str(e)
109
+ result_dict['traceback'] = traceback.format_exc()
110
+
111
+ # Para debug
112
+ print(f"[Processo Filho] Erro ocorrido: {str(e)}")
113
+
114
+
53
115
  def run(self, function: Callable[..., T], *args, **kwargs) -> 'ParallelRunner[T]':
54
116
  """
117
+ Starts the execution of the function in a parallel process.
118
+
119
+ Args:
120
+ function: Function to be executed in parallel
121
+ *args: Positional arguments for the function
122
+ **kwargs: Keyword arguments for the function
123
+
124
+ Returns:
125
+ self: Returns the instance itself to allow chained calls
126
+
127
+ pt-br
128
+ ------
55
129
  Inicia a execução da função em um processo paralelo.
56
130
 
57
131
  Args:
@@ -70,10 +144,17 @@ class ParallelRunner(Generic[T]):
70
144
  self._result_dict['status'] = 'running'
71
145
 
72
146
  # Inicia o processo com a função auxiliar estática
73
- self._process = Process(
74
- target=ParallelRunner._execute_function,
75
- args=(function, args, kwargs, self._result_dict)
76
- )
147
+ if self.display_message:
148
+ self._process = Process(
149
+ target=ParallelRunner._execute_function_w_disp_msg,
150
+ args=(function, args, kwargs, self._result_dict)
151
+ )
152
+ else:
153
+ self._process = Process(
154
+ target=ParallelRunner._execute_function,
155
+ args=(function, args, kwargs, self._result_dict)
156
+ )
157
+
77
158
  self._process.daemon = True # Processo filho termina quando o principal termina
78
159
  self._process.start()
79
160
  self._start_time = time.time()
@@ -82,33 +163,60 @@ class ParallelRunner(Generic[T]):
82
163
 
83
164
  def is_running(self) -> bool:
84
165
  """
85
- Verifica se o processo ainda está em execução.
166
+ Checks if the process is still running.
86
167
 
87
168
  Returns:
169
+ bool: True if the process is still running, False otherwise
170
+
171
+ pt-br
172
+ ------
173
+ Verifica se o processo ainda está em execução.
174
+
175
+ Retorna:
88
176
  bool: True se o processo ainda estiver em execução, False caso contrário
89
177
  """
90
178
  if self._process is None:
91
179
  return False
92
180
  return self._process.is_alive()
93
181
 
94
- def get_result(self, timeout: Optional[float] = None, terminate_on_timeout: bool = True) -> Dict[str, Any]:
182
+ def get_result(self, timeout: Optional[float] = 60, terminate_on_timeout: bool = True) -> Dict[str, Any]:
95
183
  """
96
- Obtém o resultado da execução paralela.
184
+ Retrieves the result of the parallel execution.
97
185
 
98
186
  Args:
99
- timeout: Tempo máximo (em segundos) para aguardar o término do processo
100
- None significa esperar indefinidamente
101
- terminate_on_timeout: Se True, termina o processo caso o timeout seja atingido
187
+ timeout: Maximum time (in seconds) to wait for the process to finish.
188
+ None means wait indefinitely.
189
+ terminate_on_timeout: If True, terminates the process if the timeout is reached.
102
190
 
103
191
  Returns:
104
- Dict contendo:
105
- - success: bool indicando se a operação foi bem-sucedida
106
- - result: resultado da função (se bem-sucedida)
107
- - error: mensagem de erro (se houver)
108
- - traceback: stack trace completo (se houver erro)
109
- - execution_time: tempo de execução em segundos
110
- - terminated: True se o processo foi terminado por timeout
192
+ - Dict containing:
193
+ - success: bool indicating if the operation was successful.
194
+ - result: result of the function (if successful).
195
+ - error: error message (if any).
196
+ - traceback: full stack trace (if an error occurred).
197
+ - execution_time: execution time in seconds.
198
+ - terminated: True if the process was terminated due to timeout.
199
+
200
+ pt-br
201
+ ------
202
+
203
+ Recupera o resultado da execução paralela.
204
+
205
+ Args:
206
+ timeout: Tempo máximo (em segundos) para aguardar o término do processo.
207
+ None significa aguardar indefinidamente.
208
+ terminate_on_timeout: Se True, termina o processo se o tempo limite for atingido.
209
+
210
+ Retorna:
211
+ - Dicionário contendo:
212
+ - success: bool indicando se a operação foi bem-sucedida.
213
+ - result: resultado da função (se bem-sucedida).
214
+ - error: mensagem de erro (se houver).
215
+ - traceback: rastreamento completo da pilha (se ocorreu um erro).
216
+ - execution_time: tempo de execução em segundos.
217
+ - terminated: True se o processo foi terminado devido ao tempo limite.
111
218
  """
219
+
112
220
  if self._process is None:
113
221
  return {
114
222
  'success': False,
@@ -128,7 +236,7 @@ class ParallelRunner(Generic[T]):
128
236
  }
129
237
 
130
238
  # Debug - mostra o dicionário compartilhado
131
- print(f"[Processo Principal] Dicionário compartilhado: {dict(self._result_dict)}")
239
+ if self.display_message: print(f"[Processo Principal] Dicionário compartilhado: {dict(self._result_dict)}")
132
240
 
133
241
  # Verifica se o processo terminou ou se atingiu o timeout
134
242
  if self._process.is_alive():
@@ -167,6 +275,10 @@ class ParallelRunner(Generic[T]):
167
275
 
168
276
  def terminate(self) -> None:
169
277
  """
278
+ Terminates the running process.
279
+
280
+ pt-br
281
+ ------
170
282
  Termina o processo em execução.
171
283
  """
172
284
  if self._process and self._process.is_alive():
@@ -176,6 +288,10 @@ class ParallelRunner(Generic[T]):
176
288
 
177
289
  def _cleanup(self) -> None:
178
290
  """
291
+ Cleans up resources used by the process.
292
+
293
+ pt-br
294
+ ------
179
295
  Limpa os recursos utilizados pelo processo.
180
296
  """
181
297
  if hasattr(self, '_manager') and self._manager is not None:
@@ -188,6 +304,10 @@ class ParallelRunner(Generic[T]):
188
304
 
189
305
  def __del__(self):
190
306
  """
307
+ Destructor of the class, ensures resources are released.
308
+
309
+ pt-br
310
+ ------
191
311
  Destrutor da classe, garante que recursos sejam liberados.
192
312
  """
193
- self.terminate()
313
+ self.terminate()
rpa_suite/suite.py CHANGED
@@ -11,6 +11,7 @@ from .core.print import Print
11
11
  from .core.regex import Regex
12
12
  from .core.validate import Validate
13
13
  from .core.parallel import ParallelRunner
14
+ from .core.asyncrun import AsyncRunner
14
15
 
15
16
 
16
17
  # imports external
@@ -148,6 +149,7 @@ class Suite():
148
149
  regex: Regex = Regex()
149
150
  validate: Validate = Validate()
150
151
  Parallel: ParallelRunner = ParallelRunner
152
+ Asyn: AsyncRunner = AsyncRunner
151
153
 
152
154
  # On this case, we are importing the Browser class only if the selenium and webdriver_manager modules are installed.
153
155
  # This is useful to avoid unnecessary imports and dependencies if the user does not need the Browser functionality.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rpa_suite
3
- Version: 1.4.8
3
+ Version: 1.4.9
4
4
  Summary: Conjunto de ferramentas essenciais para Automação RPA com Python, que facilitam o dia a dia de desenvolvimento.
5
5
  Author: Camilo Costa de Carvalho
6
6
  Author-email: camilo.carvalho@triasoftware.com.br
@@ -65,7 +65,7 @@ Dynamic: summary
65
65
  - [Dependências](#dependências)
66
66
  - [Estrutura do módulo](#estrutura-do-módulo)
67
67
  - [Release](#release)
68
- - [Notas da atualização: 1.4.8](#notas-da-atualização-148)
68
+ - [Notas da atualização: 1.4.9](#notas-da-atualização-149)
69
69
  - [Mais Sobre](#mais-sobre)
70
70
 
71
71
  ## Destaque
@@ -156,6 +156,7 @@ No setup do nosso projeto já estão inclusas as dependências, só será necess
156
156
  - pillow
157
157
  - pyautogui
158
158
  - typing
159
+ - setuptools
159
160
 
160
161
  opcionalmente para automação de navegador:
161
162
 
@@ -226,9 +227,15 @@ O módulo principal do rpa-suite é dividido em categorias. Cada categoria cont
226
227
  - **get_result** - Função para coletar o retorno da execução em paralelo junto com resultado da função ou funções que foram enviadas a este processo com retorno em forma de dict.
227
228
  - **terminate** - Função para finalizar o processo paralelo mantendo apenas o processo principal do seu código, também é chamada de forma automatica esta função ao final de um procesos paralelo ou no final da função "get_result".
228
229
 
230
+ - **async**
231
+ - **run** - Função para iniciar a execução assíncrona de uma função mantendo o fluxo principal da aplicação.
232
+ - **is_running** - Função para verificar se a tarefa assíncrona ainda está em execução.
233
+ - **get_result** - Função para obter o resultado da execução assíncrona, incluindo tempo de execução e status, com suporte a timeout.
234
+ - **cancel** - Função para cancelar a tarefa assíncrona em execução.
235
+
229
236
  ## Release
230
237
 
231
- Versão: **Beta 1.4.8**
238
+ Versão: **Beta 1.4.9**
232
239
 
233
240
  Lançamento: *20/02/2024*
234
241
 
@@ -236,11 +243,12 @@ Lançamento: *20/02/2024*
236
243
 
237
244
  Status: Em desenvolvimento.
238
245
 
239
- ### Notas da atualização: 1.4.8
246
+ ### Notas da atualização: 1.4.9
240
247
 
241
248
  - Mudança dos submodulos para Objetos, agora Rpa_suite é um Objeto de Suite que compoe diversos sub-objetos separados pelas mesmas categorias anteriormente ja definidas
242
249
  - Reformulada a arquitetura do projeto para melhor coeção e menos subpastas e arquivos, agora a estrutura é mais simples e de melhor manutenção contendo apenas uma pasta core para o nucleo de nossos modulos, e uma pasta utils com ferramentas utilitarias que vamos adicionar varias novidades
243
- - Adicionado SubModulo Parallel com função dedicada a rodar um processo em paralelo com seu fluxo principal podendo recuperar o resultado da execução em paralelo a qualquer momento e setando timeout ou deixando o tempo indefinido para aguardar a resposta.
250
+ - Adicionado SubModulo Parallel com função dedicada a rodar um processo em paralelo com seu fluxo principal podendo recuperar o resultado da execução em paralelo a qualquer momento e setando timeout ou deixando o tempo indefinido para aguardar a resposta.
251
+ - Adicionado SubModulo AsyncRunnner com função dedicada a facilitar uso de funções assincronas podendo recuperar seus resultados usando menos código, é um modulo simples porem poupa-nos tempo.
244
252
  - Adicionado setor utils com funcionalidade de tornar o diretorio atual em um importavel relativo para o python
245
253
  - Adicionado Automação de Navegadores! Sim estamos devendo esta feature a bastante tempo, porem estamos com a primeira versão disponivel, em breve teremos mais recursos e disponibilidade para outros navegadores, atualmente suporte apenas para *Chrome.*
246
254
  - Mantemos o alerta! **get_dma** atualizada e **renomeada** para **get_dmy** para manter o padrão em ingles
@@ -1,14 +1,15 @@
1
1
  rpa_suite/__init__.py,sha256=KO6GC2XbZUO56SAOgKxIkycHFEy6oeWPSswd8-B5IP4,2562
2
- rpa_suite/suite.py,sha256=4aKwFsIz4YuDuKD41o2ws5bRkmt11uDblymCarYHHUw,11110
3
- rpa_suite/core/__init__.py,sha256=27hq1brv83Kf89xtk-VVQx2etUWWBnVoZMgbgKI7Ac0,1678
4
- rpa_suite/core/browser.py,sha256=XgUoOc6pcFwnSQxSlcOF0x8JjlUmj7gw3OvSJ_EoQns,14757
2
+ rpa_suite/suite.py,sha256=1lsdFLz44gh7y3leOR5BCsx1dEKam5cm1g7l5RCFsYc,11187
3
+ rpa_suite/core/__init__.py,sha256=oGQiEtmgR9fBHgcAKYsl5eZsS2_SbRZnlhzOgRqXrAM,1713
4
+ rpa_suite/core/asyncrun.py,sha256=S5b-ueG4oJmupBZLsfYqcyTA5k5SaAi8j3KU8NnTOMg,4378
5
+ rpa_suite/core/browser.py,sha256=h1sMERkEw8y8zfQs2hdv2VbBNt3pQlVkMlkQOTKpaKQ,14755
5
6
  rpa_suite/core/clock.py,sha256=-ZEEaTYzwoYk9Bw1K6K1RN4s7O21uEhTg2hgBmdYLtQ,13880
6
- rpa_suite/core/date.py,sha256=4T8_JKWBcYh4klQBAYx4RrmsKqz7uUb8wD5UtgCueeg,6629
7
+ rpa_suite/core/date.py,sha256=0dqkP7zVjWeMmZA5xDZuvin97yYPMl1p0bCfLmtXdlM,6635
7
8
  rpa_suite/core/dir.py,sha256=sc_mJGrjo520cmNyC_HZo3YKEbORkBDfD3bCLaQ7U2o,9855
8
9
  rpa_suite/core/email.py,sha256=CUqhW8-BF0XS7vFeZieQ13VywEg1TQZVoicEexSQCPE,8671
9
- rpa_suite/core/file.py,sha256=9Psho6n9eqfLu3aA3XW43LzXefEJnAgIentFyopOpxQ,11623
10
+ rpa_suite/core/file.py,sha256=8eKlOSRptCYDJ-zRrHYK7tnmxR-JjQ55U47BRRdMGRE,11621
10
11
  rpa_suite/core/log.py,sha256=7VTPKXzVkWMg1W5bBO6BM3XDihKqNOcB4D-d6ytDbts,5631
11
- rpa_suite/core/parallel.py,sha256=Pftz5cC-3jJLlprLjjSYadc6A9omBBmziCmeUcvNKh4,7668
12
+ rpa_suite/core/parallel.py,sha256=p5jM7UwLWGYoYuQoUo659469nsuvy9QEkzVhXqu-GnU,11876
12
13
  rpa_suite/core/print.py,sha256=jhCNdid67dtVE6cCgRnWjqUrmsJcAr1hN38MHVupgfo,6423
13
14
  rpa_suite/core/regex.py,sha256=gh3dlV29chepdoaWsl5yW9Db6MHQTGJeWstm0mD9zKU,3377
14
15
  rpa_suite/core/validate.py,sha256=vKpl4u7f8CM30e_1rS6sqUqePy0ga51HHGn1cgent1o,11032
@@ -17,8 +18,8 @@ rpa_suite/functions/__init__.py,sha256=aa0jejVvnghufR50owKcKpmYit7XVAliyN9gn9Jkd
17
18
  rpa_suite/functions/_printer.py,sha256=51Xbqr0Ck7HHOrhJCxhMxdCKrF_kQ5AsKZN5SZQPwpk,3991
18
19
  rpa_suite/utils/__init__.py,sha256=RQ-m9QNbaByek25moxx9ajpuxjPAEdjoMu69ReLBCWY,675
19
20
  rpa_suite/utils/system.py,sha256=fQ9BAWxVETrFUeZJlfhN3cLzToU3XDQYqvDS9W0hWgY,1157
20
- rpa_suite-1.4.8.dist-info/licenses/LICENSE,sha256=5D8PIbs31iGd9i1_MDNg4SzaQnp9sEIULALh2y3WyMI,1102
21
- rpa_suite-1.4.8.dist-info/METADATA,sha256=N6Yo_DNSgM__jAR4X1SUULETkDQZRSnG-bcciOxkOXQ,12769
22
- rpa_suite-1.4.8.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
23
- rpa_suite-1.4.8.dist-info/top_level.txt,sha256=HYkDtg-kJNAr3F2XAIPyJ-QBbNhk7q6jrqsFt10lz4Y,10
24
- rpa_suite-1.4.8.dist-info/RECORD,,
21
+ rpa_suite-1.4.9.dist-info/licenses/LICENSE,sha256=5D8PIbs31iGd9i1_MDNg4SzaQnp9sEIULALh2y3WyMI,1102
22
+ rpa_suite-1.4.9.dist-info/METADATA,sha256=_Sb_Dl_nnF0kJYHsP0HGAQITOOWFvlndupMsQq9M47Y,13447
23
+ rpa_suite-1.4.9.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
24
+ rpa_suite-1.4.9.dist-info/top_level.txt,sha256=HYkDtg-kJNAr3F2XAIPyJ-QBbNhk7q6jrqsFt10lz4Y,10
25
+ rpa_suite-1.4.9.dist-info/RECORD,,