O blog da AWS

O runtime Python 3.12 agora disponível no AWS Lambda

Esta publicação foi escrita por Jeff Gebhart, Sr. Specialist TAM, Serverless. Adaptado para o português por Helton Ribeiro, arquiteto de aplicações cloud.

O AWS Lambda agora oferece suporte ao Python 3.12 como runtime gerenciado e imagem base de contêiner. O Python 3.12 se baseia nos aprimoramentos de desempenho lançados pela primeira vez com o Python 3.11 e adiciona vários recursos de desempenho e legibilidade da linguagem no interpretador. Com essa versão, os desenvolvedores de Python agora podem aproveitar esses novos recursos e aprimoramentos ao criar aplicativos serverless no AWS Lambda.

Você pode usar o Python 3.12 com o Powertools for AWS Lambda (Python), um kit de ferramentas para desenvolvedores para implementar as melhores práticas serverless, como observabilidade, processamento em lote, integração com Parameter Store, idempotência, feature flags, métricas do CloudWatch e logging estruturado, entre outros recursos.

Você também pode usar o Python 3.12 com o Lambda @Edge, permitindo que você personalize o conteúdo de baixa latência entregue pelo Amazon CloudFront.

Python é uma linguagem popular para criar aplicativos serverless. A versão 3.12 do Python trás várias melhorias sintáticas e em seu interpretador.

Na fase de lançamento, os novos runtimes do Lambda recebem menos uso do que os runtimes existentes e estabelecidos. Isso pode resultar em tempos de inicialização a frio (cold start) mais longos devido a redução da residência do cache nos subsistemas internos do Lambda. Os tempos de inicialização a frio geralmente melhoram nas semanas seguintes ao lançamento, a medida que o uso aumenta. Como resultado, a AWS recomenda não tirar conclusões de comparações de desempenho lado a lado com outros tempos de execução do Lambda até que o desempenho se estabilize. Como o desempenho é altamente dependente da carga de trabalho, os clientes com cargas de trabalho sensíveis ao desempenho devem realizar seus próprios testes, em vez de confiar em benchmarks de teste genéricos.

Mudanças no runtime do Lambda

Amazon Linux 2023

O runtime Python 3.12 é baseado no runtime provided.al2023, que se baseia na imagem mínima do contêiner Amazon Linux 2023. Esta atualização do sistema operacional traz várias melhorias em relação ao sistema operacional baseado no Amazon Linux 2 (AL2) usado para runtimes Python do Lambda, do Python 3.8 ao Python 3.11.

provided.al2023 contém somente os componentes essenciais necessários para instalar outros pacotes e oferece uma área de implantação menor de menos de 40 MB em comparação com mais de 100 MB das imagens baseadas em AL2 do Lambda.

Com a versão 2.34 da glibc, os clientes têm acesso a uma versão moderna da glibc, atualizada da versão 2.26 em imagens baseadas em AL2.

A imagem mínima do Amazon Linux 2023 usa microdnf como gerenciador de pacotes, com link simbólico como dnf. Isso substitui o gerenciador de pacotes yum usado em imagens anteriores baseadas em AL2. Se você implantar suas funções do Lambda como imagens de contêiner, deverá atualizar seus Dockerfiles para usar dnf em vez de yum ao atualizar para a imagem base do Python 3.12.

Além disso, curl e gnupg2 também estão incluídos como suas versões mínimas curl-minimal e gnupg2-minimal.

Saiba mais sobre o runtime provided.al2023 na postagem do blog Apresentando o runtime do Amazon Linux 2023 para o AWS Lambda e na postagem do blog de lançamento do Amazon Linux 2023.

Alteração no formato da resposta

A partir do runtime do Python 3.12, as funções retornam caracteres Unicode como parte de sua resposta JSON. As versões anteriores retornam sequências de escape para caracteres Unicode nas respostas.

Por exemplo, no Python 3.11, se você retornar uma string Unicode, como “こんにちは”, ela codifica os caracteres Unicode e retorna “\u3053\u3093\u306b\u3061\u306f”. O runtime do Python 3.12 retorna o “こんにちは” original.

