📚 Pré-requisitos Teóricos: este projeto aplica conceitos ensinados em Especialização em Sistemas com Python. Recomendado revisar antes de começar.
Trilha de Especialização Pedagógica — Nível Intermediário (Curso 25: Sistemas Desktop com Python & POO)
- Visão Geral da Trilha: 📚 Módulo Sistemas com Python
- Trilha Evolutiva Completa: 🚀 Especificação das 4 Fases
- Catálogo de Projetos: 🏗️ Catálogo de Projetos
- ➡️ Projeto 1 de 4: Processador de Arquivos em Lote Desktop (
sistemas_python_01_desktop_poo)
Este projeto atua como a ponte pedagógica fundamental entre os scripts introdutórios e a arquitetura de software profissional. Nele, o estudante aprende a construir um Processador e Sanitizador de Arquivos em Lote para automação de rotinas de escritórios de contabilidade e despachantes, aplicando:
list[T], Optional[str], Tuple[int, int], Callable).@dataclass(slots=True)): modelagem de entidades de domínio com baixo consumo de memória e sem código boilerplate.enum.Enum): eliminação de “strings mágicas” através dos enums StatusProcessamento e TipoOperacao.@property: cálculo dinâmico de extensões e formatação amigável de tamanhos (B, KB, MB).models.py), Regras de Negócio/Serviços (services.py), Interface Desktop (app.py) e CLI (cli.py).UTF-8, Latin-1, CP1252) para evitar travamentos em arquivos corrompidos.flowchart TD
subgraph View ["🖥️ Camada de Apresentação (View / Controller)"]
GUI["app.py (AppProcessadorLote)\nTkinter / ttk.Treeview / Progressbar"]
CLI["cli.py (Interface de Terminal)\nExecução em lote sem GUI"]
end
subgraph Service ["⚙️ Camada de Serviços / Negócio (Service)"]
SVC["services.py (ProcessadorArquivosService)\nTransformação, Encodings e Callbacks"]
end
subgraph Model ["📦 Camada de Domínio / Dados (Model)"]
M1["ArquivoLote (@dataclass)\nMetadados, @property tamanho_formatado"]
M2["ConfiguracaoLote (@dataclass)\nOperação, prefixo, sufixo e destino"]
E1["StatusProcessamento (Enum)"]
E2["TipoOperacao (Enum)"]
end
GUI -->|Invoca| SVC
CLI -->|Invoca| SVC
SVC -->|Manipula| M1
SVC -->|Utiliza| M2
M1 --> E1
M2 --> E2
style View fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
style Service fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
style Model fill:#fffde7,stroke:#fbc02d,stroke-width:2px
sistemas_python_01_desktop_poo/
├── models.py # Entidades Dataclass, Enums e Type Hints PEP 484/585
├── services.py # Regras de transformação, tratamento de encodings e callbacks
├── app.py # Interface Gráfica Desktop com Tkinter / ttk.Treeview
├── cli.py # Interface de Linha de Comando interativa
├── main.py # Hub Launcher central (GUI, CLI ou Testes)
├── tests/
│ └── test_processor.py # Suíte de testes unitários automatizados com unittest
├── docs/
│ └── adr/ # Architectural Decision Records (ADRs)
└── index.md # Guia técnico e documentação pedagógica
No VS Code / PyCharm, abra a pasta deste projeto (File > Open Folder) ou navegue via terminal:
cd sistemas_python_01_desktop_poo
# Executar o Hub Launcher (Menu interativo):
python main.py
# Ou executar diretamente a Interface Gráfica Desktop:
python app.py
# Executar a Interface de Linha de Comando (CLI):
python cli.py
# Executar a Suíte de Testes Unitários:
python -m unittest discover -s tests
[!TIP] Dica para execução a partir da raiz do repositório: Se você abriu o repositório completo no VS Code, basta executar:
python catalogo_projetos/sistemas_python_01_desktop_poo/main.py
models.py)from dataclasses import dataclass, field
from enum import Enum
import os
from typing import Optional
class StatusProcessamento(str, Enum):
PENDENTE = "Pendente"
PROCESSANDO = "Processando"
SUCESSO = "Sucesso"
ERRO = "Erro"
class TipoOperacao(str, Enum):
RENOMEAR_PREFIXO = "Adicionar Prefixo/Sufixo"
SANITIZAR_ENCODING = "Sanitizar Encoding (UTF-8)"
MAIUSCULAS = "Converter Conteúdo para MAIÚSCULAS"
MINUSCULAS = "Converter Conteúdo para minúsculas"
@dataclass(slots=True)
class ArquivoLote:
caminho_origem: str
nome_original: str = field(init=False)
tamanho_bytes: int = field(init=False)
status: StatusProcessamento = StatusProcessamento.PENDENTE
mensagem_erro: Optional[str] = None
caminho_destino: Optional[str] = None
def __post_init__(self) -> None:
self.nome_original = os.path.basename(self.caminho_origem)
self.tamanho_bytes = os.path.getsize(self.caminho_origem) if os.path.exists(self.caminho_origem) else 0
@property
def tamanho_formatado(self) -> str:
if self.tamanho_bytes < 1024:
return f"{self.tamanho_bytes} B"
elif self.tamanho_bytes < 1024 * 1024:
return f"{self.tamanho_bytes / 1024:.2f} KB"
return f"{self.tamanho_bytes / (1024 * 1024):.2f} MB"
services.py)class ProcessadorArquivosService:
def processar_lote(self, arquivos: list[ArquivoLote], config: ConfiguracaoLote) -> tuple[int, int]:
sucessos, erros = 0, 0
total = len(arquivos)
for indice, arq in enumerate(arquivos, start=1):
try:
self._processar_arquivo_individual(arq, config)
sucessos += 1
except Exception as e:
arq.marcar_erro(str(e))
erros += 1
if self.callback_progresso:
self.callback_progresso(indice, total, arq)
return sucessos, erros
Ran 4 tests in 0.032s — OK
Os testes automatizados cobrem:
A visualização arquitetural abaixo detalha a separação de responsabilidades e o fluxo de dados implementado na subpasta app-python/:
flowchart TD
subgraph Entrada["Camada de Entrada & CLI"]
IN1["Interface de Comando / API"] --> IN2["Parser & Sanitização"]
end
subgraph Dominio["Camada de Domínio & Regras"]
DM1["Modelos de Domínio"] --> DM2["Processamento Algorítmico"]
end
subgraph Armazenamento["Persistência & Recursos"]
ST1["Banco de Dados / Arquivo"] --> ST2["Transações ACID & Logs"]
end
subgraph Qualidade["Validação & Qualidade"]
QA1["Testes Automatizados"] --> QA2["Checkpoints CP-01..05 PASS"]
end
Entrada --> Dominio
Dominio --> Armazenamento
Armazenamento --> Qualidade
style Entrada fill:#e3f2fd,stroke:#1976d2,stroke-width:1.5px
style Dominio fill:#fffde7,stroke:#fbc02d,stroke-width:1.5px
style Armazenamento fill:#e8f5e9,stroke:#388e3c,stroke-width:1.5px
style Qualidade fill:#f3e5f5,stroke:#7b1fa2,stroke-width:1.5px
| ID | Persona | História de Usuário | Critério de Aceite | Prioridade |
|---|---|---|---|---|
| US-01 | Analista de Operações | Desejo processar lotes de arquivos CSV, JSON e XML em lote | Parsing atômico com validação de schema e geração de relatórios consolidados | Alta |
| US-02 | Arquiteto de Software | Desejo arquitetura MVC desacoplada para separar dados, regras e UI | Models encapsulando regras, Services processando dados e Views apresentando | Alta |
| US-03 | Operador de Dados | Desejo relatório de inconformidades e logs detalhados de erros de processamento | Geração de logs estruturados e arquivos de auditoria com falhas apontadas | Alta |
| US-04 | Usuário de Linha de Comando | Desejo disparar execuções agendadas via CLI com flags de configuração | Interface CLI flexível com suporte a argumentos –input, –output e –dry-run | Média |
| US-05 | Auditor de Qualidade | Desejo suíte de testes com mocks cobrindo falhas de arquivos corrompidos | Cobertura de testes unitários com pytest validando cenários adversos | Média |
| ID | Descrição do Requisito | Criticidade |
|---|---|---|
| RF-01 | Pipeline de ingestão e normalização de múltiplos formatos de arquivo | Alta |
| RF-02 | Arquitetura estruturada em Models, Services e Controllers/CLI | Alta |
| RF-03 | Geração de relatórios consolidados em formatos CSV e JSON resumido | Alta |
| RF-04 | Interface de comando com logs formatados e níveis INFO, WARN e ERROR | Média |
| RF-05 | Suíte de testes automatizados com fixtures e dados de teste temporários | Média |
| ID | Especificação Arquitetural | Criticidade |
|---|---|---|
| RNF-01 | Processamento em streaming para arquivos volumosos sem esgotar RAM | Alta |
| RNF-02 | Tratamento seguro de exceções de permissão de arquivo e I/O | Alta |
| RNF-03 | Aderência rigorosa aos princípios SOLID e POO moderna | Média |
| RNF-04 | Execução multiplataforma sem dependências de SO | Média |
| RNF-05 | Isolamento dos módulos executáveis na pasta app-python/ | Alta |
| User Story | Requisito Funcional | Requisito Não-Funcional | Módulo / Artefato de Código | Status de Homologação |
|---|---|---|---|---|
| US-01 | RF-01 |
RNF-01, RNF-02 |
app-python/services.py |
Testado |
| US-02 | RF-02 |
RNF-03, RNF-05 |
app-python/models.py |
Testado |
| US-03 | RF-03 |
RNF-02, RNF-04 |
app-python/services.py |
Testado |
| US-04 | RF-04 |
RNF-04, RNF-05 |
app-python/cli.py |
Testado |
| US-05 | RF-05 |
RNF-02, RNF-05 |
app-python/tests/ |
Testado |
| Checkpoint | Escopo da Validação | Artefato Verificado | Status |
|---|---|---|---|
| CP-01 | Inicialização & Estrutura de Pastas | app-python/ |
PASS ✅ |
| CP-02 | Modelagem de Domínio & Regras Centrais | Domain Models |
PASS ✅ |
| CP-03 | Persistência & Operações de I/O | Storage / Data |
PASS ✅ |
| CP-04 | Interface de Operação & Usabilidade | CLI / GUI / API |
PASS ✅ |
| CP-05 | Homologação com Suíte de Testes | Test Suite |
PASS ✅ |