Skip to content

Commit

Permalink
Merge pull request #1 from ImpulsoGov/feat/pipeline
Browse files Browse the repository at this point in the history
[Pipeline Mensageria MVP] Adiciona serviço de API para automação da pipeline de envio de mensagens
  • Loading branch information
waltmatheus authored Oct 25, 2024
2 parents b941a00 + d1bba26 commit a3c0bad
Show file tree
Hide file tree
Showing 14 changed files with 1,832 additions and 99 deletions.
52 changes: 42 additions & 10 deletions .github/workflows/master_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,48 @@ jobs:
run: |
gcloud auth configure-docker us-central1-docker.pkg.dev
- name: Construir Imagem Docker
- name: Build and push Docker image
env:
PROJECT_ID: ${{ secrets.PROJECT_ID }}
TEMPLATE_NAMESPACE: ${{ secrets.TEMPLATE_NAMESPACE }}
ENV_PAULORAMOS_MA: ${{ secrets.ENV_PAULORAMOS_MA }}
ENV_LAGOVERDE_MA: ${{ secrets.ENV_LAGOVERDE_MA }}
ENV_PACOTI_CE: ${{ secrets.ENV_PACOTI_CE }}
ENV_MONSENHORTABOSA_CE: ${{ secrets.ENV_MONSENHORTABOSA_CE }}
ENV_MARAJADOSENA_MA: ${{ secrets.ENV_MARAJADOSENA_MA }}
ENV_ALAGOINHA_PE: ${{ secrets.ENV_ALAGOINHA_PE }}
ENV_BARAUNA_RN: ${{ secrets.ENV_BARAUNA_RN }}
ENV_JUCURUCU_BA: ${{ secrets.ENV_JUCURUCU_BA }}
ENV_VITORINOFREIRE_MA: ${{ secrets.ENV_VITORINOFREIRE_MA }}
ENV_BREJODEAREIA_MA: ${{ secrets.ENV_BREJODEAREIA_MA }}
ENV_OIAPOQUE_AP: ${{ secrets.ENV_OIAPOQUE_AP }}
ENV_TARRAFAS_CE: ${{ secrets.ENV_TARRAFAS_CE }}
ENV_SALVATERRA_PA: ${{ secrets.ENV_SALVATERRA_PA }}
ENV_LAGOADOOURO_PE: ${{ secrets.ENV_LAGOADOOURO_PE }}
run: |
docker build -t mesageria-mvp:latest .
- name: Adicionar Tag à Imagem Docker
run: |
docker tag mesageria-mvp:latest us-central1-docker.pkg.dev/predictive-keep-314223/mesageria-mvp/mesageria-mvp:latest
docker build \
--build-arg PROJECT_ID=$PROJECT_ID \
--build-arg TEMPLATE_NAMESPACE=$TEMPLATE_NAMESPACE \
--build-arg ENV_PAULORAMOS_MA=$ENV_PAULORAMOS_MA \
--build-arg ENV_LAGOVERDE_MA=$ENV_LAGOVERDE_MA \
--build-arg ENV_PACOTI_CE=$ENV_PACOTI_CE \
--build-arg ENV_MONSENHORTABOSA_CE=$ENV_MONSENHORTABOSA_CE \
--build-arg ENV_MARAJADOSENA_MA=$ENV_MARAJADOSENA_MA \
--build-arg ENV_ALAGOINHA_PE=$ENV_ALAGOINHA_PE \
--build-arg ENV_BARAUNA_RN=$ENV_BARAUNA_RN \
--build-arg ENV_JUCURUCU_BA=$ENV_JUCURUCU_BA \
--build-arg ENV_VITORINOFREIRE_MA=$ENV_VITORINOFREIRE_MA \
--build-arg ENV_BREJODEAREIA_MA=$ENV_BREJODEAREIA_MA \
--build-arg ENV_OIAPOQUE_AP=$ENV_OIAPOQUE_AP \
--build-arg ENV_TARRAFAS_CE=$ENV_TARRAFAS_CE \
--build-arg ENV_SALVATERRA_PA=$ENV_SALVATERRA_PA \
--build-arg ENV_LAGOADOOURO_PE=$ENV_LAGOADOOURO_PE \
-t us-central1-docker.pkg.dev/predictive-keep-314223/mensageria-mvp/mensageria-mvp:latest .
docker push us-central1-docker.pkg.dev/predictive-keep-314223/mensageria-mvp/mensageria-mvp:latest
- name: Enviar Imagem Docker
run: |
docker push us-central1-docker.pkg.dev/predictive-keep-314223/mesageria-mvp/mesageria-mvp:latest
docker push us-central1-docker.pkg.dev/predictive-keep-314223/mensageria-mvp/mensageria-mvp:latest
deploy:
runs-on: ubuntu-latest
Expand All @@ -56,8 +87,9 @@ jobs:

- name: Fazer Deploy no Google Cloud Run
run: |
gcloud run deploy mesageria-mvp-staging \
--image="us-central1-docker.pkg.dev/predictive-keep-314223/mesageria-mvp/mesageria-mvp:latest" \
gcloud run deploy mesageria-mvp \
--image="us-central1-docker.pkg.dev/predictive-keep-314223/mensageria-mvp/mensageria-mvp:latest" \
--region=us-central1 \
--platform=managed \
--allow-unauthenticated
--allow-unauthenticated \
--project=predictive-keep-314223
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.env
credencial_bigquery.json
credenciais.json
venv/
75 changes: 75 additions & 0 deletions Dockerfile
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.
156 changes: 144 additions & 12 deletions app.py
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)))
Loading

0 comments on commit a3c0bad

Please sign in to comment.