Essa alteração reduz o tamanho do payload retornado pelo Lambda. No exemplo anterior, a versão codificada é de 32 bytes em comparação com 17 bytes com a string Unicode. O uso de respostas Unicode reduz o tamanho das respostas do Lambda, facilitando o ajuste de respostas maiores no limite de 6 MB de resposta do Lambda (para chamadas síncronas).

Ao atualizar para o Python 3.12, talvez seja necessário ajustar seu código em outros módulos para considerar esse novo comportamento. Se o chamador espera que a resposta esteja codificada com a sequência de escape (comportamento anterior), você precisará modificar a função para retornar a sequência de escape ou modificar o chamador para lidar com o retorno Unicode.

Processamento de extensões para um desligamento controlado (graceful shutdown)

As funções do Lambda com extensões externas agora podem se beneficiar de recursos aprimorados de desligamento controlado (graceful shutdown). Quando o serviço Lambda está prestes a encerrar o tempo de execução, ele envia um sinal SIGTERM para o runtime e, em seguida, um evento SHUTDOWN para cada extensão externa registrada.

Esses eventos são enviados sempre que um ambiente de execução é encerrado. Isso permite que você capture o sinal SIGTERM em sua função Lambda e limpe recursos, como conexões de banco de dados, que foram criadas pela função.

Para saber mais sobre o ciclo de vida do ambiente de execução do Lambda, consulte Ambiente de execução do Lambda. Mais detalhes e exemplos de como usar o Graceful Shutdown com extensões estão disponíveis no repositório AWS Samples GitHub.

Novos recursos do Python

Compreensão embutida (Comprehension inlining)

Com a implementação do PEP 709, as compreensões de dictionary, list  e set agora estão embutidas. As versões anteriores criam uma função de uso único para executar essas compreensões. A remoção dessa sobrecarga resulta em uma execução até 2x mais rápida do que a abordagem anterior.

Há algumas mudanças de comportamento nas compreensões devido a essa atualização. Por exemplo, uma chamada para a função ‘locals()’ de dentro da compreensão agora inclui objetos do escopo que a contém, não apenas dentro da compreensão em si, como nas versões anteriores. Você deve testar as funções que você está migrando de uma versão anterior do Python para o Python 3.12.

Alterações de tipagem

O Python 3.12 continua a evolução da inclusão de anotações de tipo no Python. O PEP 695 inclui uma sintaxe nova e mais compacta para classes e funções genéricas e adiciona uma nova instrução “type” para permitir a criação de alias de tipo. Os aliases de tipo são avaliados sob demanda. Isso permite que os aliases se refiram a outros tipos definidos posteriormente.

Os parâmetros de tipo são visíveis no escopo da declaração e em qualquer escopo aninhado, mas não no escopo externo.

Formalização de f-strings

Uma das maiores mudanças no Python 3.12, a formalização da sintaxe f-strings, é abordada no PEP 701. Agora, qualquer expressão válida pode estar contida em uma f-strings, incluindo outras f-strings.

Nas versões anteriores do Python, reutilizar aspas em uma f-strings resulta em erros. Com o Python 3.12, a reutilização de citações é totalmente suportada em f-strings aninhadas, como no exemplo a seguir:

>>>songs = ['Take me back to Eden', 'Alkaline', 'Ascensionism']

>>>f"Esta é a playlist: {", ".join(songs)}"

'Esta é a playlist: Take me back to Eden, Alkaline, Ascensionism'

Além disso, qualquer expressão válida do Python pode estar contida em uma f-string. Isso inclui expressões de várias linhas e a capacidade de incorporar comentários em uma f-string.

Antes do Python 3.12, o caractere “\” não era permitido em uma f-string. Isso evitava o uso da sintaxe “\n” para definir caracteres Unicode de escape no corpo de uma string f.

Melhorias no Asyncio

