apig-wsgi
apig-wsgi is a Python library that wraps a standard WSGI application in an AWS Lambda handler function, allowing it to be run on AWS API Gateway (REST API or HTTP API) or an Application Load Balancer (ALB). It's currently on version 2.20.0 and sees active maintenance with several releases per year.
Common errors
-
TypeError: APIGatewayWSGI.__init__() got an unexpected keyword argument 'aws_event_type'
cause The `aws_event_type` parameter was renamed to `gateway_type` in `apig-wsgi` version 2.0.0.fixChange `aws_event_type=` to `gateway_type=` in your `APIGatewayWSGI` constructor call. Example: `APIGatewayWSGI(my_wsgi_app, gateway_type=APIGatewayEventType.API_GATEWAY_V1)` -
Runtime.ExitError: Your function exited with an error. Check the logs for details.
cause Often occurs after upgrading `apig-wsgi` to `2.x.x` from an older version when using an ALB, without explicitly setting the `gateway_type`.fixThe default `gateway_type` changed from ALB to API Gateway V1 in `apig-wsgi` 2.0.0. If you are using an ALB, you must explicitly set `apig_wsgi_handler = APIGatewayWSGI(my_wsgi_app, gateway_type=APIGatewayEventType.ALB)`. -
NameError: name 'APIGatewayEventType' is not defined
cause The `APIGatewayEventType` enum was used without being imported.fixAdd `from apig_wsgi import APIGatewayEventType` to your imports. -
Image/PDF files downloaded from API Gateway are corrupted or unreadable.
cause Binary data is not being correctly base64-encoded and flagged in the API Gateway response.fixEnsure the content type of the binary file is included in the `binary_response_content_types` parameter of `APIGatewayWSGI`. For example: `APIGatewayWSGI(my_wsgi_app, binary_response_content_types={'image/jpeg', 'application/pdf'})`. Your WSGI app must return the raw bytes.
Warnings
- breaking Version 2.0.0 dropped support for Python versions older than 3.9. Ensure your Lambda runtime environment is configured for Python 3.9 or newer.
- breaking In version 2.0.0, the `APIGatewayWSGI` constructor parameter `aws_event_type` was renamed to `gateway_type`. Additionally, the default `gateway_type` changed from `APIGatewayEventType.ALB` to `APIGatewayEventType.API_GATEWAY_V1`. Existing deployments using ALB without explicitly setting `aws_event_type=ALB` will break.
- breaking Module-level constants `TEXT_MIME_TYPES` and `BINARY_MIME_TYPES` were removed in 2.0.0. They were replaced by instance-level parameters `text_response_content_types` and `binary_response_content_types` in the `APIGatewayWSGI` constructor.
- gotcha When handling binary responses (e.g., images, PDFs), API Gateway requires the Lambda response to have `isBase64Encoded: true` and the body to be base64-encoded. `apig-wsgi` handles this if the content type is in `binary_response_content_types`, but incorrect configuration can lead to corrupted files or empty responses.
Install
-
pip install apig-wsgi
Imports
- APIGatewayWSGI
from apig_wsgi.handler import APIGatewayWSGI
from apig_wsgi import APIGatewayWSGI
- APIGatewayEventType
from apig_wsgi.constants import APIGatewayEventType
from apig_wsgi import APIGatewayEventType
Quickstart
import json
from apig_wsgi import APIGatewayWSGI, APIGatewayEventType
# A simple WSGI application function
def my_wsgi_app(environ, start_response):
status = '200 OK'
headers = [('Content-type', 'application/json')]
start_response(status, headers)
response_body = {
"message": "Hello from WSGI on Lambda!",
"path": environ.get('PATH_INFO', '/'),
"method": environ.get('REQUEST_METHOD', 'GET'),
"query_string": environ.get('QUERY_STRING', '')
}
return [json.dumps(response_body).encode('utf-8')]
# Instantiate the APIGatewayWSGI handler
# Use APIGatewayEventType.API_GATEWAY_V1 for REST API (default if omitted)
# Use APIGatewayEventType.API_GATEWAY_V2 for HTTP API
# Use APIGatewayEventType.ALB for Application Load Balancer
apig_wsgi_handler = APIGatewayWSGI(my_wsgi_app, gateway_type=APIGatewayEventType.API_GATEWAY_V1)
# This is the standard AWS Lambda handler entry point
def lambda_handler(event, context):
print(f"Received Lambda event: {json.dumps(event)}")
response = apig_wsgi_handler(event, context)
print(f"Returning Lambda response: {json.dumps(response)}")
return response
# Example of how you would test this locally or simulate an event
if __name__ == "__main__":
# Simulate an API Gateway V1 (REST API) GET event
mock_event_v1 = {
"resource": "/hello", "path": "/hello", "httpMethod": "GET",
"headers": {"Accept": "*/*", "User-Agent": "test-client"},
"queryStringParameters": {"name": "Registry"},
"requestContext": {"resourceId": "xxx", "apiId": "yyy", "resourcePath": "/hello", "httpMethod": "GET",
"requestId": "uuid", "identity": {"sourceIp": "127.0.0.1"}, "path": "/hello"},
"body": None, "isBase64Encoded": False
}
mock_context = {}
print("--- Testing API Gateway V1 event ---")
lambda_response = lambda_handler(mock_event_v1, mock_context)
print("\nSimulated API Gateway V1 Lambda Response:")
print(json.dumps(lambda_response, indent=2))