csc-cia-stne 0.1.28__py3-none-any.whl → 0.1.30__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 +2 -0
- csc_cia_stne/gcp_document_ai.py +100 -0
- csc_cia_stne/utilitarios/functions/__init__.py +3 -0
- csc_cia_stne/utilitarios/functions/func_pdf_extract.py +104 -0
- {csc_cia_stne-0.1.28.dist-info → csc_cia_stne-0.1.30.dist-info}/METADATA +4 -1
- {csc_cia_stne-0.1.28.dist-info → csc_cia_stne-0.1.30.dist-info}/RECORD +9 -7
- {csc_cia_stne-0.1.28.dist-info → csc_cia_stne-0.1.30.dist-info}/WHEEL +0 -0
- {csc_cia_stne-0.1.28.dist-info → csc_cia_stne-0.1.30.dist-info}/licenses/LICENCE +0 -0
- {csc_cia_stne-0.1.28.dist-info → csc_cia_stne-0.1.30.dist-info}/top_level.txt +0 -0
csc_cia_stne/__init__.py
CHANGED
@@ -16,6 +16,7 @@ from .web import web_screen
|
|
16
16
|
from .wacess import Waccess
|
17
17
|
from .gcp_bucket import GCPBucket
|
18
18
|
from .ftp import FTP
|
19
|
+
from .gcp_document_ai import GCPDocumentAIClient
|
19
20
|
|
20
21
|
# Define os itens disponíveis para importação
|
21
22
|
__all__ = [
|
@@ -30,6 +31,7 @@ __all__ = [
|
|
30
31
|
"Provio",
|
31
32
|
"Email",
|
32
33
|
"GoogleDrive",
|
34
|
+
"GCPDocumentAIClient"
|
33
35
|
"Slack",
|
34
36
|
"web_screen",
|
35
37
|
"Waccess",
|
@@ -0,0 +1,100 @@
|
|
1
|
+
from typing import Optional, Dict, Union
|
2
|
+
from google.cloud import documentai_v1beta3 as documentai
|
3
|
+
from google.oauth2 import service_account
|
4
|
+
|
5
|
+
class GCPDocumentAIClient:
|
6
|
+
def __init__(self, credential_json: Optional[dict] = None, processor_id: Optional[str] = None) -> None:
|
7
|
+
"""
|
8
|
+
Inicializa o cliente do Google Cloud Document AI.
|
9
|
+
|
10
|
+
Args:
|
11
|
+
credential_json (Optional[dict]): Dicionário contendo as credenciais do Google Cloud.
|
12
|
+
processor_id (Optional[str]): ID do processador do Document AI.
|
13
|
+
|
14
|
+
Attributes:
|
15
|
+
credential_json (dict): Credenciais do Google Cloud
|
16
|
+
project_id (str): ID do projeto extraído das credenciais
|
17
|
+
location (str): Localização do processador (fixo: "us")
|
18
|
+
processor_id (str): ID do processador do Document AI
|
19
|
+
client (documentai.DocumentProcessorServiceClient): Cliente do Document AI
|
20
|
+
is_connected (bool): Status da conexão
|
21
|
+
error (str|None): Mensagem de erro se houver falha na inicialização
|
22
|
+
"""
|
23
|
+
self.credential_json: dict = credential_json
|
24
|
+
self.project_id: str = self.credential_json.get("project_id")
|
25
|
+
self.location: str = "us"
|
26
|
+
self.processor_id: str = processor_id
|
27
|
+
|
28
|
+
try:
|
29
|
+
self.client: documentai.DocumentProcessorServiceClient = self._get_document_ai_client(self.credential_json)
|
30
|
+
self.is_connected: bool = True
|
31
|
+
self.error = None
|
32
|
+
|
33
|
+
except Exception as e:
|
34
|
+
error_msg = f"Erro ao inicializar o cliente do Document AI: {e}"
|
35
|
+
self.is_connected = False
|
36
|
+
self.error = error_msg
|
37
|
+
|
38
|
+
def _get_document_ai_client(self, credential_json: dict) -> documentai.DocumentProcessorServiceClient:
|
39
|
+
"""
|
40
|
+
Cria e retorna o cliente do Document AI.
|
41
|
+
|
42
|
+
Args:
|
43
|
+
credential_json (dict): Dicionário contendo as credenciais do Google Cloud.
|
44
|
+
|
45
|
+
Returns:
|
46
|
+
documentai.DocumentProcessorServiceClient: Cliente autenticado do Document AI.
|
47
|
+
|
48
|
+
Raises:
|
49
|
+
Exception: Se houver erro na autenticação ou inicialização do cliente.
|
50
|
+
"""
|
51
|
+
try:
|
52
|
+
credential = service_account.Credentials.from_service_account_info(credential_json)
|
53
|
+
except Exception as e:
|
54
|
+
error_msg = f"Erro ao criar credenciais do Document AI: {e}"
|
55
|
+
raise Exception(error_msg)
|
56
|
+
|
57
|
+
return documentai.DocumentProcessorServiceClient(credentials=credential)
|
58
|
+
|
59
|
+
|
60
|
+
def ler_documento(self, file_bytes: bytes, mime_type: str) -> Dict[str, Union[bool, str, documentai.Document, None]]:
|
61
|
+
"""
|
62
|
+
Processa um documento PDF usando o Google Cloud Document AI para extrair texto.
|
63
|
+
|
64
|
+
Args:
|
65
|
+
file_bytes (bytes): Bytes do arquivo PDF a ser processado.
|
66
|
+
mime_type (str): Tipo MIME do arquivo (ex.: "application/pdf").
|
67
|
+
|
68
|
+
Returns:
|
69
|
+
Dict[str, Union[bool, str, documentai.Document, None]]: Resultado do processamento
|
70
|
+
- success (bool): True se o processamento foi bem-sucedido
|
71
|
+
- error (str|None): Mensagem de erro se houver falha
|
72
|
+
- data (documentai.Document|None): Documento processado pelo Document AI
|
73
|
+
|
74
|
+
Example:
|
75
|
+
>>> client = GCPDocumentAIClient(creds, processor_id)
|
76
|
+
>>> with open("documento.pdf", "rb") as f:
|
77
|
+
... resultado = client.ler_documento(f.read(), "application/pdf")
|
78
|
+
>>> if resultado["success"]:
|
79
|
+
... texto = resultado["data"].text
|
80
|
+
... print(f"Texto extraído: {texto[:100]}...")
|
81
|
+
|
82
|
+
Note:
|
83
|
+
- Utiliza o processador configurado no __init__
|
84
|
+
- Processa o documento completo enviado em file_bytes
|
85
|
+
- Para limitar páginas, use extrair_x_paginas_pdf antes desta função
|
86
|
+
"""
|
87
|
+
try:
|
88
|
+
name = self.client.processor_path(self.project_id, self.location, self.processor_id)
|
89
|
+
request = documentai.ProcessRequest(
|
90
|
+
name=name,
|
91
|
+
raw_document=documentai.RawDocument(content=file_bytes, mime_type=mime_type)
|
92
|
+
)
|
93
|
+
|
94
|
+
result = self.client.process_document(request=request)
|
95
|
+
return {"success": True, "error": None, "data": result.document}
|
96
|
+
|
97
|
+
except Exception as e:
|
98
|
+
error_msg = f"Erro ao processar o documento com o Document AI: {str(e)}"
|
99
|
+
return {"success": False, "error": error_msg, "data": None}
|
100
|
+
|
@@ -7,6 +7,7 @@ from .func_get_secret import get_secret
|
|
7
7
|
from .func_datetime import now_sp
|
8
8
|
from .func_delete import delete_file, delete_folder
|
9
9
|
from .func_validate_json import validate_json
|
10
|
+
from .func_pdf_extract import extrair_x_paginas_pdf, extrair_paginas_intervalo_pdf
|
10
11
|
|
11
12
|
__all__ = [
|
12
13
|
"titulo",
|
@@ -19,5 +20,7 @@ __all__ = [
|
|
19
20
|
"now_sp",
|
20
21
|
"delete_file",
|
21
22
|
"delete_folder",
|
23
|
+
"extrair_x_paginas_pdf",
|
24
|
+
"extrair_paginas_intervalo_pdf",
|
22
25
|
"validate_json"
|
23
26
|
]
|
@@ -0,0 +1,104 @@
|
|
1
|
+
from PyPDF2 import PdfReader, PdfWriter
|
2
|
+
from io import BytesIO
|
3
|
+
from typing import Optional
|
4
|
+
|
5
|
+
def extrair_x_paginas_pdf(file_path: str, pages_limit: int = 15) -> Optional[bytes]:
|
6
|
+
"""
|
7
|
+
Extrai as primeiras X páginas de um arquivo PDF e retorna os bytes dessas páginas.
|
8
|
+
|
9
|
+
Args:
|
10
|
+
file_path (str): Caminho completo do arquivo PDF original.
|
11
|
+
pages_limit (int, optional): Número máximo de páginas a serem extraídas.
|
12
|
+
Defaults to 15.
|
13
|
+
|
14
|
+
Returns:
|
15
|
+
Optional[bytes]: Bytes do novo PDF contendo as primeiras X páginas,
|
16
|
+
ou None em caso de erro.
|
17
|
+
|
18
|
+
Note:
|
19
|
+
- Se o PDF tiver menos páginas que pages_limit, todas serão extraídas
|
20
|
+
- Utiliza PyPDF2 para manipulação do arquivo PDF
|
21
|
+
- Retorna None em caso de erro no processamento
|
22
|
+
|
23
|
+
Example:
|
24
|
+
>>> pdf_bytes = extrair_x_paginas_pdf("documento.pdf", 10)
|
25
|
+
>>> if pdf_bytes["success"]:
|
26
|
+
... print(f"PDF extraído com {len(pdf_bytes["data"])} bytes")
|
27
|
+
"""
|
28
|
+
try:
|
29
|
+
# Lê o arquivo PDF original
|
30
|
+
reader = PdfReader(file_path)
|
31
|
+
writer = PdfWriter()
|
32
|
+
|
33
|
+
# Extrai as primeiras 'pages_limit' páginas ou menos, caso o PDF tenha menos de 'pages_limit' páginas
|
34
|
+
for page_num in range(min(pages_limit, len(reader.pages))):
|
35
|
+
writer.add_page(reader.pages[page_num])
|
36
|
+
|
37
|
+
# Salva o novo PDF em um objeto BytesIO
|
38
|
+
pdf_bytes = BytesIO()
|
39
|
+
writer.write(pdf_bytes)
|
40
|
+
pdf_bytes.seek(0) # Move o cursor para o início do buffer
|
41
|
+
resposta = {"success": True, "error": None, "data": pdf_bytes.read()}
|
42
|
+
return resposta
|
43
|
+
except Exception as e:
|
44
|
+
resposta = {"success": False, "error": f"Erro ao extrair as primeiras {pages_limit} páginas do PDF: {str(e)}", "data": None}
|
45
|
+
return resposta
|
46
|
+
|
47
|
+
def extrair_paginas_intervalo_pdf(file_path: str, page_start: int = 1, pages_limit: int = 15) -> Optional[bytes]:
|
48
|
+
"""
|
49
|
+
Extrai um número específico de páginas de um arquivo PDF a partir de uma página inicial.
|
50
|
+
|
51
|
+
Args:
|
52
|
+
file_path (str): Caminho completo do arquivo PDF original.
|
53
|
+
page_start (int, optional): Página inicial para começar a extração (1-indexed).
|
54
|
+
Defaults to 1.
|
55
|
+
pages_limit (int, optional): Número máximo de páginas a serem extraídas a partir
|
56
|
+
da página inicial. Defaults to 15.
|
57
|
+
|
58
|
+
Returns:
|
59
|
+
Optional[bytes]: Bytes do novo PDF contendo as páginas do intervalo especificado,
|
60
|
+
ou None em caso de erro.
|
61
|
+
|
62
|
+
Note:
|
63
|
+
- Se page_start for maior que o número total de páginas, retorna None
|
64
|
+
- Se o número de páginas restantes for menor que pages_limit, extrai apenas as disponíveis
|
65
|
+
- Utiliza PyPDF2 para manipulação do arquivo PDF
|
66
|
+
- Páginas são indexadas começando em 1 (não 0)
|
67
|
+
|
68
|
+
Example:
|
69
|
+
>>> # Extrai 5 páginas começando da página 3
|
70
|
+
>>> pdf_bytes = extrair_paginas_intervalo_pdf("documento.pdf", 3, 5)
|
71
|
+
>>> if pdf_bytes["success"]:
|
72
|
+
... print(f"PDF extraído com {len(pdf_bytes["data"])} bytes")
|
73
|
+
"""
|
74
|
+
try:
|
75
|
+
# Lê o arquivo PDF original
|
76
|
+
reader = PdfReader(file_path)
|
77
|
+
writer = PdfWriter()
|
78
|
+
|
79
|
+
# Converte page_start para índice 0-based
|
80
|
+
start_index = page_start - 1
|
81
|
+
|
82
|
+
# Verifica se a página inicial é válida
|
83
|
+
if start_index >= len(reader.pages) or start_index < 0:
|
84
|
+
resposta = {"success": False, "error": f"Página inicial {page_start} inválida. O PDF tem {len(reader.pages)} páginas.", "data": None}
|
85
|
+
return resposta
|
86
|
+
|
87
|
+
# Calcula o índice final baseado no limite de páginas
|
88
|
+
end_index = min(start_index + pages_limit, len(reader.pages))
|
89
|
+
|
90
|
+
# Extrai as páginas do intervalo especificado
|
91
|
+
for page_num in range(start_index, end_index):
|
92
|
+
writer.add_page(reader.pages[page_num])
|
93
|
+
|
94
|
+
# Salva o novo PDF em um objeto BytesIO
|
95
|
+
pdf_bytes = BytesIO()
|
96
|
+
writer.write(pdf_bytes)
|
97
|
+
pdf_bytes.seek(0) # Move o cursor para o início do buffer
|
98
|
+
|
99
|
+
resposta = {"success": True, "error": None, "data": pdf_bytes.read()}
|
100
|
+
return resposta
|
101
|
+
|
102
|
+
except Exception as e:
|
103
|
+
resposta = {"success": False, "error": f"Erro ao extrair páginas {page_start}-{page_start + pages_limit - 1} do PDF: {str(e)}", "data": None}
|
104
|
+
return resposta
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: csc_cia_stne
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.30
|
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,botcity,stne
|
@@ -17,9 +17,11 @@ Requires-Dist: zeep
|
|
17
17
|
Requires-Dist: google-cloud-bigquery
|
18
18
|
Requires-Dist: google-cloud-storage
|
19
19
|
Requires-Dist: google-cloud-bigquery-storage
|
20
|
+
Requires-Dist: google-auth
|
20
21
|
Requires-Dist: google-auth-oauthlib
|
21
22
|
Requires-Dist: google-auth-httplib2
|
22
23
|
Requires-Dist: google-api-python-client
|
24
|
+
Requires-Dist: google-cloud-documentai
|
23
25
|
Requires-Dist: pyjwt
|
24
26
|
Requires-Dist: PyYAML
|
25
27
|
Requires-Dist: python-dotenv
|
@@ -31,6 +33,7 @@ Requires-Dist: email-validator
|
|
31
33
|
Requires-Dist: botcity-maestro-sdk
|
32
34
|
Requires-Dist: psutil
|
33
35
|
Requires-Dist: cryptography
|
36
|
+
Requires-Dist: PyPDF2
|
34
37
|
Requires-Dist: pycurl
|
35
38
|
Dynamic: license-file
|
36
39
|
|
@@ -1,10 +1,11 @@
|
|
1
|
-
csc_cia_stne/__init__.py,sha256=
|
1
|
+
csc_cia_stne/__init__.py,sha256=LITCLPqafF-VUV85wUvJ047ozLnfd82vw5AuuKXYi2s,2713
|
2
2
|
csc_cia_stne/bc_correios.py,sha256=s2XjJ0iokMlcUv0mAy9saU3pc_G-6X8wltb_lFHIL6o,24717
|
3
3
|
csc_cia_stne/bc_sta.py,sha256=S4EtkSEHP-wTMWRjmmSBH9XY5SnVQ1TwwZFSOE6tI2Q,29551
|
4
4
|
csc_cia_stne/email.py,sha256=y4xyPAe6_Mga5Wf6qAsDzYgn0f-zf2KshfItlWe58z8,8481
|
5
5
|
csc_cia_stne/ftp.py,sha256=eNkOUEXdw-9NYfuZjNo6Oh7EduD54g8N0cfD0LuOiTU,11516
|
6
6
|
csc_cia_stne/gcp_bigquery.py,sha256=foq8azvvv_f7uikMDslX9RcUIrx7RAS-Sn0AGW0QFQc,7231
|
7
7
|
csc_cia_stne/gcp_bucket.py,sha256=vMALWiW7IoBCuJAR8bUCpOV6BuBzI9AhRRk3b72OdMk,11515
|
8
|
+
csc_cia_stne/gcp_document_ai.py,sha256=Dzlk7YR3M_LxE0sHn-Lxz-PA1NsUZN2hgY5PyUfs0IQ,4506
|
8
9
|
csc_cia_stne/google_drive.py,sha256=7qwx4_RPEoSJgeVI02aLYNXA7o69_Z3qONvX5bfA4V0,44500
|
9
10
|
csc_cia_stne/karavela.py,sha256=jJCYX43D49gGuzmwwK6bN9XVnv2dXdp9iHnnV5H1LMQ,4794
|
10
11
|
csc_cia_stne/logger_json.py,sha256=CXxSCOFGMymDi8XE9SKnPKjW4D0wJLqDLnxqePS26i8,3187
|
@@ -16,12 +17,13 @@ csc_cia_stne/stne_admin.py,sha256=tbRN_l3y---GHlQoAAjlZP92wnVA73hUmk9hQxKavH8,28
|
|
16
17
|
csc_cia_stne/wacess.py,sha256=g-bWZNpm_tU7UsW1G_rqh_2fW2KShvxZHGOerX8DuQw,26768
|
17
18
|
csc_cia_stne/web.py,sha256=TBXUJ5eS36fytU3oFDuJsogi0sgw_qKgK-uphx4Nvxo,2506
|
18
19
|
csc_cia_stne/utilitarios/__init__.py,sha256=ul7p-4XduFOQW2ldKSIbTQb3eq7h5O1l8IwSP7b5KgY,410
|
19
|
-
csc_cia_stne/utilitarios/functions/__init__.py,sha256=
|
20
|
+
csc_cia_stne/utilitarios/functions/__init__.py,sha256=KPzb4b48YxWkn-9Pg4L3XHTWO3UqDiRXmTu1IyOJXMY,778
|
20
21
|
csc_cia_stne/utilitarios/functions/func_b64.py,sha256=XGU34BIQQXWXBS0yM2B4A2wDlcrMl1unIJXjq4lpLnk,1254
|
21
22
|
csc_cia_stne/utilitarios/functions/func_converters.py,sha256=EY1zvlBaRX7G1MceVSiRXwwKDQDZwUO9iECBL0fe5iU,481
|
22
23
|
csc_cia_stne/utilitarios/functions/func_datetime.py,sha256=UA7ch4sQWTiYcz8r6LtGujIdpTU-Sht8qmTYvm9vhh0,257
|
23
24
|
csc_cia_stne/utilitarios/functions/func_delete.py,sha256=o2h4leucTq5Cs0XxJ5aBzbRyuxusKXIoedn2tmxNp1E,2449
|
24
25
|
csc_cia_stne/utilitarios/functions/func_get_secret.py,sha256=XFsAd9GnKnf9WLnARqNG2fFg5h_JEOxbVvt_78VFYh4,2959
|
26
|
+
csc_cia_stne/utilitarios/functions/func_pdf_extract.py,sha256=uuGecPx4gh6uVyCvrqstK97G11FP7Sz0iwr52MUgD48,4508
|
25
27
|
csc_cia_stne/utilitarios/functions/func_recriar_pastas.py,sha256=4whZpB3aJQaCPJ3osMAQpKrzEhqYtJbljGWlx_OvKIM,826
|
26
28
|
csc_cia_stne/utilitarios/functions/func_settings.py,sha256=XwlfqdcfocXQ8kTsDKZ6GsAtpzr0_u44AOTIMtdem7U,2059
|
27
29
|
csc_cia_stne/utilitarios/functions/func_titulo.py,sha256=bH4tYxovTARF-g2kWUK_GIzzXt8egbVdp6mWD6fc_3I,5345
|
@@ -38,8 +40,8 @@ csc_cia_stne/utilitarios/web_screen/__init__.py,sha256=5QcOPXKd95SvP2DoZiHS0gaU6
|
|
38
40
|
csc_cia_stne/utilitarios/web_screen/web_screen_abstract.py,sha256=PjL8Vgfj_JdKidia7RFyCkro3avYLQu4RZRos41sh3w,3241
|
39
41
|
csc_cia_stne/utilitarios/web_screen/web_screen_botcity.py,sha256=Xi5YJjl2pcxlX3OimqcBWRNXZEpAE7asyUjDJ4Oho5U,12297
|
40
42
|
csc_cia_stne/utilitarios/web_screen/web_screen_selenium.py,sha256=JLIcPJE9ZX3Pd6zG6oTRMqqUAY063UzLY3ReRlxmiSM,15581
|
41
|
-
csc_cia_stne-0.1.
|
42
|
-
csc_cia_stne-0.1.
|
43
|
-
csc_cia_stne-0.1.
|
44
|
-
csc_cia_stne-0.1.
|
45
|
-
csc_cia_stne-0.1.
|
43
|
+
csc_cia_stne-0.1.30.dist-info/licenses/LICENCE,sha256=LPGMtgKki2C3KEZP7hDhA1HBrlq5JCHkIeStUCLEMx4,1073
|
44
|
+
csc_cia_stne-0.1.30.dist-info/METADATA,sha256=VzrUhcUhi1RZ2i2aBwBczNzvOfPFmGtwA3wfQSyAvYc,1552
|
45
|
+
csc_cia_stne-0.1.30.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
46
|
+
csc_cia_stne-0.1.30.dist-info/top_level.txt,sha256=ldo7GVv3tQx5KJvwBzdZzzQmjPys2NDVVn1rv0BOF2Q,13
|
47
|
+
csc_cia_stne-0.1.30.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|