Há várias melhorias no módulo asyncio. Isso inclui melhorias de desempenho na gravação de soquetes e uma nova implementação de asyncio.current_task() que pode gerar uma melhoria de desempenho de 4 a 6 vezes. Os ciclos de eventos agora otimizam seus observadores filhos de acordo com o ambiente subjacente.

Usando o Python 3.12 no Lambda

Console de gerenciamento da AWS

Para usar o tempo de execução do Python 3.12 para desenvolver suas funções do Lambda, especifique um valor de parâmetro de runtime Python 3.12 ao criar ou atualizar uma função. A versão Python 3.12 agora está disponível no menu Runtime na página Criar função:

Para atualizar uma função Lambda existente para o Python 3.12, navegue até a função no console do Lambda e escolha Editar no painel de configurações do Runtime. A nova versão do Python está disponível no menu Runtime:

Imagem do contêiner AWS Lambda

Altere a versão da imagem base do Python modificando a instrução FROM em seu Dockerfile:

FROM public.ecr.aws/lambda/python:3.12
# Copy function code
COPY lambda_handler.py ${LAMBDA_TASK_ROOT}

Os clientes que executam as imagens Docker do Python 3.12 localmente, incluindo clientes que usam o AWS SAM, devem atualizar sua instalação do Docker para a versão 20.10.10 ou posterior.

AWS Serverless Application Model (AWS SAM)

No AWS SAM, defina o atributo Runtime como python3.12 para usar essa versão.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Simple Lambda Function
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Description: My Python Lambda Function
      CodeUri: my_function/
      Handler: lambda_function.lambda_handler
      Runtime: python3.12

O AWS SAM suporta a geração desse modelo com o Python 3.12 para novos aplicativos serverless usando o comando sam init. Utilize a documentação do AWS SAM para mais informações.

AWS Cloud Development Kit (AWS CDK)

No AWS CDK, defina o atributo de runtime como Runtime.PYTHON_3_12 para usar essa versão. No Python CDK:

from constructs import Construct 
from aws_cdk import ( App, Stack, aws_lambda as _lambda )

class SampleLambdaStack(Stack):
    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)
        
        base_lambda = _lambda.Function(self, 'SampleLambda', 
                                       handler='lambda_handler.handler', 
                                    runtime=_lambda.Runtime.PYTHON_3_12, 
                                 code=_lambda.Code.from_asset('lambda')) 

No TypeScript CDK:

import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda'
import * as path from 'path';
import { Construct } from 'constructs';

export class CdkStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here

    // The python3.12 enabled Lambda Function
    const lambdaFunction = new lambda.Function(this, 'python311LambdaFunction', {
      runtime: lambda.Runtime.PYTHON_3_12,
      memorySize: 512,
      code: lambda.Code.fromAsset(path.join(__dirname, '/../lambda')),
      handler: 'lambda_handler.handler'
    })
  }
}

Conclusão

O Lambda agora oferece suporte ao Python 3.12. Esta versão usa o sistema operacional Amazon Linux 2023, oferece suporte a respostas Unicode e desligamento controlado (graceful shutdown) para funções com extensões externas e recursos da linguagem Python 3.12.

Você pode criar e implantar funções usando o Python 3.12 usando o AWS Management Console, o AWS CLI , o AWS SDK, o AWS SAM, o AWS CDK ou a ferramenta Infrastructure as Code (IaC) de sua escolha. Você também pode usar a imagem base de contêiner do Python 3.12 se preferir criar e implantar suas funções usando imagens de contêiner.

O suporte ao runtime do Python 3.12 ajuda os desenvolvedores a criar aplicativos serverless mais eficientes, poderosos e escaláveis. Experimente o runtime Python 3.12 no Lambda hoje e experimente os benefícios dessa versão atualizada da linguagem.

Para obter mais recursos de aprendizado serverless, visite Serverless Land.

Este blog em português é uma tradução do blog original em inglês (link aqui).

Tradutor: Helton Ribeiro | Cloud Application Architect