-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from ImpulsoGov/feat/pipeline
[Pipeline Mensageria MVP] Adiciona serviço de API para automação da pipeline de envio de mensagens
- Loading branch information
Showing
14 changed files
with
1,832 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
.env | ||
credencial_bigquery.json | ||
credenciais.json | ||
venv/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# Use a imagem base do Python | ||
FROM python:3.10.8-slim-bullseye | ||
|
||
# Instala o OpenVPN e dependências do sistema | ||
RUN apt-get update && \ | ||
apt-get install -y \ | ||
curl \ | ||
build-essential \ | ||
libpq-dev | ||
|
||
# Define o diretório de trabalho dentro do contêiner | ||
WORKDIR /app | ||
|
||
ENV POETRY_VIRTUALENVS_CREATE 1 | ||
ENV POETRY_VIRTUALENVS_IN_PROJECT 0 | ||
|
||
# Definindo argumentos de build | ||
ARG PROJECT_ID | ||
ARG TEMPLATE_NAMESPACE | ||
ARG ENV_PAULORAMOS_MA | ||
ARG ENV_LAGOVERDE_MA | ||
ARG ENV_PACOTI_CE | ||
ARG ENV_MONSENHORTABOSA_CE | ||
ARG ENV_MARAJADOSENA_MA | ||
ARG ENV_ALAGOINHA_PE | ||
ARG ENV_BARAUNA_RN | ||
ARG ENV_JUCURUCU_BA | ||
ARG ENV_VITORINOFREIRE_MA | ||
ARG ENV_BREJODEAREIA_MA | ||
ARG ENV_OIAPOQUE_AP | ||
ARG ENV_TARRAFAS_CE | ||
ARG ENV_SALVATERRA_PA | ||
ARG ENV_LAGOADOOURO_PE | ||
|
||
# Passando os argumentos para variáveis de ambiente | ||
ENV PROJECT_ID=$PROJECT_ID | ||
ENV TEMPLATE_NAMESPACE=$TEMPLATE_NAMESPACE | ||
ENV ENV_PAULORAMOS_MA=$ENV_PAULORAMOS_MA | ||
ENV ENV_LAGOVERDE_MA=$ENV_LAGOVERDE_MA | ||
ENV ENV_PACOTI_CE=$ENV_PACOTI_CE | ||
ENV ENV_MONSENHORTABOSA_CE=$ENV_MONSENHORTABOSA_CE | ||
ENV ENV_MARAJADOSENA_MA=$ENV_MARAJADOSENA_MA | ||
ENV ENV_ALAGOINHA_PE=$ENV_ALAGOINHA_PE | ||
ENV ENV_BARAUNA_RN=$ENV_BARAUNA_RN | ||
ENV ENV_JUCURUCU_BA=$ENV_JUCURUCU_BA | ||
ENV ENV_VITORINOFREIRE_MA=$ENV_VITORINOFREIRE_MA | ||
ENV ENV_BREJODEAREIA_MA=$ENV_BREJODEAREIA_MA | ||
ENV ENV_OIAPOQUE_AP=$ENV_OIAPOQUE_AP | ||
ENV ENV_TARRAFAS_CE=$ENV_TARRAFAS_CE | ||
ENV ENV_SALVATERRA_PA=$ENV_SALVATERRA_PA | ||
ENV ENV_LAGOADOOURO_PE=$ENV_LAGOADOOURO_PE | ||
|
||
# Instala o Poetry | ||
RUN curl -sSL https://install.python-poetry.org | python3 - | ||
|
||
# Define o PATH para incluir o diretório do Poetry | ||
ENV PATH="/root/.local/bin:${PATH}" | ||
|
||
# Copia os arquivos de configuração do Poetry | ||
COPY pyproject.toml poetry.lock poetry.toml /app/ | ||
|
||
# Configura o número máximo de workers para a instalação do Poetry | ||
RUN poetry config installer.max-workers 10 | ||
|
||
# Instala as dependências usando o Poetry | ||
RUN poetry install --no-root | ||
|
||
# Copia o código do aplicativo | ||
COPY . /app | ||
|
||
# Exponha a porta 5000 | ||
EXPOSE 5000 | ||
|
||
# Comando para iniciar o script de inicialização | ||
CMD ["poetry", "run", "python", "app.py"] |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,160 @@ | ||
import os | ||
import datetime | ||
|
||
from dotenv import load_dotenv | ||
from flask import Flask, request, jsonify | ||
from google.cloud import secretmanager | ||
import json | ||
import os | ||
|
||
|
||
# Carrega as variáveis de ambiente | ||
load_dotenv() | ||
|
||
# Importando as funções | ||
from src.scripts.passo_1_selecao_cidadao import selecionar_cidadaos | ||
from src.scripts.passo_2_match_com_equipe_e_upload_turn import processo_envio_turn | ||
from src.scripts.passo_3_envio_de_mensagens import programa_mensagens | ||
from src.loggers import logger | ||
|
||
from src.scripts.passo_1_selecao_cidadao import processa_passo_1 | ||
PROJECT_ID = os.getenv('PROJECT_ID') | ||
|
||
if not PROJECT_ID: | ||
raise ValueError("A variável de ambiente 'PROJECT_ID' não está definida") | ||
|
||
app = Flask(__name__) | ||
|
||
def validar_autenticacao( | ||
chave_recebida: str, | ||
projeto_id="567502497958", | ||
versao="latest", | ||
secret_id="mensageria-chave-api", | ||
): | ||
# Obter o valor da chave secreta do Secret Manager | ||
|
||
client = secretmanager.SecretManagerServiceClient() | ||
|
||
# Constrói o nome do recurso da versão do segredo | ||
name = f"projects/{projeto_id}/secrets/{secret_id}/versions/{versao}" | ||
|
||
# Acessa o segredo | ||
response = client.access_secret_version(name=name) | ||
chave_secreta = response.payload.data.decode("UTF-8") | ||
|
||
# Comparar a chave recebida com a chave secreta | ||
if chave_recebida != chave_secreta: | ||
return False | ||
|
||
return True | ||
|
||
@app.route("/passo1", methods=['GET']) | ||
def passo1(): | ||
|
||
try: | ||
# Validação da chave recebida | ||
chave_recebida = request.headers.get("X-API-Key") | ||
logger.info("Autenticando chave de acesso") | ||
validar_autenticacao(chave_recebida=chave_recebida) | ||
|
||
# Se a chave não for fornecida, retornar erro | ||
if not chave_recebida: | ||
return jsonify({"error": "Chave de API ausente"}), 401 | ||
|
||
# Autenticar a requisição | ||
if not validar_autenticacao(chave_recebida=chave_recebida): | ||
return jsonify({"error": "Chave de API inválida"}), 401 | ||
|
||
logger.info("Processo iniciado") | ||
|
||
#### Retire o comentário a baixo quando o módulo estiver finalizado | ||
#resultado = selecionar_cidadaos() | ||
#if resultado["status"] == "sucesso": | ||
|
||
# Retire a validação abaixo quando o módulo acima estiver finalizado | ||
if validar_autenticacao: | ||
return json.dumps({ | ||
'status': 'sucesso', | ||
'mensagem': 'Dados processados e histórico atualizado.', | ||
}), 200, {'Content-Type': 'application/json'} | ||
|
||
logger.info("Processo finalizado") | ||
|
||
except Exception as e: | ||
logger.error(f"Extração falhou. Exceção: {e}") | ||
return jsonify({f"erro": f"Erro do servidor: {str(e)}"}), 500 | ||
|
||
@app.route("/passo2", methods=['GET']) | ||
def passo2(): | ||
|
||
try: | ||
# Validação da chave recebida | ||
chave_recebida = request.headers.get("X-API-Key") | ||
logger.info("Autenticando chave de acesso") | ||
validar_autenticacao(chave_recebida=chave_recebida) | ||
|
||
# Se a chave não for fornecida, retornar erro | ||
if not chave_recebida: | ||
return jsonify({"error": "Chave de API ausente"}), 401 | ||
|
||
# Autenticar a requisição | ||
if not validar_autenticacao(chave_recebida=chave_recebida): | ||
return jsonify({"error": "Chave de API inválida"}), 401 | ||
|
||
logger.info("Processo iniciado") | ||
|
||
#### Retire o comentário a baixo quando o módulo estiver finalizado | ||
#resultado = processo_envio_turn() | ||
#if resultado["status"] == "sucesso": | ||
|
||
# Retire a validação abaixo quando o módulo acima estiver finalizado | ||
if validar_autenticacao: | ||
return json.dumps({ | ||
'status': 'sucesso', | ||
'mensagem': 'Dados enviados para TurnIO.' | ||
}), 200, {'Content-Type': 'application/json'} | ||
|
||
logger.info("Processo finalizado") | ||
|
||
except Exception as e: | ||
logger.error(f"Extração falhou. Exceção: {e}") | ||
return jsonify({f"erro": f"Erro do servidor: {str(e)}"}), 500 | ||
|
||
@app.route("/passo3", methods=['GET']) | ||
def passo3(): | ||
|
||
try: | ||
# Validação da chave recebida | ||
chave_recebida = request.headers.get("X-API-Key") | ||
logger.info("Autenticando chave de acesso") | ||
validar_autenticacao(chave_recebida=chave_recebida) | ||
|
||
# Se a chave não for fornecida, retornar erro | ||
if not chave_recebida: | ||
return jsonify({"error": "Chave de API ausente"}), 401 | ||
|
||
@app.route("/passo_1", methods=['POST']) | ||
def passo_1(): | ||
content_type = request.headers.get('Content-Type') | ||
if (content_type != 'application/json'): | ||
return 'Erro, content-type deve ser json', 400 | ||
# Autenticar a requisição | ||
if not validar_autenticacao(chave_recebida=chave_recebida): | ||
return jsonify({"error": "Chave de API inválida"}), 401 | ||
|
||
logger.info("Processo iniciado") | ||
|
||
return processa_passo_1() | ||
#### Retire o comentário a baixo quando o módulo estiver finalizado | ||
#resultado = programa_mensagens() | ||
#if resultado["status"] == "sucesso": | ||
|
||
# Retire a validação abaixo quando o módulo acima estiver finalizado | ||
if validar_autenticacao: | ||
return json.dumps({ | ||
'status': 'sucesso', | ||
'mensagem': 'Mensagens enviados para o cidadão.' | ||
}), 200, {'Content-Type': 'application/json'} | ||
|
||
logger.info("Processo finalizado") | ||
|
||
except Exception as e: | ||
logger.error(f"Extração falhou. Exceção: {e}") | ||
return jsonify({f"erro": f"Erro do servidor: {str(e)}"}), 500 | ||
|
||
#@app.route("/passo_2", methods=['POST']) | ||
|
||
#@app.route("/passo_3", methods=['POST']) | ||
|
||
if __name__ == "__main__": | ||
from waitress import serve | ||
serve(app, host="0.0.0.0", port=int(os.environ.get("PORT", 8080))) | ||
serve(app, host="0.0.0.0", port=int(os.environ.get("PORT", 5000))) |
Oops, something went wrong.