csc-cia-stne 0.0.24__py3-none-any.whl → 0.0.26__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.
csc_cia_stne/__init__.py CHANGED
@@ -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
  ]
csc_cia_stne/bc_sta.py CHANGED
@@ -1,10 +1,8 @@
1
1
  from requests.auth import HTTPBasicAuth
2
- import sys
3
- from pydantic import BaseModel
4
2
  import requests
5
3
  import xml.etree.ElementTree as ET
6
4
  import hashlib
7
- from pydantic import BaseModel, StrictStr, StrictInt, ValidationError, field_validator, FieldValidationInfo
5
+ from pydantic import BaseModel, ValidationError, field_validator
8
6
  from typing import Literal, Dict, Union, Optional
9
7
 
10
8
  # Validações dos inputs
csc_cia_stne/email.py ADDED
@@ -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
+ }
@@ -2,10 +2,104 @@ from google.cloud import bigquery
2
2
  import json
3
3
  import os
4
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
5
97
 
6
98
  class BigQuery():
7
99
 
8
- def __init__(self, client: bigquery.Client, limit: int = 3):
100
+
101
+ def __init__(self, id_project: str, creds_dict: dict = None, creds_file: str = "", limit: int = 3):
102
+
9
103
  """
10
104
  Inicializa a classe BigQuery.
11
105
  Parâmetros:
@@ -14,9 +108,21 @@ class BigQuery():
14
108
  """
15
109
 
16
110
  self.limit = limit
17
- self.client = client
111
+ self.id_project = id_project
112
+ self.creds_dict = creds_dict
113
+ self.creds_file = creds_file
114
+ self.client = self.create_client()
18
115
 
19
- def create_client(id_project: str, creds_dict: dict = None, creds_file: str = "") -> bigquery.Client:
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:
20
126
  """
21
127
  Cria um cliente BigQuery com base nas credenciais fornecidas.
22
128
  Parâmetros:
@@ -34,19 +140,19 @@ class BigQuery():
34
140
 
35
141
  try:
36
142
 
37
- if(creds_dict is not None):
143
+ if(self.creds_dict is not None):
38
144
 
39
145
  credentials = service_account.Credentials.from_service_account_info(
40
- creds_dict,
146
+ self.creds_dict,
41
147
  scopes=["https://www.googleapis.com/auth/cloud-platform"],
42
148
  )
43
149
 
44
- client = bigquery.Client(credentials=credentials, project=id_project)
150
+ client = bigquery.Client(credentials=credentials, project=self.id_project)
45
151
 
46
- elif(str(creds_file) > 0):
152
+ elif(str(self.creds_file) > 0):
47
153
 
48
154
  credentials = service_account.Credentials.from_service_account_file(
49
- creds_file,
155
+ self.creds_file,
50
156
  scopes=["https://www.googleapis.com/auth/cloud-platform"],
51
157
  )
52
158
 
@@ -67,7 +173,9 @@ class BigQuery():
67
173
  'details':str(e)
68
174
  }
69
175
 
70
- def try_query(self, query_to_execute:str,organize:bool=True) -> dict:
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
+
71
179
  """
72
180
  Executa uma consulta no BigQuery e retorna o resultado.
73
181
  Args:
@@ -85,13 +193,28 @@ class BigQuery():
85
193
  'status': False,
86
194
  """
87
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
+
88
204
  error = ""
89
205
 
90
206
  for try_out in range(self.limit):
91
207
 
92
208
  try:
93
209
 
94
- result_query = self.client.query(query_to_execute).result()
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()
95
218
 
96
219
  error = False
97
220
 
@@ -121,14 +244,15 @@ class BigQuery():
121
244
  'error': str(error)
122
245
  }
123
246
 
124
- def insert_list(self,table:str,dict_to_insert:dict=[]) -> dict:
247
+
248
+ def insert_list(self, table: str, list_to_insert: list = [], insert_limit: int = 10000) -> dict:
125
249
 
126
250
  """
127
251
  Insere uma lista de dicionários em uma tabela do BigQuery.
128
252
  Args:
129
253
  client (bigquery.Client): Cliente do BigQuery.
130
254
  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 é [].
255
+ list_to_insert (dict, optional): Lista de dicionários a serem inseridos. O padrão é [].
132
256
  limit_trys (int, optional): Número máximo de tentativas de inserção. O padrão é 3.
133
257
  Returns:
134
258
  dict: Dicionário contendo o status da inserção e informações adicionais.
@@ -138,16 +262,24 @@ class BigQuery():
138
262
  {'status': False, 'error': error, 'last_try': list_to_insert, 'inserted': inserted}
