nia-etl-utils 0.2.0__py3-none-any.whl → 0.2.1__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.
@@ -1,15 +1,16 @@
1
- nia_etl_utils/__init__.py,sha256=ODg-ykR1Imq2bwtVopyKeSpu3e2X8fJvC1r2JbyfYkQ,6157
1
+ nia_etl_utils/__init__.py,sha256=kQCql-D62cup5_BJ0DNixoGNwOGcAWwgdTU7LIBldKA,6624
2
2
  nia_etl_utils/config.py,sha256=ITgG-BxmCOKGsyxTJnsQYqQJv5TeM2ng9JlGtUxz0Sw,11842
3
3
  nia_etl_utils/database.py,sha256=Ggn9EqSb7SyIRUpumx_DIO3bLN-9-ZrgwkKmuqfIKS0,10789
4
4
  nia_etl_utils/email_smtp.py,sha256=F4eVeVmNFnzK-4HU7bKijgPzMzWOWOWXTlFF_1fFdFc,8339
5
5
  nia_etl_utils/env_config.py,sha256=LH1FCpaAlo2nVx4SIuL9RGKchkgYP8jJurPe_3_IHEA,5506
6
- nia_etl_utils/exceptions.py,sha256=nsZoleUB9aV7Tfb5gLuYy_LCP1TgHiuccTSFA4qlZUA,8728
6
+ nia_etl_utils/exceptions.py,sha256=y4hVU5x5fiy49aXcbhc1V3PgBbTSfWmZONOEdjVN2Jo,10412
7
7
  nia_etl_utils/limpeza_pastas.py,sha256=OuiSCp7Hxpby0WRgox2Ak-B3ATFpyj08uidmBMwV434,7906
8
8
  nia_etl_utils/logger_config.py,sha256=Thhv7uwuhvXMKxef6_2M7lTwE1MfN_LAxWuTHjbLPd0,6787
9
+ nia_etl_utils/ocr.py,sha256=xv4-ohNhdt7G4L2Cc00ifrKIp8anGo43mOYCz30p_Ww,12383
9
10
  nia_etl_utils/processa_csv.py,sha256=BzgN6UUq2mGXjqKdnOaimLOLTXWu9H1SYdE1tJSWZ3M,11834
10
11
  nia_etl_utils/processa_csv_paralelo.py,sha256=0tQwsbHzi6UYEc2fp6o2E3pl23XOTvKhCShwCdcqrW0,8859
11
12
  nia_etl_utils/results.py,sha256=ah0ZaIymjdDi-4lO24EYiBeZTQpm289_ZHmUpoNQEVs,9156
