Introdução à AWS Lambda com Python (Boto3)
Conceitos Básicos da AWS Lambda
AWS Lambda é um serviço na nuvem da Amazon Web Services (AWS) que permite executar códigos diretamente nos Serviços da AWS ou em aplicações existentes. Este conceito simplifica a criação de aplicativos escaláveis e flexíveis. Para utilizar Lambda efetivamente, é importante entender alguns conceitos básicos como funções lambda, manipuladores de função e integração entre serviços.
Funções Lambda
Funções Lambda são unidades de código isoladas que podem ser chamadas por outros serviços ou APIs da AWS. Elas não têm estado persistente e são executadas apenas quando solicitados. As funções Lambda suportam várias linguagens incluindo Python, Node.js, Java, Go e mais.
Manipuladores de Função
Manipuladores de função são métodos definidos pelo usuário para lidar com as entradas recebidas pela função Lambda durante uma execução. Eles permitem ao desenvolvedor escrever o comportamento específico da funcionalidade desejada dentro das funções Lambda sem precisar se preocupar com detalhes do funcionamento interno dos servidores.
Integração Entre Serviços
A integração entre serviços envolve chamar funções Lambda através de outras APIs ou serviços da AWS. Isso pode ser feito usando parâmetros passados na entrada da função Lambda ou utilizando integrations específicas fornecidas pelos diferentes serviços.
Criando e Invocando Funções Lambda em Python (Boto3)
Para criar e invocar funções Lambda no Python, você precisa utilizar a biblioteca Boto3, um cliente SDK oficialmente gerenciado pela Amazon Web Services. Aqui está como fazer isso:
Instale a Biblioteca:
pip install boto3Conecte-se à sua Conta AWS: Certifique-se de que seu ambiente estiver configurado corretamente para autenticar contra sua conta AWS.
Crie uma Nova Função Lambda: Use
boto3.client('lambda')para acessar as operações relacionadas às suas funções lambda.Carregue o Codigo Manipulador: O código manipulador é responsável por processar os dados recebidos durante a execução da função. Ele deve estar disponível localmente antes de carregar para a função Lambda.
Invoca a Função Lambda: Você pode chamar a função Lambda com qualquer número de parâmetros definidos na entrada do evento.
Trabalhe Com Integrações entre Serviços: Para integrar com outros serviços ou APIs, use integrações específicas fornecidas pelos diferentes servidores.
Exemplos Práticos
Definindo um Manipulador Básico em Python (Boto3)
import json
import logging
from botocore.exceptions import ClientError
# Configuração do logger
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def handler(event, context):
"""
AWS Lambda Handler
"""
try:
# Log do evento recebido
logger.info("Evento recebido: %s", json.dumps(event))
# Verifica se o campo existe
if 'number' not in event:
raise ValueError("Campo 'number' não encontrado no evento")
number = event['number']
# Validação do tipo
if not isinstance(number, int):
raise TypeError(
f"O campo 'number' deve ser inteiro. Valor recebido: {number}"
)
# Validação de valor positivo
if number < 0:
raise ValueError(
f"O número deve ser positivo. Valor recebido: {number}"
)
# Exemplo de processamento
result = calculate_factorial(number)
# Retorno de sucesso
response = {
"statusCode": 200,
"body": json.dumps({
"message": "Processamento realizado com sucesso",
"input": number,
"result": result
})
}
logger.info("Resposta gerada com sucesso")
return response
except ValueError as ve:
logger.error("Erro de validação: %s", str(ve))
return {
"statusCode": 400,
"body": json.dumps({
"error": "ValidationError",
"message": str(ve)
})
}
except TypeError as te:
logger.error("Erro de tipo: %s", str(te))
return {
"statusCode": 400,
"body": json.dumps({
"error": "TypeError",
"message": str(te)
})
}
except ClientError as ce:
logger.error("Erro AWS ClientError: %s", str(ce))
return {
"statusCode": 500,
"body": json.dumps({
"error": "AWSClientError",
"message": str(ce)
})
}
except Exception as e:
logger.exception("Erro inesperado")
return {
"statusCode": 500,
"body": json.dumps({
"error": "InternalServerError",
"message": str(e)
})
}
def calculate_factorial(number):
"""
Exemplo de função de processamento
"""
factorial = 1
for i in range(1, number + 1):
factorial *= i
return factorial
Exemplo de saída
{
"message": "Processamento realizado com sucesso",
"input": 5,
"result": 120
}
Este exemplo define uma função Lambda que aceita um número como entrada e retorna o resultado de incrementar esse número por 1.
Invoca a Função Lambda com Parâmetros
aws lambda invoke --function-name MyFunctionName \
--log-type Tail \
--payload '{"number": 5}' response_body.json
Onde MyFunctionName é o nome da sua função Lambda e você pode substituir "number" pelo valor desejado para testes ou integração futura.
Trabalhando Com Integrações entre Serviços (Exemplo)
Supondo que temos uma API Gateway integrada à nossa função Lambda, podemos chamar a função Lambda diretamente através dessa integração. Aqui está um breve exemplo do código manipulador em Python Boto3 que processa os dados recebidos pela API Gateway:
import json
import logging
from botocore.exceptions import ClientError
# Configuração de logs
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# Dicionário de ações disponíveis
ACTIONS = {
'plus': lambda x, y: x + y,
'minus': lambda x, y: x - y,
'times': lambda x, y: x * y,
'divided-by': lambda x, y: x / y
}
def build_response(status_code, body):
"""
Padroniza resposta HTTP
"""
return {
"statusCode": status_code,
"headers": {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
},
"body": json.dumps(body)
}
def validate_input(data):
"""
Valida payload recebido
"""
required_fields = ['x', 'y', 'action']
for field in required_fields:
if field not in data:
raise ValueError(f"Campo obrigatório ausente: {field}")
if not isinstance(data['x'], int):
raise TypeError(f"x deve ser inteiro. Recebido: {data['x']}")
if not isinstance(data['y'], int):
raise TypeError(f"y deve ser inteiro. Recebido: {data['y']}")
if data['action'] not in ACTIONS:
raise ValueError(
f"Ação inválida. Permitidas: {list(ACTIONS.keys())}"
)
if data['action'] == 'divided-by' and data['y'] == 0:
raise ValueError("Divisão por zero não permitida")
def execute_operation(action, x, y):
"""
Executa operação matemática
"""
func = ACTIONS[action]
return func(x, y)
def handler(event, context):
"""
AWS Lambda Handler
"""
try:
logger.info("Evento recebido: %s", json.dumps(event))
# Quando integrado ao API Gateway
body = event.get('body')
if body:
body = json.loads(body)
else:
body = event
# Validação
validate_input(body)
x = body['x']
y = body['y']
action = body['action']
logger.info(
"Executando operação %s com valores %s e %s",
action,
x,
y
)
# Processamento
result = execute_operation(action, x, y)
response = {
"success": True,
"operation": action,
"input": {
"x": x,
"y": y
},
"result": result
}
logger.info("Operação executada com sucesso")
return build_response(200, response)
except ValueError as ve:
logger.error("Erro de validação: %s", str(ve))
return build_response(400, {
"success": False,
"error": "ValidationError",
"message": str(ve)
})
except TypeError as te:
logger.error("Erro de tipo: %s", str(te))
return build_response(400, {
"success": False,
"error": "TypeError",
"message": str(te)
})
except ClientError as ce:
logger.error("Erro AWS: %s", str(ce))
return build_response(500, {
"success": False,
"error": "AWSClientError",
"message": str(ce)
})
except Exception as e:
logger.exception("Erro interno")
return build_response(500, {
"success": False,
"error": "InternalServerError",
"message": str(e)
})
Neste exemplo, o manipulador de função lida com operações matemáticas básicas (soma, subtração, multiplicação e divisão). Ele usa uma lista ACTIONS que define funções para cada operação desejada. O código também captura exceções como ZeroDivisionError e retorna um status HTTP adequado ao cliente.
Bônus: Configuração de API Gateway
Passo 1 - Criar API Gateway
Criar função
Clique em:
Create function
Configuração
Escolha:
Author from scratch
Nome
calculator-api
Runtime
Escolha:
Python 3.12
Architecture
x86_64
Permissões
Deixe:
Create a new role with basic Lambda permissions
Isso cria automaticamente:
- IAM Role
- CloudWatch permissions
- Clique em:
- Create function
Passo 2 - Inserir código Python
# No editor da Lambda, adicione o código de exemplo que citamos
Passo 3 - Deploy da Lambda
Clique em:
Deploy
Pronto. Sua Lambda já existe.
Passo 4 - Criar API Gateway
Agora vamos expor ela via HTTP.
No menu lateral da Lambda:
Configuration
→ Triggers
→ Add trigger
Passo 5 - Escolher API Gateway
Selecione:
API Gateway
Passo 6 - Configuração da API
API type: Escolha "HTTP API"
Security: Escolha "Open" (sem autenticação, mas claro, altere isso após a validação)
Additional settings: Marque "Enable API Gateway CORS"
Passo 7 - Adicionar Trigger
Add
AWS automaticamente:
- ✅ cria API Gateway
- ✅ cria integração
- ✅ cria rota
- ✅ cria endpoint público
Será gerado uma url parecida com essa: "https://abc123.execute-api.us-east-1.amazonaws.com/default/calculator-api"
Passo 8 - Testar
curl -X POST \
https://SEU-ENDPOINT \
-H "Content-Type: application/json" \
-d '{
"x": 10,
"y": 5,
"action": "times"
}'
Conclusão
Compreender os conceitos básicos da AWS Lambda é fundamental antes de começar a trabalhar com funções Lambda em Python Boto3. Ao usar esses princípios fundamentais, você pode criar soluções escaláveis e flexíveis sem precisar gerenciar servidores ou preocupações técnicas adicionais.
Expanda ainda mais seus conhecimentos sobre AWS Cloud Development, certifique-se 👉 AWS Certified Cloud Practitioner
Referencias tecnicas
- [Fonte 1] Criar sua primeira função do Lambda - AWS Lambda
- [Fonte 2] Criar funções do Lambda com Python - AWS Lambda
- [Fonte 3] Exemplos de Lambda usando o SDK para Python (Boto3) - AWS Exemplos de código do SDK
- [Fonte 4] Definir o manipulador de função do Lambda em Python - AWS Lambda
- [Fonte 5] Definir o manipulador de função do Lambda em Node.js - AWS Lambda
- [Fonte 6] Criar uma aplicação de processamento de arquivos com tecnologia sem servidor - AWS Lambda
- Contexto adicional fornecido pelo usuario