csc-cia-stne 0.0.25__tar.gz → 0.0.26__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.
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/PKG-INFO +1 -1
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/pyproject.toml +1 -1
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/__init__.py +3 -1
- csc_cia_stne-0.0.26/src/csc_cia_stne/email.py +142 -0
- csc_cia_stne-0.0.26/src/csc_cia_stne/gcp_bigquery.py +314 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne.egg-info/PKG-INFO +1 -1
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne.egg-info/SOURCES.txt +1 -0
- csc_cia_stne-0.0.25/src/csc_cia_stne/gcp_bigquery.py +0 -182
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/LICENCE +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/README.md +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/README_PYPI.md +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/setup.cfg +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/bc_correios.py +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/bc_sta.py +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/karavela.py +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/logger_json.py +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/logger_rich.py +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/servicenow.py +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/stne_admin.py +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/utilitarios/__init__.py +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/utilitarios/functions/__init__.py +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/utilitarios/functions/func_b64.py +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/utilitarios/functions/func_converters.py +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/utilitarios/functions/func_recriar_pastas.py +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/utilitarios/functions/func_titulo.py +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne.egg-info/dependency_links.txt +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne.egg-info/requires.txt +0 -0
- {csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne.egg-info/top_level.txt +0 -0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "csc_cia_stne"
|
7
|
-
version = "0.0.
|
7
|
+
version = "0.0.26"
|
8
8
|
license = { text = "MIT" }
|
9
9
|
description = "Biblioteca do time CSC-CIA utilizada no desenvolvimento de RPAs"
|
10
10
|
keywords = ["karavela", "csc", "cia", "stone", "rpa"]
|
@@ -15,6 +15,7 @@ from .stne_admin import StoneAdmin
|
|
15
15
|
from .bc_sta import BC_STA
|
16
16
|
from .bc_correios import BC_Correios
|
17
17
|
from .gcp_bigquery import BigQuery
|
18
|
+
from .email import Email
|
18
19
|
#from .utilitarios.functions import titulo
|
19
20
|
# Define os itens disponíveis para importação
|
20
21
|
__all__ = [
|
@@ -25,5 +26,6 @@ __all__ = [
|
|
25
26
|
"StoneAdmin",
|
26
27
|
"ServiceNow",
|
27
28
|
"Util",
|
28
|
-
"logger"
|
29
|
+
"logger",
|
30
|
+
"Email"
|
29
31
|
]
|
@@ -0,0 +1,142 @@
|
|
1
|
+
import smtplib
|
2
|
+
from email.mime.multipart import MIMEMultipart
|
3
|
+
from email.mime.text import MIMEText
|
4
|
+
from email.mime.base import MIMEBase
|
5
|
+
from email import encoders
|
6
|
+
from pydantic import BaseModel, ValidationError, field_validator
|
7
|
+
|
8
|
+
class InitParamsValidator(BaseModel):
|
9
|
+
email_sender: str
|
10
|
+
email_password: str
|
11
|
+
|
12
|
+
@field_validator('email_sender','email_password')
|
13
|
+
def check_str_input(cls, value, info):
|
14
|
+
if not isinstance(value, str) or not value.strip():
|
15
|
+
raise ValueError(f"O campo '{info.field_name}' deve ser strings e não {type(value)}")
|
16
|
+
return value
|
17
|
+
|
18
|
+
class SendEmailParamsValidator(BaseModel):
|
19
|
+
|
20
|
+
to: list
|
21
|
+
message: str
|
22
|
+
title: str
|
23
|
+
reply_to:str
|
24
|
+
attachments: list = []
|
25
|
+
cc: list = []
|
26
|
+
cco: list = []
|
27
|
+
|
28
|
+
@field_validator('message','title','reply_to')
|
29
|
+
def check_str_input(cls, value, info):
|
30
|
+
if not isinstance(value, str) or not value.strip():
|
31
|
+
raise ValueError(f"O campo '{info.field_name}' deve ser strings e não {type(value)}")
|
32
|
+
return value
|
33
|
+
|
34
|
+
@field_validator('to','attachments','cc','cco')
|
35
|
+
def check_list_input(cls, value, info):
|
36
|
+
if not isinstance(value, list):
|
37
|
+
raise ValueError(f"O parametro '{info.field_name}' deve ser uma lista")
|
38
|
+
|
39
|
+
return value
|
40
|
+
|
41
|
+
class Email():
|
42
|
+
|
43
|
+
def __init__(self, email_sender, email_password):
|
44
|
+
|
45
|
+
self.email_sender = email_sender
|
46
|
+
self.email_password = email_password
|
47
|
+
|
48
|
+
try:
|
49
|
+
|
50
|
+
InitParamsValidator(email_sender=email_sender, email_password=email_password)
|
51
|
+
|
52
|
+
except ValidationError as e:
|
53
|
+
|
54
|
+
raise ValueError("Erro na validação dos dados de input da inicialização da instância:", e.errors())
|
55
|
+
|
56
|
+
|
57
|
+
self.server = self.login_email()
|
58
|
+
|
59
|
+
if not isinstance(self.server, smtplib.SMTP) and 'status' in self.server and not self.server['status']:
|
60
|
+
|
61
|
+
raise ValueError("Erro na validação dos dados de input da inicialização da instância:", self.server['error'])
|
62
|
+
|
63
|
+
|
64
|
+
def login_email(self):
|
65
|
+
|
66
|
+
try:
|
67
|
+
|
68
|
+
server = smtplib.SMTP('smtp.gmail.com', 587)
|
69
|
+
server.starttls()
|
70
|
+
server.login(self.email_sender, self.email_password)
|
71
|
+
|
72
|
+
return server
|
73
|
+
|
74
|
+
except Exception as e:
|
75
|
+
|
76
|
+
return {
|
77
|
+
'status':False,
|
78
|
+
'error':str(e)
|
79
|
+
}
|
80
|
+
|
81
|
+
|
82
|
+
def send_email( self, to : list , message : str , title : str , reply_to: str, attachments : list = [] , cc : list = [] , cco : list = [] ) -> dict:
|
83
|
+
|
84
|
+
try:
|
85
|
+
|
86
|
+
SendEmailParamsValidator(to=to, message=message, title=title, reply_to=reply_to, attachments=attachments, cc=cc, cco=cco)
|
87
|
+
|
88
|
+
except ValidationError as e:
|
89
|
+
|
90
|
+
raise ValueError("Erro na validação dos dados para o envio do email:", e.errors())
|
91
|
+
|
92
|
+
try:
|
93
|
+
|
94
|
+
msg = MIMEMultipart()
|
95
|
+
|
96
|
+
msg["From"] = self.email_sender
|
97
|
+
|
98
|
+
msg["To"] = (",").join(to)
|
99
|
+
|
100
|
+
msg["cc"] = (",").join(cc)
|
101
|
+
|
102
|
+
msg['Reply-To'] = reply_to
|
103
|
+
|
104
|
+
msg["Subject"] = title
|
105
|
+
|
106
|
+
for file in attachments:
|
107
|
+
|
108
|
+
try:
|
109
|
+
|
110
|
+
attachment = open(file, "rb")
|
111
|
+
|
112
|
+
part = MIMEBase("application", "octet-stream")
|
113
|
+
|
114
|
+
part.set_payload(attachment.read())
|
115
|
+
|
116
|
+
encoders.encode_base64(part)
|
117
|
+
|
118
|
+
part.add_header("Content-Disposition", f"attachment; filename={file.split('/')[-1]}")
|
119
|
+
|
120
|
+
msg.attach(part)
|
121
|
+
|
122
|
+
attachment.close()
|
123
|
+
|
124
|
+
except Exception as e:
|
125
|
+
|
126
|
+
return {
|
127
|
+
'status':False,
|
128
|
+
'error':str(e)
|
129
|
+
}
|
130
|
+
|
131
|
+
msg.attach(MIMEText(message))
|
132
|
+
|
133
|
+
self.server.sendmail(self.email_sender, to + cc + cco, msg.as_string())
|
134
|
+
|
135
|
+
return True
|
136
|
+
|
137
|
+
except Exception as e:
|
138
|
+
|
139
|
+
return {
|
140
|
+
'status':False,
|
141
|
+
'error':str(e)
|
142
|
+
}
|
@@ -0,0 +1,314 @@
|
|
1
|
+
from google.cloud import bigquery
|
2
|
+
import json
|
3
|
+
import os
|
4
|
+
from google.oauth2 import service_account
|
5
|
+
from pydantic import BaseModel, ValidationError, field_validator,model_validator
|
6
|
+
|
7
|
+
class InitParamsValidator(BaseModel):
|
8
|
+
limit:int
|
9
|
+
id_project:str
|
10
|
+
creds_dict:dict
|
11
|
+
creds_file:str
|
12
|
+
|
13
|
+
@field_validator('limit')
|
14
|
+
def check_input_basic(cls, value, info):
|
15
|
+
if not isinstance(value, int):
|
16
|
+
raise ValueError(f"O parametro 'limit' deve ser um inteiro e não um {type(value)}")
|
17
|
+
|
18
|
+
return value
|
19
|
+
|
20
|
+
@field_validator('id_project')
|
21
|
+
def check_str_input(cls, value, info):
|
22
|
+
if not isinstance(value, str) or not value.strip():
|
23
|
+
raise ValueError(f"O parametro 'id_project' deve ser uma string e não um {type(value)} e não vazio")
|
24
|
+
return value
|
25
|
+
|
26
|
+
@model_validator(mode="after")
|
27
|
+
def check_others_input(cls, model):
|
28
|
+
creds_dict = model.creds_dict
|
29
|
+
creds_file = model.creds_file
|
30
|
+
|
31
|
+
if isinstance(creds_dict, dict):
|
32
|
+
return model
|
33
|
+
|
34
|
+
elif isinstance(creds_file, str) and creds_file.strip():
|
35
|
+
return model
|
36
|
+
|
37
|
+
else:
|
38
|
+
raise ValueError("Pelo menos um dos parâmetros 'creds_dict' ou 'creds_file' deve ser fornecido.")
|
39
|
+
|
40
|
+
|
41
|
+
class tryQueryValidator(BaseModel):
|
42
|
+
|
43
|
+
query_to_execute:str
|
44
|
+
organize:bool
|
45
|
+
use_legacy:bool
|
46
|
+
use_cache:bool
|
47
|
+
query_parameters:list
|
48
|
+
|
49
|
+
@field_validator('query_to_execute')
|
50
|
+
def check_str_input(cls, value, info):
|
51
|
+
if not isinstance(value, str) or not value.strip():
|
52
|
+
raise ValueError(f"O parametro '{info.field_name}' deve ser uma string não vazia")
|
53
|
+
|
54
|
+
return value
|
55
|
+
|
56
|
+
@field_validator('organize','use_legacy','use_cache')
|
57
|
+
def check_bool_input(cls, value, info):
|
58
|
+
if not isinstance(value, bool):
|
59
|
+
raise ValueError(f"O parametro '{info.field_name}' deve ser um boleano")
|
60
|
+
|
61
|
+
return value
|
62
|
+
|
63
|
+
@field_validator('query_parameters')
|
64
|
+
def check_list_input(cls, value, info):
|
65
|
+
if not isinstance(value, list):
|
66
|
+
raise ValueError(f"O parametro '{info.field_name}' deve ser uma lista")
|
67
|
+
|
68
|
+
return value
|
69
|
+
|
70
|
+
|
71
|
+
class tryInsertListValidator(BaseModel):
|
72
|
+
|
73
|
+
insert_limit:int
|
74
|
+
list_to_insert:list
|
75
|
+
table:str
|
76
|
+
|
77
|
+
@field_validator('list_to_insert')
|
78
|
+
def check_list_input(cls, value, info):
|
79
|
+
if not isinstance(value, list) and len(value) > 0:
|
80
|
+
raise ValueError(f"O parametro '{info.field_name}' deve ser uma lista e não estar vazia")
|
81
|
+
|
82
|
+
return value
|
83
|
+
|
84
|
+
@field_validator('table')
|
85
|
+
def check_str_input(cls, value, info):
|
86
|
+
if not isinstance(value, str) or not value.strip():
|
87
|
+
raise ValueError(f"O parametro '{info.field_name}' deve ser uma string não vazia")
|
88
|
+
|
89
|
+
return value
|
90
|
+
|
91
|
+
@field_validator('insert_limit')
|
92
|
+
def check_int_input(cls, value, info):
|
93
|
+
if not isinstance(value, int) or value > 10000:
|
94
|
+
raise ValueError(f"O parametro '{info.field_name}' deve ser um inteiro não maior que 10000")
|
95
|
+
|
96
|
+
return value
|
97
|
+
|
98
|
+
class BigQuery():
|
99
|
+
|
100
|
+
|
101
|
+
def __init__(self, id_project: str, creds_dict: dict = None, creds_file: str = "", limit: int = 3):
|
102
|
+
|
103
|
+
"""
|
104
|
+
Inicializa a classe BigQuery.
|
105
|
+
Parâmetros:
|
106
|
+
limit (int): O limite de resultados a serem retornados. O valor padrão é 3.
|
107
|
+
client (bigquery.Client): O cliente BigQuery a ser utilizado.
|
108
|
+
"""
|
109
|
+
|
110
|
+
self.limit = limit
|
111
|
+
self.id_project = id_project
|
112
|
+
self.creds_dict = creds_dict
|
113
|
+
self.creds_file = creds_file
|
114
|
+
self.client = self.create_client()
|
115
|
+
|
116
|
+
try:
|
117
|
+
|
118
|
+
InitParamsValidator(limit=limit, id_project=id_project, creds_dict=creds_dict, creds_file=creds_file)
|
119
|
+
|
120
|
+
except ValidationError as e:
|
121
|
+
|
122
|
+
raise ValueError("Erro na validação dos dados de input da inicialização da instância:", e.errors())
|
123
|
+
|
124
|
+
|
125
|
+
def create_client(self) -> bigquery.Client:
|
126
|
+
"""
|
127
|
+
Cria um cliente BigQuery com base nas credenciais fornecidas.
|
128
|
+
Parâmetros:
|
129
|
+
- creds_dict (dict): Dicionário contendo as informações das credenciais. Opcional se creds_file for fornecido.
|
130
|
+
- creds_file (str): Caminho do arquivo de credenciais. Opcional se creds_dict for fornecido.
|
131
|
+
- id_project (str): ID do projeto BigQuery.
|
132
|
+
Retorna:
|
133
|
+
- client (bigquery.Client): Cliente BigQuery criado com base nas credenciais fornecidas.
|
134
|
+
Exceções:
|
135
|
+
- Retorna um dicionário com as seguintes chaves em caso de erro:
|
136
|
+
- 'status' (bool): False
|
137
|
+
- 'error' (str): Mensagem de erro
|
138
|
+
- 'details' (str): Detalhes do erro
|
139
|
+
"""
|
140
|
+
|
141
|
+
try:
|
142
|
+
|
143
|
+
if(self.creds_dict is not None):
|
144
|
+
|
145
|
+
credentials = service_account.Credentials.from_service_account_info(
|
146
|
+
self.creds_dict,
|
147
|
+
scopes=["https://www.googleapis.com/auth/cloud-platform"],
|
148
|
+
)
|
149
|
+
|
150
|
+
client = bigquery.Client(credentials=credentials, project=self.id_project)
|
151
|
+
|
152
|
+
elif(str(self.creds_file) > 0):
|
153
|
+
|
154
|
+
credentials = service_account.Credentials.from_service_account_file(
|
155
|
+
self.creds_file,
|
156
|
+
scopes=["https://www.googleapis.com/auth/cloud-platform"],
|
157
|
+
)
|
158
|
+
|
159
|
+
else:
|
160
|
+
|
161
|
+
return {
|
162
|
+
'status':False,
|
163
|
+
'error':"Credenciais não fornecidas"
|
164
|
+
}
|
165
|
+
|
166
|
+
return client
|
167
|
+
|
168
|
+
except Exception as e:
|
169
|
+
|
170
|
+
return {
|
171
|
+
'status':False,
|
172
|
+
'error':'Problema ao tentar gerar o client do big query',
|
173
|
+
'details':str(e)
|
174
|
+
}
|
175
|
+
|
176
|
+
|
177
|
+
def try_query(self, query_to_execute: str, organize: bool = False, use_legacy: bool = False, use_cache: bool = False, query_parameters: list = []) -> dict:
|
178
|
+
|
179
|
+
"""
|
180
|
+
Executa uma consulta no BigQuery e retorna o resultado.
|
181
|
+
Args:
|
182
|
+
query_to_execute (str): A consulta a ser executada.
|
183
|
+
organize (bool, optional): Indica se o resultado deve ser organizado em um formato específico.
|
184
|
+
O padrão é True.
|
185
|
+
Returns:
|
186
|
+
dict: Um dicionário contendo o status da consulta e o resultado, se houver.
|
187
|
+
Exemplo:
|
188
|
+
{
|
189
|
+
'status': True,
|
190
|
+
'resultado': result_query
|
191
|
+
Se ocorrer um erro durante a execução da consulta, o dicionário de retorno terá o seguinte formato:
|
192
|
+
{
|
193
|
+
'status': False,
|
194
|
+
"""
|
195
|
+
|
196
|
+
try:
|
197
|
+
|
198
|
+
tryQueryValidator(query_to_execute=query_to_execute, organize=organize, use_legacy=use_legacy, use_cache=use_cache, query_parameters=query_parameters)
|
199
|
+
|
200
|
+
except ValidationError as e:
|
201
|
+
|
202
|
+
raise ValueError("Erro na validação dos dados de input da função para tentar executar a query:", e.errors())
|
203
|
+
|
204
|
+
error = ""
|
205
|
+
|
206
|
+
for try_out in range(self.limit):
|
207
|
+
|
208
|
+
try:
|
209
|
+
|
210
|
+
job_config = bigquery.QueryJobConfig(
|
211
|
+
priority=bigquery.QueryPriority.INTERACTIVE,
|
212
|
+
use_legacy_sql=use_legacy,
|
213
|
+
use_query_cache=use_cache,
|
214
|
+
query_parameters=query_parameters,
|
215
|
+
)
|
216
|
+
|
217
|
+
result_query = self.client.query(query_to_execute,job_config=job_config).result()
|
218
|
+
|
219
|
+
error = False
|
220
|
+
|
221
|
+
if organize:
|
222
|
+
|
223
|
+
result_rows = [dict(row) for row in result_query['resultado']]
|
224
|
+
|
225
|
+
result_query = result_rows
|
226
|
+
|
227
|
+
break
|
228
|
+
|
229
|
+
except Exception as e:
|
230
|
+
|
231
|
+
error = e
|
232
|
+
|
233
|
+
if not error:
|
234
|
+
|
235
|
+
return {
|
236
|
+
'status':True,
|
237
|
+
'resultado':result_query
|
238
|
+
}
|
239
|
+
|
240
|
+
else:
|
241
|
+
|
242
|
+
return {
|
243
|
+
'status':False,
|
244
|
+
'error': str(error)
|
245
|
+
}
|
246
|
+
|
247
|
+
|
248
|
+
def insert_list(self, table: str, list_to_insert: list = [], insert_limit: int = 10000) -> dict:
|
249
|
+
|
250
|
+
"""
|
251
|
+
Insere uma lista de dicionários em uma tabela do BigQuery.
|
252
|
+
Args:
|
253
|
+
client (bigquery.Client): Cliente do BigQuery.
|
254
|
+
table (str): Nome da tabela onde os dados serão inseridos.
|
255
|
+
list_to_insert (dict, optional): Lista de dicionários a serem inseridos. O padrão é [].
|
256
|
+
limit_trys (int, optional): Número máximo de tentativas de inserção. O padrão é 3.
|
257
|
+
Returns:
|
258
|
+
dict: Dicionário contendo o status da inserção e informações adicionais.
|
259
|
+
- Se a inserção for bem-sucedida:
|
260
|
+
{'status': True, 'inserted': inserted}
|
261
|
+
- Se ocorrer um erro durante a inserção:
|
262
|
+
{'status': False, 'error': error, 'last_try': list_to_insert, 'inserted': inserted}
|
263
|
+
"""
|
264
|
+
|
265
|
+
try:
|
266
|
+
|
267
|
+
tryInsertListValidator(table=table, list_to_insert=list_to_insert, insert_limit=insert_limit)
|
268
|
+
|
269
|
+
except ValidationError as e:
|
270
|
+
|
271
|
+
raise ValueError("Erro na validação dos dados de input da função para tentar inserir dados em uma tabela:", e.errors())
|
272
|
+
|
273
|
+
table_ref = self.client.get_table(table)
|
274
|
+
|
275
|
+
error = ""
|
276
|
+
|
277
|
+
inserted = []
|
278
|
+
|
279
|
+
for data in range(0, len(list_to_insert), insert_limit):
|
280
|
+
|
281
|
+
# listagem que será inserida no big query
|
282
|
+
list_to_insert = list_to_insert[data:data+10000]
|
283
|
+
|
284
|
+
for try_out in range(self.limit):
|
285
|
+
|
286
|
+
try:
|
287
|
+
|
288
|
+
self.client.insert_rows(table_ref, list_to_insert)
|
289
|
+
|
290
|
+
error = False
|
291
|
+
|
292
|
+
except Exception as e:
|
293
|
+
|
294
|
+
error = e
|
295
|
+
|
296
|
+
if not error:
|
297
|
+
|
298
|
+
inserted.extend(list_to_insert)
|
299
|
+
|
300
|
+
continue
|
301
|
+
|
302
|
+
else:
|
303
|
+
|
304
|
+
return{
|
305
|
+
'status':False,
|
306
|
+
'error':str(error),
|
307
|
+
'last_try':list_to_insert,
|
308
|
+
'inserted':inserted
|
309
|
+
}
|
310
|
+
|
311
|
+
return {
|
312
|
+
'status':True,
|
313
|
+
'inserted':inserted
|
314
|
+
}
|
@@ -1,182 +0,0 @@
|
|
1
|
-
from google.cloud import bigquery
|
2
|
-
import json
|
3
|
-
import os
|
4
|
-
from google.oauth2 import service_account
|
5
|
-
|
6
|
-
class BigQuery():
|
7
|
-
|
8
|
-
def __init__(self, client: bigquery.Client, limit: int = 3):
|
9
|
-
"""
|
10
|
-
Inicializa a classe BigQuery.
|
11
|
-
Parâmetros:
|
12
|
-
limit (int): O limite de resultados a serem retornados. O valor padrão é 3.
|
13
|
-
client (bigquery.Client): O cliente BigQuery a ser utilizado.
|
14
|
-
"""
|
15
|
-
|
16
|
-
self.limit = limit
|
17
|
-
self.client = client
|
18
|
-
|
19
|
-
def create_client(id_project: str, creds_dict: dict = None, creds_file: str = "") -> bigquery.Client:
|
20
|
-
"""
|
21
|
-
Cria um cliente BigQuery com base nas credenciais fornecidas.
|
22
|
-
Parâmetros:
|
23
|
-
- creds_dict (dict): Dicionário contendo as informações das credenciais. Opcional se creds_file for fornecido.
|
24
|
-
- creds_file (str): Caminho do arquivo de credenciais. Opcional se creds_dict for fornecido.
|
25
|
-
- id_project (str): ID do projeto BigQuery.
|
26
|
-
Retorna:
|
27
|
-
- client (bigquery.Client): Cliente BigQuery criado com base nas credenciais fornecidas.
|
28
|
-
Exceções:
|
29
|
-
- Retorna um dicionário com as seguintes chaves em caso de erro:
|
30
|
-
- 'status' (bool): False
|
31
|
-
- 'error' (str): Mensagem de erro
|
32
|
-
- 'details' (str): Detalhes do erro
|
33
|
-
"""
|
34
|
-
|
35
|
-
try:
|
36
|
-
|
37
|
-
if(creds_dict is not None):
|
38
|
-
|
39
|
-
credentials = service_account.Credentials.from_service_account_info(
|
40
|
-
creds_dict,
|
41
|
-
scopes=["https://www.googleapis.com/auth/cloud-platform"],
|
42
|
-
)
|
43
|
-
|
44
|
-
client = bigquery.Client(credentials=credentials, project=id_project)
|
45
|
-
|
46
|
-
elif(str(creds_file) > 0):
|
47
|
-
|
48
|
-
credentials = service_account.Credentials.from_service_account_file(
|
49
|
-
creds_file,
|
50
|
-
scopes=["https://www.googleapis.com/auth/cloud-platform"],
|
51
|
-
)
|
52
|
-
|
53
|
-
else:
|
54
|
-
|
55
|
-
return {
|
56
|
-
'status':False,
|
57
|
-
'error':"Credenciais não fornecidas"
|
58
|
-
}
|
59
|
-
|
60
|
-
return client
|
61
|
-
|
62
|
-
except Exception as e:
|
63
|
-
|
64
|
-
return {
|
65
|
-
'status':False,
|
66
|
-
'error':'Problema ao tentar gerar o client do big query',
|
67
|
-
'details':str(e)
|
68
|
-
}
|
69
|
-
|
70
|
-
def try_query(self, query_to_execute:str,organize:bool=True) -> dict:
|
71
|
-
"""
|
72
|
-
Executa uma consulta no BigQuery e retorna o resultado.
|
73
|
-
Args:
|
74
|
-
query_to_execute (str): A consulta a ser executada.
|
75
|
-
organize (bool, optional): Indica se o resultado deve ser organizado em um formato específico.
|
76
|
-
O padrão é True.
|
77
|
-
Returns:
|
78
|
-
dict: Um dicionário contendo o status da consulta e o resultado, se houver.
|
79
|
-
Exemplo:
|
80
|
-
{
|
81
|
-
'status': True,
|
82
|
-
'resultado': result_query
|
83
|
-
Se ocorrer um erro durante a execução da consulta, o dicionário de retorno terá o seguinte formato:
|
84
|
-
{
|
85
|
-
'status': False,
|
86
|
-
"""
|
87
|
-
|
88
|
-
error = ""
|
89
|
-
|
90
|
-
for try_out in range(self.limit):
|
91
|
-
|
92
|
-
try:
|
93
|
-
|
94
|
-
result_query = self.client.query(query_to_execute).result()
|
95
|
-
|
96
|
-
error = False
|
97
|
-
|
98
|
-
if organize:
|
99
|
-
|
100
|
-
result_rows = [dict(row) for row in result_query['resultado']]
|
101
|
-
|
102
|
-
result_query = result_rows
|
103
|
-
|
104
|
-
break
|
105
|
-
|
106
|
-
except Exception as e:
|
107
|
-
|
108
|
-
error = e
|
109
|
-
|
110
|
-
if not error:
|
111
|
-
|
112
|
-
return {
|
113
|
-
'status':True,
|
114
|
-
'resultado':result_query
|
115
|
-
}
|
116
|
-
|
117
|
-
else:
|
118
|
-
|
119
|
-
return {
|
120
|
-
'status':False,
|
121
|
-
'error': str(error)
|
122
|
-
}
|
123
|
-
|
124
|
-
def insert_list(self,table:str,dict_to_insert:dict=[]) -> dict:
|
125
|
-
|
126
|
-
"""
|
127
|
-
Insere uma lista de dicionários em uma tabela do BigQuery.
|
128
|
-
Args:
|
129
|
-
client (bigquery.Client): Cliente do BigQuery.
|
130
|
-
table (str): Nome da tabela onde os dados serão inseridos.
|
131
|
-
dict_to_insert (dict, optional): Lista de dicionários a serem inseridos. O padrão é [].
|
132
|
-
limit_trys (int, optional): Número máximo de tentativas de inserção. O padrão é 3.
|
133
|
-
Returns:
|
134
|
-
dict: Dicionário contendo o status da inserção e informações adicionais.
|
135
|
-
- Se a inserção for bem-sucedida:
|
136
|
-
{'status': True, 'inserted': inserted}
|
137
|
-
- Se ocorrer um erro durante a inserção:
|
138
|
-
{'status': False, 'error': error, 'last_try': list_to_insert, 'inserted': inserted}
|
139
|
-
"""
|
140
|
-
|
141
|
-
table_ref = self.client.get_table(table)
|
142
|
-
|
143
|
-
error = ""
|
144
|
-
|
145
|
-
inserted = []
|
146
|
-
|
147
|
-
for data in range(0, len(dict_to_insert), 10000):
|
148
|
-
|
149
|
-
# listagem que será inserida no big query
|
150
|
-
list_to_insert = dict_to_insert[data:data+10000]
|
151
|
-
|
152
|
-
for try_out in range(self.limit):
|
153
|
-
|
154
|
-
try:
|
155
|
-
|
156
|
-
self.client.insert_rows(table_ref, list_to_insert)
|
157
|
-
|
158
|
-
error = False
|
159
|
-
|
160
|
-
except Exception as e:
|
161
|
-
|
162
|
-
error = e
|
163
|
-
|
164
|
-
if not error:
|
165
|
-
|
166
|
-
inserted.extend(list_to_insert)
|
167
|
-
|
168
|
-
continue
|
169
|
-
|
170
|
-
else:
|
171
|
-
|
172
|
-
return{
|
173
|
-
'status':False,
|
174
|
-
'error':str(error),
|
175
|
-
'last_try':list_to_insert,
|
176
|
-
'inserted':inserted
|
177
|
-
}
|
178
|
-
|
179
|
-
return {
|
180
|
-
'status':True,
|
181
|
-
'inserted':inserted
|
182
|
-
}
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/utilitarios/functions/__init__.py
RENAMED
File without changes
|
{csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/utilitarios/functions/func_b64.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{csc_cia_stne-0.0.25 → csc_cia_stne-0.0.26}/src/csc_cia_stne/utilitarios/functions/func_titulo.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|