12
- nia_etl_utils-0.2.0.dist-info/METADATA,sha256=eSUBmRTdIFMmNYOhCGqFV0MKiyNF8Zr2cFV6fJ2a2Ik,18196
13
- nia_etl_utils-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
- nia_etl_utils-0.2.0.dist-info/top_level.txt,sha256=LYLtk9Gh-GaiyyQkwpVs1CoOtnn1G9t8_ijxcFHyjfY,14
15
- nia_etl_utils-0.2.0.dist-info/RECORD,,
13
+ nia_etl_utils-0.2.1.dist-info/METADATA,sha256=vjIfaH9k6_oe1FgvCRdJkd_JlgDAGbhgbvoUbQ05Z-w,20285
14
+ nia_etl_utils-0.2.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
15
+ nia_etl_utils-0.2.1.dist-info/top_level.txt,sha256=LYLtk9Gh-GaiyyQkwpVs1CoOtnn1G9t8_ijxcFHyjfY,14
16
+ nia_etl_utils-0.2.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,615 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: nia-etl-utils
3
- Version: 0.2.0
4
- Summary: Utilitários compartilhados para pipelines ETL do NIA/MPRJ
5
- Author-email: Nícolas Esmael <nicolas.esmael@mprj.mp.br>
6
- License: MIT
7
- Project-URL: Repository, https://gitlab-dti.mprj.mp.br/nia/etl-nia/nia-etl-utils
8
- Project-URL: Documentation, https://gitlab-dti.mprj.mp.br/nia/etl-nia/nia-etl-utils/-/blob/main/README.md
9
- Project-URL: Changelog, https://gitlab-dti.mprj.mp.br/nia/etl-nia/nia-etl-utils/-/blob/main/CHANGELOG.md
10
- Keywords: etl,data-engineering,pipeline,mprj,nia
11
- Classifier: Development Status :: 4 - Beta
12
- Classifier: Intended Audience :: Developers
13
- Classifier: License :: OSI Approved :: MIT License
14
- Classifier: Operating System :: OS Independent
15
- Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.10
17
- Classifier: Programming Language :: Python :: 3.11
18
- Classifier: Programming Language :: Python :: 3.12
19
- Classifier: Programming Language :: Python :: 3.13
20
- Classifier: Topic :: Database
21
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
- Classifier: Typing :: Typed
23
- Requires-Python: >=3.10
24
- Description-Content-Type: text/markdown
25
- Requires-Dist: loguru>=0.7.0
26
- Requires-Dist: python-dotenv>=1.0.0
27
- Requires-Dist: cx-Oracle>=8.3.0
28
- Requires-Dist: psycopg2-binary>=2.9.0
29
- Requires-Dist: sqlalchemy>=2.0.0
30
- Requires-Dist: pandas>=2.0.0
31
- Provides-Extra: dev
32
- Requires-Dist: pytest>=7.0.0; extra == "dev"
33
- Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
34
- Requires-Dist: ruff>=0.1.0; extra == "dev"
35
- Requires-Dist: mypy>=1.0.0; extra == "dev"
36
- Requires-Dist: pandas-stubs>=2.0.0; extra == "dev"
37
- Provides-Extra: docs
38
- Requires-Dist: mkdocs>=1.5.0; extra == "docs"
39
- Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
40
- Requires-Dist: mkdocstrings[python]>=0.24.0; extra == "docs"
41
-
42
- # nia-etl-utils
43
-
44
- ## ✨ Visão Geral
45
-
46
- Biblioteca Python centralizada contendo **utilitários compartilhados** para pipelines ETL do NIA/MPRJ. Consolida funções reutilizáveis para configuração de ambiente, notificações por email, conexões de banco de dados, logging padronizado e processamento de dados.
47
-
48
- Desenvolvida para **eliminar duplicação de código**, **padronizar boas práticas** e **facilitar manutenção** em todos os projetos de engenharia de dados do NIA.
49
-
50
- ---
51
-
52
- ## 📂 Estrutura do Projeto
53
-
54
- ```plaintext
55
- .
56
- ├── src/
57
- │ └── nia_etl_utils/ # Pacote principal
58
- │ ├── __init__.py # Exporta funções principais
59
- │ ├── env_config.py # Gerenciamento de variáveis de ambiente
60
- │ ├── email_smtp.py # Envio de emails via SMTP
61
- │ ├── database.py # Conexões PostgreSQL e Oracle
62
- │ ├── logger_config.py # Configuração de logging com Loguru
63
- │ ├── processa_csv.py # Processamento e exportação de CSV
64
- │ ├── processa_csv_paralelo.py # Processamento paralelo de CSV grandes
65
- │ └── limpeza_pastas.py # Manipulação de arquivos e diretórios
66
-
67
- ├── tests/ # Testes unitários (~60+ testes)
68
- │ ├── conftest.py # Fixtures compartilhadas
69
- │ ├── test_env_config.py # Testes de variáveis de ambiente
70
- │ ├── test_email_smtp.py # Testes de email (com mocks)
71
- │ ├── test_database.py # Testes de conexões (com mocks)
72
- │ ├── test_logger_config.py # Testes de logging
73
- │ ├── test_processa_csv.py # Testes de processamento CSV
74
- │ ├── test_processa_csv_paralelo.py # Testes de processamento paralelo
75
- │ ├── test_limpeza_pastas.py # Testes de manipulação de arquivos
76
- │ └── README.md # Documentação dos testes
77
-
78
- ├── .env.example # Template de variáveis de ambiente
79
- ├── .gitignore # Arquivos ignorados pelo Git
80
- ├── .gitlab-ci.yml # Pipeline CI/CD (testes + cobertura)
81
- ├── .python-version # Versão Python do projeto (3.13.3)
82
- ├── pyproject.toml # Configuração do pacote Python
83
- ├── requirements.txt # Dependências do projeto
84
- ├── run_tests.sh # Script helper para executar testes
85
- └── README.md
86
- ```
87
-
88
- ---
89
-
90
- ## 🔧 Módulos Disponíveis
91
-
92
- ### 1️⃣ Configuração de Ambiente (`env_config.py`)
93
-
94
- Gerenciamento robusto de variáveis de ambiente com validação e falha explícita.
95
-
96
- ```python
97
- from nia_etl_utils import obter_variavel_env
98
-
99
- # Variável obrigatória (falha com sys.exit(1) se não existir)
100
- db_host = obter_variavel_env('DB_POSTGRESQL_HOST')
101
-
102
- # Variável opcional com fallback
103
- porta = obter_variavel_env('DB_PORT', default='5432')
104
- ```
105
-
106
- **Características:**
107
- - ✅ Falha rápida com `sys.exit(1)` quando variável obrigatória não existe
108
- - ✅ Suporte a valores padrão opcionais
109
- - ✅ Logs descritivos de erro
110
-
111
- ---
112
-
113
- ### 2️⃣ Email SMTP (`email_smtp.py`)
114
-
115
- Envio de emails com ou sem anexo, suportando destinatários configuráveis via env var.
116
-
117
- ```python
118
- from nia_etl_utils import enviar_email_smtp
119
-
120
- # Uso padrão (destinatários da env var EMAIL_DESTINATARIOS)
121
- enviar_email_smtp(
122
- corpo_do_email="Pipeline concluído com sucesso",
123
- assunto="[PROD] ETL Finalizado"
124
- )
125
-
126
- # Com destinatários específicos e anexo
127
- enviar_email_smtp(
128
- destinatarios=["diretor@mprj.mp.br"],
129
- corpo_do_email="Relatório executivo anexo",
130
- assunto="Relatório Mensal",
131
- anexo="/tmp/relatorio.pdf"
132
- )
133
- ```
134
-
135
- **Características:**
136
- - ✅ Destinatários configuráveis via `EMAIL_DESTINATARIOS`
137
- - ✅ Suporte a anexos
138
- - ✅ Falha explícita com `sys.exit(1)` em erros SMTP
139
- - ✅ Validação de arquivos anexos
140
-
141
- ---
142
-
143
- ### 3️⃣ Conexões de Banco (`database.py`)
144
-
145
- Conexões padronizadas para PostgreSQL (psycopg2 + SQLAlchemy) e Oracle (cx_Oracle).
146
-
147
- #### PostgreSQL
148
-
149
- ```python
150
- from nia_etl_utils import conectar_postgresql_nia, fechar_conexao
151
-
152
- # Conecta no PostgreSQL do NIA
153
- cur, conn = conectar_postgresql_nia()
154
- cur.execute("SELECT * FROM tabela")
155
- resultados = cur.fetchall()
156
- fechar_conexao(cur, conn)
157
-
158
- # Engine SQLAlchemy (para pandas)
159
- from nia_etl_utils import obter_engine_postgresql_nia
160
- import pandas as pd
161
-
162
- engine = obter_engine_postgresql_nia()
163
- df = pd.read_sql("SELECT * FROM tabela", engine)
164
- ```
165
-
166
- #### Oracle
167
-
168
- ```python
169
- from nia_etl_utils import conectar_oracle, fechar_conexao
170
-
171
- # Conecta no Oracle
172
- cur, conn = conectar_oracle()
173
- cur.execute("SELECT * FROM tabela WHERE ROWNUM <= 10")
174
- resultados = cur.fetchall()
175
- fechar_conexao(cur, conn)
176
- ```
177
-
178
- #### Bancos Adicionais (Genérico)
179
-
180
- ```python
181
- from nia_etl_utils import conectar_postgresql
182
-
183
- # Conecta em qualquer PostgreSQL configurado com sufixo customizado
184
- # Requer: DB_POSTGRESQL_HOST_SUFIXO, DB_POSTGRESQL_PORT_SUFIXO, etc
185
- cur, conn = conectar_postgresql("_SUFIXO")
186
- ```
187
-
188
- **Características:**
189
- - ✅ Funções genéricas + wrappers de conveniência
190
- - ✅ Suporte a múltiplos bancos PostgreSQL (via sufixos)
191
- - ✅ Logs informativos de conexão
192
- - ✅ Falha explícita com `sys.exit(1)` em erros de conexão
193
- - ✅ `fechar_conexao()` segura (não falha se erro ao fechar)
194
-
195
- ---
196
-
197
- ### 4️⃣ Logging (`logger_config.py`)
198
-
199
- Configuração padronizada do Loguru com rotação, retenção e níveis customizáveis.
200
-
201
- ```python
202
- from nia_etl_utils import configurar_logger_padrao_nia
203
- from loguru import logger
204
-
205
- # Configuração rápida com padrões do NIA
206
- caminho_log = configurar_logger_padrao_nia("ouvidorias_etl")
207
- logger.info("Pipeline iniciado")
208
-
209
- # Configuração customizada
210
- from nia_etl_utils import configurar_logger
211
-
212
- caminho_log = configurar_logger(
213
- prefixo="meu_pipeline",
214
- data_extracao="2025_01_19",
215
- pasta_logs="/var/logs/nia",
216
- rotation="50 MB",
217
- retention="30 days",
218
- level="INFO"
219
- )
220
- ```
221
-
222
- **Características:**
223
- - ✅ Rotação automática de arquivos por tamanho
224
- - ✅ Retenção configurável (padrão: 7 dias em DEV, 30 dias em PROD)
225
- - ✅ Formato padronizado com timestamp, nível, módulo, função e linha
226
- - ✅ Logs organizados por pipeline e data
227
-
228
- ---
229
-
230
- ### 5️⃣ Processamento CSV (`processa_csv.py`)
231
-
232
- Exportação de DataFrames para CSV com nomenclatura padronizada e validações.
233
-
234
- ```python
235
- from nia_etl_utils import exportar_para_csv, extrair_e_exportar_csv
236
- import pandas as pd
237
-
238
- # Exportação simples
239
- df = pd.DataFrame({"col1": [1, 2], "col2": [3, 4]})
240
- caminho = exportar_para_csv(
241
- df=df,
242
- nome_arquivo="dados_clientes",
243
- data_extracao="2025_01_19",
244
- diretorio_base="/tmp/dados"
245
- )
246
-
247
- # Extração + Exportação
248
- def extrair_dados():
249
- # ... lógica de extração ...
250
- return pd.DataFrame({"dados": [1, 2, 3]})
251
-
252
- caminho = extrair_e_exportar_csv(
253
- nome_extracao="dados_vendas",
254
- funcao_extracao=extrair_dados,
255
- data_extracao="2025_01_19",
256
- diretorio_base="/tmp/dados",
257
- falhar_se_vazio=True # sys.exit(1) se DataFrame vazio
258
- )
259
-
260
- # Múltiplas extrações em lote
261
- from nia_etl_utils import exportar_multiplos_csv
262
-
263
- extractions = [
264
- {"nome": "clientes", "funcao": extrair_clientes},
265
- {"nome": "vendas", "funcao": extrair_vendas}
266
- ]
267
-
268
- resultados = exportar_multiplos_csv(
269
- extractions=extractions,
270
- data_extracao="2025_01_19",
271
- diretorio_base="/tmp/dados"
272
- )
273
- ```
274
-
275
- **Características:**
276
- - ✅ Nomenclatura padronizada: `{nome}_{data}.csv`
277
- - ✅ Criação automática de diretórios
278
- - ✅ Logs com informações úteis (linhas, colunas, tamanho)
279
- - ✅ Controle de falha em DataFrames vazios
280
-
281
- ---
282
-
283
- ### 6️⃣ Manipulação de Arquivos (`limpeza_pastas.py`)
284
-
285
- Utilitários para limpeza e criação de diretórios.
286
-
287
- ```python
288
- from nia_etl_utils import limpar_pasta, remover_pasta_recursivamente, criar_pasta_se_nao_existir
289
-
290
- # Limpa pasta (remove arquivos, mantém subdiretórios)
291
- limpar_pasta("/tmp/dados")
292
-
293
- # Remove pasta completa (arquivos + subdiretórios)
294
- remover_pasta_recursivamente("/tmp/temporario")
295
-
296
- # Cria pasta se não existir (incluindo pais)
297
- criar_pasta_se_nao_existir("/dados/processados/2025/01")
298
- ```
299
-
300
- **Características:**
301
- - ✅ Uso de `pathlib.Path` (moderno e seguro)
302
- - ✅ Validações de permissão
303
- - ✅ Falha explícita com `sys.exit(1)` em erros
304
-
305
- ---
306
-
307
- ### 7️⃣ Processamento Paralelo de CSV (`processa_csv_paralelo.py`)
308
-
309
- Processa arquivos CSV grandes em paralelo usando multiprocessing com chunks otimizados.
310
-
311
- ```python
312
- from nia_etl_utils import processar_csv_paralelo
313
-
314
- # Função de transformação customizada
315
- def limpar_texto(texto):
316
- return texto.strip().upper()
317
-
318
- # Processa CSV grande em paralelo
319
- processar_csv_paralelo(
320
- caminho_entrada="dados_brutos.csv",
321
- caminho_saida="dados_limpos.csv",
322
- colunas_para_tratar=["nome", "descricao", "observacao"],
323
- funcao_transformacao=limpar_texto,
324
- remover_entrada=True # Remove arquivo original após processar
325
- )
326
-
327
- # Com configurações customizadas
328
- processar_csv_paralelo(
329
- caminho_entrada="dados_gigantes.csv",
330
- caminho_saida="dados_processados.csv",
331
- colunas_para_tratar=["texto"],
332
- funcao_transformacao=limpar_texto,
333
- chunksize=5000, # Tamanho customizado de chunk
334
- num_processos=4, # Número de processos paralelos
335
- normalizar_colunas=False, # Mantém case original das colunas
336
- remover_entrada=False # Preserva arquivo de entrada
337
- )
338
- ```
339
-
340
- **Características:**
341
- - ✅ Processamento paralelo automático usando `multiprocessing.Pool`
342
- - ✅ Chunksize calculado automaticamente baseado no tamanho do arquivo
343
- - ✅ Heurística inteligente:
344
- - Arquivos < 500MB: chunks de 10.000 linhas
345
- - Arquivos 500MB-2GB: chunks de 5.000 linhas
346
- - Arquivos 2-5GB: chunks de 2.000 linhas
347
- - Arquivos > 5GB: chunks de 1.000 linhas
348
- - ✅ Normalização opcional de nomes de colunas (lowercase)
349
- - ✅ Remoção opcional do arquivo de entrada
350
- - ✅ Logs informativos de progresso
351
- - ✅ Suporta qualquer função de transformação customizada
352
-
353
- **Quando usar:**
354
- - 📊 Arquivos CSV com milhões de linhas
355
- - 🔄 Transformações pesadas em texto (limpeza, normalização)
356
- - ⚡ Necessidade de processar múltiplas colunas rapidamente
357
- - 💾 Arquivos que não cabem confortavelmente na memória
358
-
359
- ---
360
-
361
- ## 📦 Instalação
362
-
363
- ### Via GitLab (Recomendado)
364
-
365
- ```bash
366
- # Instalar versão específica
367
- pip install git+https://gitlab-dti.mprj.mp.br/nia/etl-nia/nia-etl-utils.git@v0.1.0
368
-
369
- # Ou no requirements.txt
370
- nia-etl-utils @ git+https://gitlab-dti.mprj.mp.br/nia/etl-nia/nia-etl-utils.git@v0.1.0
371
- ```
372
-
373
- ### Modo Desenvolvimento
374
-
375
- ```bash
376
- git clone https://gitlab-dti.mprj.mp.br/nia/etl-nia/nia-etl-utils.git
377
- cd nia-etl-utils
378
- pip install -e ".[dev]"
379
- ```
380
-
381
- ---
382
-
383
- ## ⚙️ Configuração
384
-
385
- ### 1. Criar arquivo `.env`
386
-
387
- ```bash
388
- cp .env.example .env
389
- ```
390
-
391
- ### 2. Configurar variáveis de ambiente
392
-
393
- ```env
394
- # Email SMTP
395
- MAIL_SMTP_SERVER=smtp.mprj.mp.br
396
- MAIL_SMTP_PORT=587
397
- MAIL_SENDER=etl@mprj.mp.br
398
- EMAIL_DESTINATARIOS=equipe@mprj.mp.br,gestor@mprj.mp.br
399
-
400
- # PostgreSQL - NIA
401
- DB_POSTGRESQL_HOST=postgres-nia.mprj.mp.br
402
- DB_POSTGRESQL_PORT=5432
403
- DB_POSTGRESQL_DATABASE=nia_database
404
- DB_POSTGRESQL_USER=usuario
405
- DB_POSTGRESQL_PASSWORD=senha
406
-
407
- # PostgreSQL - OpenGeo
408
- DB_POSTGRESQL_HOST_OPENGEO=postgres-opengeo.mprj.mp.br
409
- DB_POSTGRESQL_PORT_OPENGEO=5432
410
- DB_POSTGRESQL_DATABASE_OPENGEO=opengeo_database
411
- DB_POSTGRESQL_USER_OPENGEO=usuario
412
- DB_POSTGRESQL_PASSWORD_OPENGEO=senha
413
-
414
- # Oracle
415
- DB_ORACLE_HOST=oracle.mprj.mp.br
416
- DB_ORACLE_PORT=1521
417
- DB_ORACLE_SERVICE_NAME=ORCL
418
- DB_ORACLE_USER=usuario
419
- DB_ORACLE_PASSWORD=senha
420
- ```
421
-
422
- ---
423
-
424
- ## 🧪 Testes
425
-
426
- ### Executar Testes
427
-
428
- ```bash
429
- # Todos os testes
430
- pytest
431
-
432
- # Com cobertura
433
- pytest --cov=src/nia_etl_utils --cov-report=term-missing
434
-
435
- # Ou usar o script helper
436
- ./run_tests.sh --coverage --verbose
437
- ```
438
-
439
- ### Cobertura Atual
440
-
441
- - **~70 testes unitários** (incluindo testes de processamento paralelo)
442
- - **~90% de cobertura** de código
443
- - Testes com mocks (sem dependência de banco/SMTP real)
444
-
445
- Veja `tests/README.md` para documentação completa dos testes.
446
-
447
- ---
448
-
449
- ## 🚀 Exemplo de Uso Completo
450
-
451
- ```python
452
- from nia_etl_utils import (
453
- configurar_logger_padrao_nia,
454
- obter_variavel_env,
455
- conectar_postgresql_nia,
456
- exportar_para_csv,
457
- processar_csv_paralelo,
458
- fechar_conexao
459
- )
460
- from loguru import logger
461
- import pandas as pd
462
-
463
- # 1. Configura logging
464
- configurar_logger_padrao_nia("meu_pipeline")
465
-
466
- # 2. Conecta no banco
467
- logger.info("Iniciando conexão com banco de dados...")
468
- cur, conn = conectar_postgresql_nia()
469
-
470
- # 3. Extrai dados
471
- logger.info("Extraindo dados...")
472
- cur.execute("SELECT * FROM tabela WHERE data >= CURRENT_DATE - 7")
473
- resultados = cur.fetchall()
474
- colunas = [desc[0] for desc in cur.description]
475
- df = pd.DataFrame(resultados, columns=colunas)
476
-
477
- # 4. Fecha conexão
478
- fechar_conexao(cur, conn)
479
- logger.info(f"Extração concluída: {len(df)} registros")
480
-
481
- # 5. Exporta CSV
482
- from datetime import datetime
483
- data_hoje = datetime.now().strftime("%Y_%m_%d")
484
-
485
- caminho = exportar_para_csv(
486
- df=df,
487
- nome_arquivo="dados_extraidos",
488
- data_extracao=data_hoje,
489
- diretorio_base="/dados/processados"
490
- )
491
-
492
- # 6. Processa CSV em paralelo (se necessário)
493
- if len(df) > 100000: # Só paraleliza arquivos grandes
494
- def limpar_descricao(texto):
495
- return texto.strip().upper() if texto else ""
496
-
497
- processar_csv_paralelo(
498
- caminho_entrada=caminho,
499
- caminho_saida=f"/dados/processados/dados_limpos_{data_hoje}.csv",
500
- colunas_para_tratar=["descricao", "observacao"],
501
- funcao_transformacao=limpar_descricao,
502
- remover_entrada=True
503
- )
504
- logger.success("Processamento paralelo concluído!")
505
-
506
- logger.success(f"Pipeline concluído! Arquivo: {caminho}")
507
- ```
508
-
509
- ---
510
-
511
- ## ☁️ Integração com Airflow
512
-
513
- ### Usando em KubernetesPodOperator
514
-
515
- ```python
516
- from airflow.providers.cncf.kubernetes.operators.kubernetes_pod import KubernetesPodOperator
517
-
518
- task = KubernetesPodOperator(
519
- task_id="meu_etl",
520
- name="meu-etl-pod",
521
- namespace="airflow-nia-stage",
522
- image="python:3.13.3",
523
- cmds=[
524
- "sh", "-c",
525
- "pip install git+https://gitlab-dti.mprj.mp.br/nia/etl-nia/nia-etl-utils.git@v0.1.0 && "
526
- "python src/extract.py"
527
- ],
528
- env_vars={
529
- "DB_POSTGRESQL_HOST": "...",
530
- "EMAIL_DESTINATARIOS": "equipe@mprj.mp.br"
531
- },
532
- # ... outras configs
533
- )
534
- ```
535
-
536
- ---
537
-
538
- ## ⚙️ Tecnologias Utilizadas
539
-
540
- - Python 3.13.3
541
- - Loguru (logging)
542
- - python-dotenv (env vars)
543
- - cx_Oracle (Oracle)
544
- - psycopg2 (PostgreSQL)
545
- - SQLAlchemy (engines)
546
- - pandas (processamento de dados)
547
- - pytest + pytest-cov (testes)
548
- - ruff (linting)
549
-
550
- ---
551
-
552
- ## 📋 Versionamento
553
-
554
- Este projeto usa [Semantic Versioning](https://semver.org/):
555
-
556
- - **MAJOR**: Mudanças incompatíveis na API
557
- - **MINOR**: Novas funcionalidades (retrocompatíveis)
558
- - **PATCH**: Correções de bugs
559
-
560
- **Versão atual:** `v0.1.0`
561
-
562
- ---
563
-
564
- ## 🔔 Monitoramento e Logs
565
-
566
- - Logging estruturado via Loguru
567
- - Logs organizados por pipeline e data em `/logs`
568
- - Scripts retornam `sys.exit(1)` em falhas para integração com Airflow
569
- - Notificações via email em pipelines de produção
570
-
571
- ---
572
-
573
- ## 🔧 CI/CD
574
-
575
- Pipeline automatizado no GitLab com:
576
-
577
- - ✅ Testes unitários (pytest)
578
- - ✅ Cobertura de código (>= 80%)
579
- - ✅ Linting (ruff)
580
- - ✅ Relatórios de cobertura (HTML + XML)
581
- - ✅ Execução em branches e merge requests
582
-
583
- ---
584
-
585
- ## ✏️ Contribuição
586
-
587
- Merge requests são bem-vindos. Sempre crie uma branch a partir de `main`.
588
-
589
- ### Checklist para Contribuir:
590
-
591
- - [ ] Testes passam: `pytest`
592
- - [ ] Cobertura >= 70%: `pytest --cov=src/nia_etl_utils --cov-fail-under=80`
593
- - [ ] Lint OK: `ruff check src/ tests/`
594
- - [ ] Commits semânticos: `feat:`, `fix:`, `refactor:`, etc.
595
- - [ ] Documentação atualizada
596
-
597
- ---
598
-
599
- ## 🔐 Licença
600
-
601
- Projeto de uso interno do MPRJ. Sem licença pública.
602
-
603
- ---
604
-
605
- ## ✨ Responsável Técnico
606
-
607
- **Nícolas Galdino Esmael** | Engenheiro de Dados - NIA | MPRJ
608
-
609
- ---
610
-
611
- ## 📚 Documentação Adicional
612
-
613
- - [Documentação de Testes](tests/README.md)
614
- - [Template de Variáveis de Ambiente](.env.example)
615
- - [Configuração do Projeto](pyproject.toml)