lbxtoolkit 2.2.13__tar.gz → 2.3.0__tar.gz
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.
- {lbxtoolkit-2.2.13 → lbxtoolkit-2.3.0}/PKG-INFO +14 -13
- {lbxtoolkit-2.2.13 → lbxtoolkit-2.3.0}/lbxtoolkit/misc.py +44 -0
- {lbxtoolkit-2.2.13 → lbxtoolkit-2.3.0}/lbxtoolkit/service.py +16 -4
- {lbxtoolkit-2.2.13 → lbxtoolkit-2.3.0}/lbxtoolkit/service_windows.py +71 -18
- lbxtoolkit-2.3.0/pyproject.toml +31 -0
- lbxtoolkit-2.2.13/pyproject.toml +0 -31
- {lbxtoolkit-2.2.13 → lbxtoolkit-2.3.0}/README.md +0 -0
- {lbxtoolkit-2.2.13 → lbxtoolkit-2.3.0}/lbxtoolkit/__init__.py +0 -0
- {lbxtoolkit-2.2.13 → lbxtoolkit-2.3.0}/lbxtoolkit/api_rest.py +0 -0
- {lbxtoolkit-2.2.13 → lbxtoolkit-2.3.0}/lbxtoolkit/auth_entra_id.py +0 -0
- {lbxtoolkit-2.2.13 → lbxtoolkit-2.3.0}/lbxtoolkit/config_manager.py +0 -0
- {lbxtoolkit-2.2.13 → lbxtoolkit-2.3.0}/lbxtoolkit/lbx_logger.py +0 -0
- {lbxtoolkit-2.2.13 → lbxtoolkit-2.3.0}/lbxtoolkit/postgresql.py +0 -0
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: lbxtoolkit
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Cristiano P. Ferrari
|
|
6
6
|
Author-email: cristiano.ferrari@lbx.com.br
|
|
7
7
|
Requires-Python: >=3.12,<4.0
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
-
|
|
11
|
-
Requires-Dist:
|
|
12
|
-
Requires-Dist:
|
|
13
|
-
Requires-Dist:
|
|
14
|
-
Requires-Dist:
|
|
15
|
-
Requires-Dist:
|
|
16
|
-
Requires-Dist:
|
|
17
|
-
Requires-Dist:
|
|
18
|
-
Requires-Dist:
|
|
19
|
-
Requires-Dist:
|
|
20
|
-
Requires-Dist:
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
11
|
+
Requires-Dist: msal (>=1.30.0)
|
|
12
|
+
Requires-Dist: numpy (>=2.0.1)
|
|
13
|
+
Requires-Dist: pandas (>=2.2.2)
|
|
14
|
+
Requires-Dist: psutil (>=6.0.0)
|
|
15
|
+
Requires-Dist: psycopg2 (>=2.9.9)
|
|
16
|
+
Requires-Dist: pygetwindow (>=0.0.9)
|
|
17
|
+
Requires-Dist: pywin32 (>=306)
|
|
18
|
+
Requires-Dist: requests (>=2.32.3)
|
|
19
|
+
Requires-Dist: selenium (>=4.23.1)
|
|
20
|
+
Requires-Dist: validators (>=0.33.0)
|
|
21
|
+
Requires-Dist: webdriver-manager (>=4.0.2)
|
|
21
22
|
Description-Content-Type: text/markdown
|
|
22
23
|
|
|
23
24
|
<a id="lbxtoolkit"></a>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import sys
|
|
2
3
|
import re
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
from unicodedata import normalize
|
|
@@ -83,6 +84,49 @@ Sintaxe e exemplos de uso. Parametros omissos assume-se os valores padrão indic
|
|
|
83
84
|
user32.ShowWindow(hWnd, 3) # 3 = SW_MAXIMIZE
|
|
84
85
|
#
|
|
85
86
|
#
|
|
87
|
+
def encontra_projeto_raiz(caminho_partida):
|
|
88
|
+
"""Sobe a árvore procurando por .venv OU pyproject.toml como raiz do projeto"""
|
|
89
|
+
dir_atual = os.path.abspath(caminho_partida)
|
|
90
|
+
while True:
|
|
91
|
+
if (
|
|
92
|
+
os.path.isdir(os.path.join(dir_atual, '.venv')) or
|
|
93
|
+
os.path.isfile(os.path.join(dir_atual, 'pyproject.toml'))
|
|
94
|
+
):
|
|
95
|
+
return dir_atual
|
|
96
|
+
novo_dir = os.path.dirname(dir_atual)
|
|
97
|
+
if novo_dir == dir_atual:
|
|
98
|
+
return None # Chegou na raiz do sistema
|
|
99
|
+
dir_atual = novo_dir
|
|
100
|
+
#
|
|
101
|
+
#
|
|
102
|
+
def encontra_python_venv(raiz_projeto):
|
|
103
|
+
"""Retorna o caminho do python da .venv se existir, senão None"""
|
|
104
|
+
if os.name == 'nt':
|
|
105
|
+
# Windows
|
|
106
|
+
python_venv = os.path.join(raiz_projeto, '.venv', 'Scripts', 'python.exe')
|
|
107
|
+
else:
|
|
108
|
+
# Linux/Mac
|
|
109
|
+
python_venv = os.path.join(raiz_projeto, '.venv', 'bin', 'python')
|
|
110
|
+
return python_venv if os.path.isfile(python_venv) else None
|
|
111
|
+
#
|
|
112
|
+
#
|
|
113
|
+
def nome_modulo(script_path, raiz_projeto):
|
|
114
|
+
"""
|
|
115
|
+
Dado o caminho absoluto do script (ex: C:/.../src/cnab/main.py)
|
|
116
|
+
e da raiz do projeto (ex: C:/...),
|
|
117
|
+
retorna o caminho do módulo python no formato pacote.subpacote.modulo
|
|
118
|
+
Exemplo: src.cnab.main
|
|
119
|
+
"""
|
|
120
|
+
relpath = os.path.relpath(script_path, raiz_projeto)
|
|
121
|
+
if relpath.endswith('.py'):
|
|
122
|
+
relpath = relpath[:-3] # remove .py
|
|
123
|
+
partes = []
|
|
124
|
+
for parte in relpath.replace("\\", "/").split("/"):
|
|
125
|
+
if parte not in ("", "__init__"):
|
|
126
|
+
partes.append(parte)
|
|
127
|
+
return ".".join(partes)
|
|
128
|
+
#
|
|
129
|
+
#
|
|
86
130
|
@classmethod
|
|
87
131
|
def cor(cls, text, color=None, style=None):
|
|
88
132
|
"""
|
|
@@ -42,7 +42,9 @@ O objetos mandatórios a serem inicilizados pelo **ConfigManager** são:
|
|
|
42
42
|
- **servicepath** = Objeto do Path com o caminho deste script
|
|
43
43
|
- **argparse_cfg** = Dicionário contendo os parametros de configuração (descrition, usage, add_help e formatter_classe) do módulo argparse (manipulado dos parametros de linha de comando)
|
|
44
44
|
- **argparse_opt** = Lista de dicionários com a configuração do argumentos de entrada aceitos (short, long, action, help)
|
|
45
|
-
- **ambiente** = Definie o ambiente de excução: Linux, Windows [console] ou Serviço [Windows]
|
|
45
|
+
- **ambiente** = Definie o ambiente de excução: Linux, Windows [console] ou Serviço [Windows]
|
|
46
|
+
- **raiz_projeto** = A raiz do projeto para fins de execução por módulo (python -m) e não diretamente pelo script. Utilize `misc.encrontra_projeto_raiz` no módulo principal para obter essa informação
|
|
47
|
+
- **modulo** = O nome do módulo quando o projeto for extrutura para execução por módulo. Utilize `misc.nome_modulo` no módulo principal para obter essa informação
|
|
46
48
|
|
|
47
49
|
> [!NOTE]
|
|
48
50
|
> Para ser funcional, é necessária que a classe local herde essa classe base e redefina (por sobrecarga) ao menos os métodos `on_run` e `args_parser()`.
|
|
@@ -148,11 +150,21 @@ class ServicerConfig(Servicer):
|
|
|
148
150
|
```
|
|
149
151
|
"""
|
|
150
152
|
def __init__(self, Log=None, piddir=None):#TODO: ao criar uma classe padrão usar args/kwargs para lidar como parametros variáveis no instanciamento
|
|
153
|
+
"""
|
|
154
|
+
variáveis abaixo são mandatórias e precisa inicializadas no ConfigManager.inicialize() do módulo principal/pai:
|
|
155
|
+
- log
|
|
156
|
+
- argparse_cfg
|
|
157
|
+
- argparse_opt
|
|
158
|
+
- ambiente
|
|
159
|
+
- raiz_projeto
|
|
160
|
+
- modulo
|
|
161
|
+
"""
|
|
151
162
|
# PRE-REQUISITOS/DEPENDÊNCIAS:
|
|
152
163
|
self.log = ConfigManager.get('log')
|
|
153
164
|
self.kwargs = ConfigManager.get('argparse_cfg')
|
|
154
165
|
self.kwopts = ConfigManager.get('argparse_opt')
|
|
155
|
-
self.ambiente = ConfigManager.get('ambiente')
|
|
166
|
+
self.ambiente = ConfigManager.get('ambiente')
|
|
167
|
+
|
|
156
168
|
if self.log is None or not isinstance(self.log, lbx_logger):
|
|
157
169
|
raise ValueError(f'Argumento "log" é mandatório e deve ser uma instância de "lbxtoolkit.lbx_logger"')
|
|
158
170
|
if self.kwargs is None:
|
|
@@ -161,7 +173,7 @@ class ServicerConfig(Servicer):
|
|
|
161
173
|
raise ValueError(f'Argumento "argparse_opt" é mandatório e deve ser uma lista de dicionários ao mínimo as chaves: [short, long, action, help] para tratamento dos argumentos recebidos da linha de comando')
|
|
162
174
|
if self.ambiente is None or self.ambiente not in ['Linux', 'Windows', 'Serviço']:
|
|
163
175
|
raise ValueError(f'Argumento "ambiente" é mandatório e deve ser uma string com um dos seguintes valores: [Linux, Windows, Serviço]')
|
|
164
|
-
|
|
176
|
+
|
|
165
177
|
self.on_init_pre() ## método opcional a ser definito por sobrecarga na função local
|
|
166
178
|
|
|
167
179
|
# Argumentos padrão obrigatórios
|
|
@@ -208,7 +220,7 @@ class ServicerConfig(Servicer):
|
|
|
208
220
|
servicemanager.PrepareToHostSingle(ServicoWindows)
|
|
209
221
|
servicemanager.StartServiceCtrlDispatcher()
|
|
210
222
|
elif len(sys.argv) > 1 and sys.argv[1] == 'install':
|
|
211
|
-
ServicoWindows.SvcInstall()
|
|
223
|
+
ServicoWindows.SvcInstall()
|
|
212
224
|
elif len(sys.argv) > 1 and sys.argv[1] == 'remove':
|
|
213
225
|
ServicoWindows.SvcRemove()
|
|
214
226
|
else:
|
|
@@ -22,6 +22,20 @@ Gerencia a instalação e execução de um daemon como um serviço do windows. T
|
|
|
22
22
|
- `SvcRemove`: Remove o serviço do windows configurado à partir de `SvcInstall`
|
|
23
23
|
- `SvcStop`: Para/Interrompe a execução do serviço do windows criado por este script (método herdado da classe pai _win32serviceutil.ServiceFramework_ invocado automaticamente pela chamada do service manager do windows)
|
|
24
24
|
- `SvcDoRun`: Inicializa a execução do serviço do windows criado por este script (método herdado da classe pai _win32serviceutil.ServiceFramework_ invocado autoamticamente pela chamada do service manager do windwos)
|
|
25
|
+
|
|
26
|
+
A classe base possui ainda algumas dependÊncias que precisam ser inicializadas fora do contexto da classe configuradora/local.
|
|
27
|
+
Para isso, use classe ConfigManager.initialize(), disponível também no módulo `lbxtoolkit`.
|
|
28
|
+
O objetos mandatórios a serem inicilizados pelo **ConfigManager** são:
|
|
29
|
+
- **log** = Objeto instanciado da classe lbx_logger, para manipular as entradas de log
|
|
30
|
+
- **daemon** = Objeto resultante do instanciamento da própria própria classe configuradora (deve ser inicializado após o instanciamento do objeto daemon, usando `ConfigManager.set()`)
|
|
31
|
+
- **config** = Dicionário contento os parametros (name, display_name e description) para instalar o serviço do windows
|
|
32
|
+
- **servicepath** = Objeto do Path com o caminho deste script
|
|
33
|
+
- **argparse_cfg** = Dicionário contendo os parametros de configuração (descrition, usage, add_help e formatter_classe) do módulo argparse (manipulado dos parametros de linha de comando)
|
|
34
|
+
- **argparse_opt** = Lista de dicionários com a configuração do argumentos de entrada aceitos (short, long, action, help)
|
|
35
|
+
- **ambiente** = Definie o ambiente de excução: Linux, Windows [console] ou Serviço [Windows]
|
|
36
|
+
- **raiz_projeto** = A raiz do projeto para fins de execução por módulo (python -m) e não diretamente pelo script. Utilize `misc.encrontra_projeto_raiz` no módulo principal para obter essa informação
|
|
37
|
+
- **modulo** = O nome do módulo quando o projeto for extrutura para execução por módulo. Utilize `misc.nome_modulo` no módulo principal para obter essa informação
|
|
38
|
+
|
|
25
39
|
"""
|
|
26
40
|
_svc_name_ = None
|
|
27
41
|
_svc_display_name_ = None
|
|
@@ -29,7 +43,9 @@ Gerencia a instalação e execução de um daemon como um serviço do windows. T
|
|
|
29
43
|
def __init__(self, args):
|
|
30
44
|
self.log = ConfigManager.get('log')
|
|
31
45
|
self.daemon = ConfigManager.get('daemon')
|
|
32
|
-
self.config = ConfigManager.get('config')
|
|
46
|
+
self.config = ConfigManager.get('config')
|
|
47
|
+
self.raiz_projeto = ConfigManager.get('raiz_projeto')
|
|
48
|
+
self.modulo = ConfigManager.get('modulo')
|
|
33
49
|
|
|
34
50
|
if self.log is None or (not isinstance(self.log, lbx_logger) and not isinstance(self.log, SafeLogger)):
|
|
35
51
|
raise ValueError(f'Argumento "log" é mandatório e deve ser uma instância de "lbxtoolkit.lbx_logger" ou "lbxtoolkit.SaffeLogger"')
|
|
@@ -39,6 +55,10 @@ Gerencia a instalação e execução de um daemon como um serviço do windows. T
|
|
|
39
55
|
raise ValueError(f'Argumento "config" é mandatório e deve ser um dicionário contendo as chaves/valores para "name", "display_name" e "description"')
|
|
40
56
|
elif [chave for chave in self.config if self.config[chave] is None]:
|
|
41
57
|
raise ValueError(f'Argumento "config" ({self.config}) possui as seguintes chaves com valores inválidos [None]: {[chave for chave in self.config if self.config[chave] is None]:}')
|
|
58
|
+
elif self.raiz_projeto is None:
|
|
59
|
+
raise ValueError(f'Argumento "raiz_projeto" é mandatório e deve ser obtido usando "misc.encrontra_projeto_raiz" no módulo principal')
|
|
60
|
+
elif self.modulo is None:
|
|
61
|
+
raise ValueError(f'Argumento "modulo" é mandatório e deve ser obtido usando "misc.nome_modulo" no módulo principal')
|
|
42
62
|
|
|
43
63
|
self._svc_name_ = self.config['name']
|
|
44
64
|
self._svc_display_name_ = self.config['display_name']
|
|
@@ -61,9 +81,10 @@ Gerencia a instalação e execução de um daemon como um serviço do windows. T
|
|
|
61
81
|
|
|
62
82
|
log = ConfigManager.get('log')
|
|
63
83
|
daemon = ConfigManager.get('daemon')
|
|
64
|
-
config = ConfigManager.get('config')
|
|
65
|
-
|
|
66
|
-
|
|
84
|
+
config = ConfigManager.get('config')
|
|
85
|
+
raiz_projeto = ConfigManager.get('raiz_projeto')
|
|
86
|
+
modulo = ConfigManager.get('modulo')
|
|
87
|
+
|
|
67
88
|
if log is None or (not isinstance(log, lbx_logger) and not isinstance(log, SafeLogger)):
|
|
68
89
|
raise ValueError(f'Argumento "log" é mandatório e deve ser uma instância de "lbxtoolkit.lbx_logger" ou "lbxtoolkit.SaffeLogger"')
|
|
69
90
|
elif daemon is None or not hasattr(daemon, 'run') or not hasattr(daemon, 'stop'):
|
|
@@ -77,6 +98,33 @@ Gerencia a instalação e execução de um daemon como um serviço do windows. T
|
|
|
77
98
|
_svc_display_name_ = config['display_name']
|
|
78
99
|
_svc_description_ = config['description']
|
|
79
100
|
|
|
101
|
+
## para legado. suportar tanto a criação de execução direta do .py (originalmente) como por módulo
|
|
102
|
+
## a lógica é que raiz_projeto e modulo só sejam definidos se o projeto foi estrutura para execução por módulo/entrypoint (pythom -m ou poetry run).
|
|
103
|
+
# neste caso, é esperado que service_path e python_path sejam nulos
|
|
104
|
+
## por outro lado, se a execução for diretamente pelo script (python script.py), é esperado que raiz_projeto e modulo sejam nulos. se service_path e python_path forem nulos também, serão definidos arbitrariamente
|
|
105
|
+
if raiz_projeto and modulo: ## execução por módulo (novo)
|
|
106
|
+
service_path = None
|
|
107
|
+
python_path = None
|
|
108
|
+
wrapper = Path(raiz_projeto, f'wrapper_servico_{modulo}.bat') ## tem que ser igual a SvcRemove. Mudou lá, muda aqui.
|
|
109
|
+
wrapper_content = f"""
|
|
110
|
+
@echo off
|
|
111
|
+
REM ==================================================================================================================
|
|
112
|
+
REM !!!!NÃO TOQUE NESSE ARQUIVO. NÃO O APAQUE NEM O MODIFIQUE.!!!!
|
|
113
|
+
REM O serviço do windows [{config['display_name']}] que roda nesta máquina depende do conteúdo deste arquivo de lotes.
|
|
114
|
+
REM ==================================================================================================================
|
|
115
|
+
set PYTHONPATH=%~dp0
|
|
116
|
+
"%~dp0.venv\\Scripts\\python.exe" -m {modulo} %*
|
|
117
|
+
"""
|
|
118
|
+
with open(wrapper, "w", encoding="utf-8") as file:
|
|
119
|
+
file.write(wrapper_content)
|
|
120
|
+
service_cmd = f'{wrapper}'
|
|
121
|
+
|
|
122
|
+
else: ## execução direta do script (legado)
|
|
123
|
+
service_path = ConfigManager.get('service_path') if ConfigManager.get('service_path') else os.path.abspath(__file__)
|
|
124
|
+
python_path = ConfigManager.get('python_path') if ConfigManager.get('python_path') else os.path.join(os.getenv('VIRTUAL_ENV'), 'Scripts', 'python.exe') if os.getenv('VIRTUAL_ENV') else sys.executable
|
|
125
|
+
service_cmd = f'{python_path} {service_path}'
|
|
126
|
+
|
|
127
|
+
|
|
80
128
|
IP = socket.gethostbyname(socket.gethostname())
|
|
81
129
|
Host = socket.gethostname()
|
|
82
130
|
OS = platform.system()
|
|
@@ -98,19 +146,17 @@ Gerencia a instalação e execução de um daemon como um serviço do windows. T
|
|
|
98
146
|
if delete:
|
|
99
147
|
log.info(f'Excluindo serviço pre-existente [{_svc_display_name_} ({_svc_name_})] em {IP}/{Host}({Usuario}): {saida}')
|
|
100
148
|
# Create the service
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
]
|
|
113
|
-
, capture_output=True)
|
|
149
|
+
svc = [
|
|
150
|
+
'sc',
|
|
151
|
+
'create',
|
|
152
|
+
_svc_name_,
|
|
153
|
+
'binPath=',
|
|
154
|
+
f'{service_cmd}',
|
|
155
|
+
'DisplayName=',
|
|
156
|
+
_svc_display_name_,
|
|
157
|
+
'start=delayed-auto',
|
|
158
|
+
]
|
|
159
|
+
install = subprocess.run(svc, capture_output=True)
|
|
114
160
|
saida = install.stdout.decode('cp850').strip()
|
|
115
161
|
log.info(f'Criando novo serviço [{_svc_display_name_} ({_svc_name_})] em {IP}/{Host}({Usuario}): {saida}')
|
|
116
162
|
# Set the service description
|
|
@@ -138,7 +184,9 @@ Gerencia a instalação e execução de um daemon como um serviço do windows. T
|
|
|
138
184
|
|
|
139
185
|
log = ConfigManager.get('log')
|
|
140
186
|
daemon = ConfigManager.get('daemon')
|
|
141
|
-
config = ConfigManager.get('config')
|
|
187
|
+
config = ConfigManager.get('config')
|
|
188
|
+
raiz_projeto = ConfigManager.get('raiz_projeto')
|
|
189
|
+
modulo = ConfigManager.get('modulo')
|
|
142
190
|
|
|
143
191
|
if log is None or (not isinstance(log, lbx_logger) and not isinstance(log, SafeLogger)):
|
|
144
192
|
raise ValueError(f'Argumento "log" é mandatório e deve ser uma instância de "lbxtoolkit.lbx_logger" ou "lbxtoolkit.SaffeLogger"')
|
|
@@ -172,6 +220,11 @@ Gerencia a instalação e execução de um daemon como um serviço do windows. T
|
|
|
172
220
|
saida = delete.stdout.decode('cp850').strip()
|
|
173
221
|
if delete:
|
|
174
222
|
log.info(f'Excluindo serviço pre-existente [{_svc_display_name_} ({_svc_name_})] em {IP}/{Host}({Usuario}): {saida}')
|
|
223
|
+
if raiz_projeto and modulo: ## execução por módulo (novo)
|
|
224
|
+
wrapper = Path(raiz_projeto, f'wrapper_servico_{modulo}.bat') ## tem que ser igual a SvcInstall. Mudou lá, muda aqui.
|
|
225
|
+
if wrapper.exists():
|
|
226
|
+
wrapper.unlink()
|
|
227
|
+
|
|
175
228
|
except Exception as Err:
|
|
176
229
|
log.erro(f'Falha ao tentar excluir o serviço [{_svc_display_name_} ({_svc_name_})]')
|
|
177
230
|
raise
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "lbxtoolkit"
|
|
3
|
+
version = "2.3.0"
|
|
4
|
+
description = ""
|
|
5
|
+
authors = ["Cristiano P. Ferrari <cristiano.ferrari@lbx.com.br>"]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
|
|
8
|
+
[tool.poetry.dependencies]
|
|
9
|
+
python = ">=3.12,<4.0"
|
|
10
|
+
psutil = ">=6.0.0"
|
|
11
|
+
psycopg2 = ">=2.9.9"
|
|
12
|
+
pandas = ">=2.2.2"
|
|
13
|
+
numpy = ">=2.0.1"
|
|
14
|
+
msal = ">=1.30.0"
|
|
15
|
+
requests = ">=2.32.3"
|
|
16
|
+
selenium = ">=4.23.1"
|
|
17
|
+
webdriver-manager = ">=4.0.2"
|
|
18
|
+
validators = ">=0.33.0"
|
|
19
|
+
pygetwindow = ">=0.0.9"
|
|
20
|
+
pywin32 = ">=306"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
[tool.poetry.group.docs.dependencies]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
[tool.poetry.group.dev.dependencies]
|
|
27
|
+
pydoc-markdown = ">=4.8.2"
|
|
28
|
+
|
|
29
|
+
[build-system]
|
|
30
|
+
requires = ["poetry-core"]
|
|
31
|
+
build-backend = "poetry.core.masonry.api"
|
lbxtoolkit-2.2.13/pyproject.toml
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
[tool.poetry]
|
|
2
|
-
name = "lbxtoolkit"
|
|
3
|
-
version = "2.2.13"
|
|
4
|
-
description = ""
|
|
5
|
-
authors = ["Cristiano P. Ferrari <cristiano.ferrari@lbx.com.br>"]
|
|
6
|
-
readme = "README.md"
|
|
7
|
-
|
|
8
|
-
[tool.poetry.dependencies]
|
|
9
|
-
python = "^3.12"
|
|
10
|
-
psutil = "^6.0.0"
|
|
11
|
-
psycopg2 = "^2.9.9"
|
|
12
|
-
pandas = "^2.2.2"
|
|
13
|
-
numpy = "^2.0.1"
|
|
14
|
-
msal = "^1.30.0"
|
|
15
|
-
requests = "^2.32.3"
|
|
16
|
-
selenium = "^4.23.1"
|
|
17
|
-
webdriver-manager = "^4.0.2"
|
|
18
|
-
validators = "^0.33.0"
|
|
19
|
-
pygetwindow = "^0.0.9"
|
|
20
|
-
pywin32 = "^306"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
[tool.poetry.group.docs.dependencies]
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
[tool.poetry.group.dev.dependencies]
|
|
27
|
-
pydoc-markdown = "^4.8.2"
|
|
28
|
-
|
|
29
|
-
[build-system]
|
|
30
|
-
requires = ["poetry-core"]
|
|
31
|
-
build-backend = "poetry.core.masonry.api"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|