139
263
  """
140
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
+
141
273
  table_ref = self.client.get_table(table)
142
274
 
143
275
  error = ""
144
276
 
145
277
  inserted = []
146
278
 
147
- for data in range(0, len(dict_to_insert), 10000):
279
+ for data in range(0, len(list_to_insert), insert_limit):
148
280
 
149
281
  # listagem que será inserida no big query
150
- list_to_insert = dict_to_insert[data:data+10000]
282
+ list_to_insert = list_to_insert[data:data+10000]
151
283
 
152
284
  for try_out in range(self.limit):
153
285
 
@@ -97,7 +97,8 @@ def add_log_level(level_name, level_num, method_name=None):
97
97
 
98
98
  if self.isEnabledFor(level_num):
99
99
 
100
- self._log(level_num, message, args, **kwargs)
100
+ #self._log(level_num, message, args, **kwargs)
101
+ self._log(level_num, message, args, **{**kwargs, "stacklevel": 2})
101
102
 
102
103
  def log_to_root(message, *args, **kwargs):
103
104
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: csc_cia_stne
3
- Version: 0.0.24
3
+ Version: 0.0.26
4
4
  Summary: Biblioteca do time CSC-CIA utilizada no desenvolvimento de RPAs
5
5
  License: MIT
6
6
  Keywords: karavela,csc,cia,stone,rpa
@@ -10,7 +10,7 @@ Requires-Dist: python-json-logger
10
10
  Requires-Dist: rich
11
11
  Requires-Dist: requests
12
12
  Requires-Dist: pydantic
13
- Requires-Dist: pydantic-settings
13
+ Requires-Dist: pydantic_settings
14
14
  Requires-Dist: zeep
15
15
  Requires-Dist: google-cloud-bigquery
16
16
  Requires-Dist: google-cloud-storage
@@ -1,10 +1,11 @@
1
- csc_cia_stne/__init__.py,sha256=IYTgLq8P6SHJM4EcpD91iex1u_hAuQ3-thxIlLQ91R4,720
1
+ csc_cia_stne/__init__.py,sha256=xTOb4_9Z6FrZqXGT1zIjtgVady-GO5IwnddAaaV_gj0,758
2
2
  csc_cia_stne/bc_correios.py,sha256=ANsvLyL7wdkM0MvjjBHB2Ih4eyTcyWgt5IqiK0Rv89E,23014
3
- csc_cia_stne/bc_sta.py,sha256=I9N29wjTbd4ZmoM2yIW-xp3X-dMENZdSb0JhapfCegY,10988
4
- csc_cia_stne/gcp_bigquery.py,sha256=f8UEQgr6XyFacYX0bRq4UDmWoH-0XqZF8fA2LsLTtAU,5654
3
+ csc_cia_stne/bc_sta.py,sha256=uyoCp-KTpkWwpyWNWp20JuDfMRYGCKxERnRQVso80iQ,10903
4
+ csc_cia_stne/email.py,sha256=TGh4JrEPLcGV0djBxQf7yaCbQFRqXHGiHJfk1jTwzJo,4152
5
+ csc_cia_stne/gcp_bigquery.py,sha256=U-m0vPmnzzVDFonY9YrDnB-93E-fSpzNO1JjGDSB7dY,10190
5
6
  csc_cia_stne/karavela.py,sha256=Q7MbQXXz_jtrLHM7QeenbSzcro07EpoFk4lKglivJ_I,3564
6
7
  csc_cia_stne/logger_json.py,sha256=2G0rm0lyCtHn4o2v7fzn4wMylb0A_nbxiQatnrSZxHs,1212
7
- csc_cia_stne/logger_rich.py,sha256=yW1py7k5yY5Fay5I_eY-ulMGGSmFGGhUl3Q4U8aczbo,3392
8
+ csc_cia_stne/logger_rich.py,sha256=WcfmdbsQuVfz_lbZ1v1wtrGspaESu-PdQthyuLkKQjM,3472
8
9
  csc_cia_stne/servicenow.py,sha256=vSsNSANFyCZtDu2O7YmdoCbr-_bO1sgMWnOI29mFBOA,23311
9
10
  csc_cia_stne/stne_admin.py,sha256=G5ozXt18VjKL2BHtROQk4GnfVY1xM14RXSQ-rra_D54,15487
10
11
  csc_cia_stne/utilitarios/__init__.py,sha256=4YFhzxu8F_CDHU6iaNhpzz9mfX-8wfJc1XEQInJzwJ4,98
@@ -13,8 +14,8 @@ csc_cia_stne/utilitarios/functions/func_b64.py,sha256=XGU34BIQQXWXBS0yM2B4A2wDlc
13
14
  csc_cia_stne/utilitarios/functions/func_converters.py,sha256=EY1zvlBaRX7G1MceVSiRXwwKDQDZwUO9iECBL0fe5iU,481
14
15
  csc_cia_stne/utilitarios/functions/func_recriar_pastas.py,sha256=2_unoSoQHxShcMw_0XIL9F0NgiF1QCKsX4drvg0fEb8,415
15
16
  csc_cia_stne/utilitarios/functions/func_titulo.py,sha256=EhUtsiIOAz4yERNZl3EOHjiFLjj4rK3pr_KB0DxwGIA,3943
16
- csc_cia_stne-0.0.24.dist-info/LICENCE,sha256=LPGMtgKki2C3KEZP7hDhA1HBrlq5JCHkIeStUCLEMx4,1073
17
- csc_cia_stne-0.0.24.dist-info/METADATA,sha256=CiP_W79ifwOjgz6TbKMAVpl0BczsgxhdNQqpZN2G-ow,1003
18
- csc_cia_stne-0.0.24.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
19
- csc_cia_stne-0.0.24.dist-info/top_level.txt,sha256=ldo7GVv3tQx5KJvwBzdZzzQmjPys2NDVVn1rv0BOF2Q,13
20
- csc_cia_stne-0.0.24.dist-info/RECORD,,
17
+ csc_cia_stne-0.0.26.dist-info/LICENCE,sha256=LPGMtgKki2C3KEZP7hDhA1HBrlq5JCHkIeStUCLEMx4,1073
18
+ csc_cia_stne-0.0.26.dist-info/METADATA,sha256=NRg5PPo6abhue9hU873kKPDiKmJSoJ4d2i5l21ALE4w,1003
19
+ csc_cia_stne-0.0.26.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
20
+ csc_cia_stne-0.0.26.dist-info/top_level.txt,sha256=ldo7GVv3tQx5KJvwBzdZzzQmjPys2NDVVn1rv0BOF2Q,13
21
+ csc_cia_stne-0.0.26.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.3.0)
2
+ Generator: setuptools (75.6.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5