This post is written by Suresh Poopandi, Senior Solutions Architect, Global Life Sciences.
AWS Lambda now supports Python 3.10 as both a managed runtime and container base image. With this release, Python developers can now take advantage of new features and improvements introduced in Python 3.10 when creating serverless applications on Lambda.
Enhancements in Python 3.10 include structural pattern matching, improved error messages, and performance enhancements. This post outlines some of the benefits of Python 3.10 and how to use this version in your Lambda functions.
AWS has also published a preview Lambda container base image for Python 3.11. Customers can use this image to get an early look at Python 3.11 support in Lambda. This image is subject to change and should not be used for production workloads. To provide feedback on this image, and for future updates on Python 3.11 support, see https://github.com/aws/aws-lambda-base-images/issues/62.
Thanks to its simplicity, readability, and extensive community support, Python is a popular language for building serverless applications. The Python 3.10 release includes several new features, such as:
The faster PEP 590 vectorcall calling convention allows for quicker and more efficient Python function calls, particularly those that take multiple arguments. The specific built-in functions that benefit from this optimization include map(), filter(), reversed(), bool(), and float(). By using the vectorcall calling convention, according to Python 3.10 release notes, these inbuilt functions’ performance improved by a factor of 1.26x.
When a function is defined with annotations, these are stored in a dictionary that maps the parameter names to their respective annotations. In previous versions of Python, this dictionary was created immediately when the function was defined. However, in Python 3.10, this dictionary is created only when the annotations are accessed, which can happen when the function is called. By delaying the creation of the annotation dictionary until it is needed, Python can avoid the overhead of creating and initializing the dictionary during function definition. This can result in a significant reduction in CPU time, as the dictionary creation can be a time-consuming operation, particularly for functions with many parameters or complex annotations.
In Python 3.10, the LOAD\_ATTR instruction, which is responsible for loading attributes from objects in the code, has been improved with a new mechanism called the “per opcode cache”. This mechanism works by storing frequently accessed attributes in a cache specific to each LOAD\_ATTR instruction, which reduces the need for repeated attribute lookups. As a result of this improvement, according to Python 3.10 release notes, the LOAD\_ATTR instruction is now approximately 36% faster when accessing regular attributes and 44% faster when accessing attributes defined using the slots mechanism.
In Python, the str(), bytes(), and bytearray() constructors are used to create new instances of these types from existing data or values. Based on the result of the performance tests conducted as part of BPO-41334, constructors str(), bytes(), and bytearray() are around 30–40% faster for small objects.
Lambda functions developed with Python that read and process Gzip compressed files can gain a performance improvement. Adding \_BlocksOutputBuffer for the bz2/lzma/zlib module eliminated the overhead of resizing bz2/lzma buffers, preventing excessive memory footprint of the zlib buffer. According to Python 3.10 release notes, bz2 decompression is now 1.09x faster, lzma decompression 1.20x faster, and GzipFile read is 1.11x faster
To use the Python 3.10 runtime to develop your Lambda functions, specify a runtime parameter value Python 3.10 when creating or updating a function. Python 3.10 version is now available in the Runtime dropdown in the Create function page.
To update an existing Lambda function to Python 3.10, navigate to the function in the Lambda console, then choose Edit in the Runtime settings panel. The new version of Python is available in the Runtime dropdown:
In AWS SAM, set the Runtime attribute to python3.10 to use this version.
AWSTemplateFormatVersion: '2010-09-09'Transform: AWS::Serverless-2016-10-31Description: Simple Lambda Function MyFunction: Type: AWS::Serverless::Function Properties: Description: My Python Lambda Function CodeUri: my\_function/ Handler: lambda\_function.lambda\_handler Runtime: python3.10
AWS SAM supports the generation of this template with Python 3.10 out of the box for new serverless applications using the sam init command. Refer to the AWS SAM documentation here.
In the AWS CDK, set the runtime attribute to Runtime.PYTHON\_3\_10 to use this version. In Python:
from constructs import Constructfrom 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\_10, code=\_lambda.Code.from\_asset('lambda'))
In TypeScript:
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.10 enabled Lambda Function const lambdaFunction = new lambda.Function(this, 'python310LambdaFunction', { runtime: lambda.Runtime.PYTHON\_3\_10, memorySize: 512, code: lambda.Code.fromAsset(path.join(\_\_dirname, '/../lambda')), handler: 'lambda\_handler.handler' }) }}
Change the Python base image version by modifying FROM statement in the Dockerfile:
FROM public.ecr.aws/lambda/python:3.10# Copy function codeCOPY lambda\_handler.py ${LAMBDA\_TASK\_ROOT}
To learn more, refer to the usage tab on building functions as container images.
You can build and deploy functions using Python 3.10 using the AWS Management Console, AWS CLI, AWS SDK, AWS SAM, AWS CDK, or your choice of Infrastructure as Code (IaC). You can also use the Python 3.10 container base image if you prefer to build and deploy your functions using container images.
We are excited to bring Python 3.10 runtime support to Lambda and empower developers to build more efficient, powerful, and scalable serverless applications. Try Python 3.10 runtime in Lambda today and experience the benefits of this updated language version and take advantage of improved performance.
For more serverless learning resources, visit Serverless Land.