
Hoje finalizaremos nosso hands-on de uma arquitetura na AWS. Cada lambda irá receber um código em python para realizar suas tarefas, dessa forma, o conhecimento será direcionado a como acessar recursos da AWS e como fazer requisições a uma API pelo Python.
Este artigo tutorial é auxiliar ao vídeo gravado pelo trainee Guilherme Ferreira Rocha, que está no Youtube do TerraLAB. Veja aqui:
Esta é a parte 4 deste tutorial, então aconselhamos que, caso ainda não esteja acompanhando desde a primeira parte, volte para entender exatamente o que estamos arquitetando. O repositório HandsOn AWS-TerraLAB contém todo o código utilizado nos tutoriais.
Dando continuidade
- LAMBDA 2:
Nossa segunda lambda, irá receber as informações do pokémon pelo trigger conectado a nossa fila MQ. Para iniciar, crie um arquivo chamado lambda2.py no seu diretório do serverless. Ela manterá o padrão inicial de parâmetros e retornos que comentamos na lambda 1.
O primeiro passo é recuperar a informação do pokémon que estará no event. Para recuperar, vamos acessar o dicionário, na chave “messages” na posição zero e em sequência na chave “data”. Esses dados precisam ser decodificados pela biblioteca base64, nativa do python e depois convertidos para dicionário python. Adicione a seus imports:
import base64
Feito isso, o código de recuperação das informações ficará como o seguinte:
message = event["messages"][0]["data"]
message = base64.b64decode(message).decode("utf-8")
pokemon = json.loads(message)
Agora, para finalizar o fluxo da arquitetura proposta, precisamos enviar tais informações ao S3 Bucket, para isso precisamos que elas estejam em formato de arquivo json. Vamos então escrever esse arquivo em uma pasta temporária da lambda:
temp = f"/tmp/{pokemon['name']}.json"
file = open(temp, "w")
json.dump(pokemon, file, indent=4)
file.close()
Para fazer o upload do arquivo, utilizaremos novamente a biblioteca boto3 (adicione ela a seus imports). Um dos critérios estabelecidos na nossa arquitetura, era particionar o S3 por tipos de pokémon, ou seja, cada pokémon estará contido em uma pasta com o nome do seu tipo, por exemplo “eletric”. O código de upload será o seguinte:
client = boto3.client("s3")
client.upload_file(
temp,"bucket-pokemon-tutorial-v2", f"{pokemon['types'][0]['type']['name']}/{pokemon['name']}.json",
)
Pronto, finalizamos a lambda 2. Alterando a mensagem de retorno e dando alguns toques informativos, seu código deverá ficar assim:
import base64
import json
import boto3
def main(event, context):
try:
print("Getting consumed message.")
message = event["messages"][0]["data"]
print("Decoding message.")
message = base64.b64decode(message).decode("utf-8")
print("Converting to dictionary (like a json)")
pokemon = json.loads(message)
temp = f"/tmp/{pokemon['name']}.json"
file = open(temp, "w")
json.dump(pokemon, file, indent=4)
file.close()
print("Connecting to s3.")
client = boto3.client("s3")
print(
f"Sending {pokemon['name']} json to s3 partition {pokemon['types'][0]['type']['name']}"
)
client.upload_file(
temp,
"bucket-pokemon-tutorial-v2",
f"{pokemon['types'][0]['type']['name']}/{pokemon['name']}.json",
)
print("Function is over.")
body = {
"message": f"Pokémon {pokemon['name']} sent to s3 partition {pokemon['types'][0]['type']['name']}",
"input": event,
}
response = {"statusCode": 200, "body": json.dumps(body)}
print(f"Lambda return = {body}")
except Exception as error:
body = {
"message": f"Error: {error}",
"input": event,
}
response = {"statusCode": 400, "body": json.dumps(body)}
print(f"Lambda return = {body}")
return response
Assim como lambda 1, para execução da lambda 2 também é necessário o arquivo “requirements.txt”. Nesse caso, usaremos o mesmo, sem modificações. Basta digitar o seguinte comando:
serverless plugin install -n serverless-python-requirements
Feito tudo isso, agora é só realizar o deploy, novamente abra o terminal no diretório do seu serverless e rode o comando:
serverless deploy
Pronto, nossa arquitetura está completa!
- POPULANDO NOSSO BUCKET:
Para popular nosso S3 Bucket com alguns pokémons, vamos criar um pequeno script para ir realizando chamadas para a nossa arquitetura. Crie um outro diretório separado para seu script e adicione dois arquivos, o “poke-names.txt” e o “start.py”.
O arquivo texto irá conter nomes de pokémons a cada linha, você pode acessar o repositório no github para copiar esse arquivo.
Já nosso código de início, irá utilizar a biblioteca requests para fazer requisições para a lambda 1 para cada nome no arquivo txt.
Uma informação importante que precisamos é a URL da lambda 1. Para recuperar sua URL vá no console da AWS > pesquise por Lambda > vá em funções no painel lateral esquerdo > tutorial-pokemon-dev-lambda1-pokemon > Configuração > Gatilhos > E aqui você terá visibilidade do Endpoint de API Gateway, ou seja, a URL que necessitamos.
Com a URL em mãos, o código “start.py” ficará da seguinte forma (lembre de alterar a URL para a da sua lambda)
import json
import requests
def call_lambda(pokemon: str):
params = {"pokemon": pokemon}
response = requests.get(
"https://t6gv53ghih.execute-api.us-east-1.amazonaws.com/dev/lambda1/pokemon",
params=params,
) # coloque a SUA url (endpoint)
print(
f'\n============\nSTATUS CODE: {response.status_code}\nREASON: {response.reason}\nRESPONSE: {json.loads(response.text)["message"]}\n'
)
if __name__ == "__main__":
with open("poke-names.txt", "r") as file:
pokemons = [pokemon.rstrip("\n") for pokemon in file]
print(pokemons)
for pokemon in pokemons:
call_lambda(pokemon)
Rode seu código no terminal e ao finalizar, você terá seu S3 populado com os pokémons que foram enviados.
Conclusão
Finalizamos aqui o tutorial de como criar uma arquitetura na AWS. Passamos por vários serviços da plataforma e com isso você recebeu um conhecimento básico para ser capaz de estruturar um problema na nuvem. A grande dica a partir de agora é pensar em problemas, algoritmos, trabalhos que você já teve que realizar e pensar em como você poderia utilizar dos serviços da AWS para arquitetar uma solução em nuvem para eles.
Se você se interessou pelo assunto, temos mais sobre o tema em nosso blog.
Você sabia que este artigo foi escrito por um trainee do TerraLAB? Você sabe como a escassez de profissionais qualificados impacta as empresas de Tecnologia da Informação? Clique aqui para conhecer os desafios desta indústria e como uma parceria com o TerraLAB pode ajudar você e a sua empresa. O TerraLAB é um celeiro de talentos que prepara estudantes para o mercado de trabalho, oferecendo vivências em projetos reais e experiência nos mais modernos processos e ferramentas de desenvolvimento de software. Siga-nos nas redes sociais para saber mais!
Este artigo foi escrito por Guilherme Ferreira Rocha, revisado por Prof. Rodrigo Silva.