commit f2f6f0327a197f5dcd3ab4559898020d0ca6bfde Author: Rafael Lopes Date: Mon Apr 20 11:10:29 2026 -0300 Initial Commit: Estrutura para o ETL e start coding diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..8bf3f1b --- /dev/null +++ b/.env.example @@ -0,0 +1,17 @@ +# PostgreSQL +DB_HOST=localhost +DB_PORT=5432 +DB_NAME=wifi_etl +DB_USER=postgres +DB_PASSWORD= + +# API Ruijie (AP) +RUIJIE_BASE_URL= +RUIJIE_API_KEY= + +# API WiFeed (autenticação) +WIFEED_BASE_URL= +WIFEED_API_KEY= + +# ETL config +LOG_LEVEL=INFO \ No newline at end of file diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..e69de29 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..25797df --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +# Ambiente +.env +.env.local +*.env + +# Python +__pycache__/ +*.py[cod] +*.pyo +*.pyd +.Python +*.egg-info/ +dist/ +build/ +*.egg + +# Virtual env +.venv/ +venv/ +env/ +ENV/ + +# IDEs +.vscode/ +.idea/ +*.swp +*.swo + +# Logs +*.log +logs/ + +# Docker +*.override.yml + +# OS +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e436aa2 --- /dev/null +++ b/README.md @@ -0,0 +1,197 @@ +# 📡 WiFi ETL Pipeline + +🚧 **Em construção** 🚧 +Este projeto está em desenvolvimento. Este primeiro commit contém a estrutura base do pipeline ETL. + +--- + +## 🧠 Visão Geral + +Este projeto tem como objetivo realizar a ingestão periódica de dados de duas APIs distintas: + +* **API de Autenticação (WiFeed)** → Nome, CPF, sexo, MAC +* **API do Access Point (Ruijie)** → MAC, tempo conectado, AP + +Os dados serão cruzados pelo **MAC Address** e persistidos em um banco **PostgreSQL** para análise e consulta. + +--- + +## ⚙️ Arquitetura + +```mermaid +flowchart TD + + A["Cron (Docker)\na cada 5 minutos"] + B["Python ETL Script"] + + C["API Autenticação\nnome, cpf, sexo, MAC"] + D["API do AP\nMAC, tempo, AP"] + + E["Transform\nmerge pelo MAC"] + F["PostgreSQL\nusers + sessions"] + + A --> B + B --> C + B --> D + + C --> E + D --> E + + E --> F +``` + + + + + + + +### Fluxo + +1. Execução automática a cada 5 minutos (cron via Docker) +2. Extração dos dados das APIs +3. Transformação (merge pelo MAC + normalização) +4. Carga no banco PostgreSQL + +--- + +## 🏗️ Estrutura do Projeto + +``` +app/ +├── core/ # Configurações e conexão com banco +│ ├── config.py +│ └── db.py +│ +├── extractor/ # Extração das APIs externas +│ ├── ruijie.py +│ └── wifeed.py +│ +├── transform/ # Regras de transformação +│ └── merge_mac.py +│ +├── load/ # Persistência no banco +│ └── load_database.py +│ +└── main.py # Orquestrador do pipeline + +infra/ +├── Dockerfile +├── docker-compose.yml +└── crontab + +.env.example +requirements.txt +README.md +``` + +--- + +## 🚀 Como executar + +> ⚠️ Observação: o projeto ainda está em fase inicial e algumas partes podem não estar totalmente implementadas. + +### 1. Clonar o repositório + +```bash +git clone +cd wifi-etl +``` + +--- + +### 2. Configurar variáveis de ambiente + +Crie um `.env` baseado no exemplo: + +```bash +cp .env.example .env +``` + +Preencha com suas credenciais: + +```env +DB_HOST= +DB_PORT=5432 +DB_NAME= +DB_USER= +DB_PASSWORD= + +RUIJIE_BASE_URL= +RUIJIE_API_KEY= + +WIFEED_BASE_URL= +WIFEED_API_KEY= +``` + +--- + +### 3. Subir o ambiente + +```bash +docker-compose up --build -d +``` + +--- + +### 4. Execução + +O pipeline será executado automaticamente a cada **5 minutos** via cron. + +--- + +## 🗄️ Modelo de Dados (planejado) + +### Tabela: users + +* nome +* cpf +* sexo +* mac + +### Tabela: sessions + +* mac +* access_point +* tempo_conectado +* timestamp + +--- + +## 🔄 Processo ETL + +### Extract + +Coleta dados das APIs Ruijie e WiFeed + +### Transform + +* Normalização de dados +* Merge pelo MAC Address + +### Load + +Inserção e/ou atualização no PostgreSQL + +--- + +## 📦 Tecnologias + +* Python +* Docker +* PostgreSQL +* Requests + +--- + +## 📌 Roadmap + +* [x] Estrutura inicial do projeto +* [ ] Integração com APIs +* [ ] Implementação do transform (merge por MAC) +* [ ] Persistência no banco +* [ ] Logging e tratamento de erros +* [ ] Deploy automatizado (CI/CD) + +--- + diff --git a/app/core/config.py b/app/core/config.py new file mode 100644 index 0000000..2a0ff7c --- /dev/null +++ b/app/core/config.py @@ -0,0 +1,18 @@ +from dotenv import load_dotenv +import os + +load_dotenv() + +DB_HOST = os.getenv("DB_HOST", "localhost") +DB_PORT = int(os.getenv("DB_PORT", 5432)) +DB_NAME = os.getenv("DB_NAME", "wifi_etl") +DB_USER = os.getenv("DB_USER", "postgres") +DB_PASSWORD = os.getenv("DB_PASSWORD", "") + +RUIJIE_BASE_URL = os.getenv("RUIJIE_BASE_URL") +RUIJIE_API_KEY = os.getenv("RUIJIE_API_KEY") + +WIFEED_BASE_URL = os.getenv("WIFEED_BASE_URL") +WIFEED_API_KEY = os.getenv("WIFEED_API_KEY") + +LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO") \ No newline at end of file diff --git a/app/core/db.py b/app/core/db.py new file mode 100644 index 0000000..e69de29 diff --git a/app/extractor/__init__.py b/app/extractor/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/extractor/ruijie.py b/app/extractor/ruijie.py new file mode 100644 index 0000000..e69de29 diff --git a/app/extractor/wifeed.py b/app/extractor/wifeed.py new file mode 100644 index 0000000..e69de29 diff --git a/app/load/load_database.py b/app/load/load_database.py new file mode 100644 index 0000000..e69de29 diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..e69de29 diff --git a/app/transform/merge_mac.py b/app/transform/merge_mac.py new file mode 100644 index 0000000..e69de29 diff --git a/infra/Dockerfile b/infra/Dockerfile new file mode 100644 index 0000000..e69de29 diff --git a/infra/crontab b/infra/crontab new file mode 100644 index 0000000..e69de29 diff --git a/infra/docker-compose.yml b/infra/docker-compose.yml new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..c2eae23 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +requests==2.31.0 +psycopg2-binary==2.9.9 +python-dotenv==1.0.1 \ No newline at end of file