Skip to main content

Lambda API Decorators CDK

AWS CDK integration for Lambda API Decorators. It discovers decorated handlers, interprets their metadata, creates independent Lambda functions, connects API Gateway routes, and applies configuration and grants through AWS CDK.

The central documentation contains the complete cross-package architecture and guides.

Installation

pip install lambda-api-decorators-cdk

The package supports Python 3.10 or newer and AWS CDK v2. The runtime package must be present at the Lambda source boundary when deployed, for example in the handler directory's requirements.txt:

lambda-api-decorators

The CDK and runtime packages are versioned independently. Installing the CDK package does not make the runtime package a Lambda dependency automatically.

Quick start

A small project can look like this:

project/
├── app.py
├── lambdas/
│   ├── __init__.py
│   ├── health.py
│   └── orders.py
└── requirements.txt

Each handler has one route. Two handlers in one file still produce two independent Lambdas; there is no runtime router.

# lambdas/orders.py
from lambda_api_decorators import GET, POST


@GET("/orders")
def list_orders(event, context):
    return {"statusCode": 200, "body": "[]"}


@POST("/orders")
def create_order(event, context):
    return {"statusCode": 201, "body": "{}"}
# app.py
from aws_cdk import App, Stack
from constructs import Construct

from lambda_api_decorators_cdk import LambdaApi, LambdaApiConfig


class OrdersStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        LambdaApi(
            self,
            "OrdersApi",
            lambda_path="lambdas",
            config=LambdaApiConfig(default_runtime="python3.14"),
        )


app = App()
OrdersStack(app, "OrdersStack")
app.synth()

lambda_path is resolved from the directory where the CDK command runs.

LambdaApi

The high-level construct builds immediately during construction. It accepts:

  • lambda_path: source directory to scan;
  • source_layout: SourceLayout.ROOT by default;
  • layers_path: optional layer-discovery directory;
  • api: a supported existing REST API or concrete aws_apigatewayv2.HttpApi;
  • api_type: ApiType.REST or ApiType.HTTP;
  • config: a LambdaApiConfig snapshot source.

REST is the default. HTTP APIs use ApiType.HTTP:

from lambda_api_decorators_cdk import ApiType, LambdaApi


LambdaApi(self, "HttpApi", lambda_path="lambdas", api_type=ApiType.HTTP)

Created and imported REST APIs are supported. Concrete HttpApi instances are supported for HTTP; the contract does not promise general support for every IHttpApi implementation. When api is supplied, its family is checked against api_type.

LambdaApiConfig

Use current defaults and registries when configuring a construct:

from aws_cdk import Duration
from lambda_api_decorators_cdk import LambdaApiConfig


config = LambdaApiConfig(
    default_runtime="python3.14",
    timeout=Duration.seconds(30),
    memory_size=512,
    common_environment={
        "SERVICE": "orders",
    },
    environment_registry={
        "production": {
            "ENVIRONMENT": "production",
        },
    },
)

The handler can select a registered environment and override the default runtime:

from lambda_api_decorators import GET, environment, runtime


@GET("/orders")
@environment("production")
@runtime("python3.12")
def orders(event, context):
    return {"statusCode": 200, "body": "[]"}

Precedence is @runtime > default_runtime. The selected environment is merged with common_environment; the selected value wins collisions. Supported runtime aliases are python3.10, python3.11, python3.12, python3.13, and python3.14.

Registries

Registry Method Decorator consumer
role_registry register_role @role
environment_registry register_environment @environment
layer_registry register_layer @layer
security_group_registry register_security_group @security_group
vpc_registry register_vpc @vpc
dynamodb_table_registry register_dynamodb_table @grant_dynamodb
s3_bucket_registry register_s3_bucket @grant_s3
authorizer_registry register_authorizer @authorizer or default

Registry keys must be non-empty strings. Duplicate keys are rejected and a missing key is an error. Configuration snapshots isolate mutable mappings while preserving the identity of supplied CDK/JSII objects.

Other supported configuration values include timeout, memory_size, default_role, vpc/vpc_subnets, layers, and security_groups. A configuration object must be complete before passing it to LambdaApi.

Roles

Role selection follows:

@role > default_role > role generated by CDK

A Lambda has one execution role. A registry supplies alternatives; it does not attach multiple roles to one function. Without a default or override, CDK creates an independent role. When one explicit role is shared, its grants are the union required by the functions that use it; CDK emits LAD_ROLE_SHARED_PERMISSIONS as a diagnostic.

DynamoDB and S3 grants

Register a CDK resource, then declare the handler's intent separately:

from aws_cdk import Stack
from aws_cdk import aws_dynamodb as dynamodb
from constructs import Construct

from lambda_api_decorators import GET, grant_dynamodb
from lambda_api_decorators_cdk import LambdaApi, LambdaApiConfig


class DataStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        orders_table = dynamodb.Table(
            self,
            "Orders",
            partition_key=dynamodb.Attribute(
                name="id", type=dynamodb.AttributeType.STRING
            ),
        )
        config = LambdaApiConfig(
            dynamodb_table_registry={"orders": orders_table},
        )
        LambdaApi(self, "DataApi", lambda_path="lambdas", config=config)


@GET("/orders")
@grant_dynamodb("orders", "read")
def list_orders(event, context):
    return {"statusCode": 200, "body": "[]"}

read produces a read grant. write represents the native cumulative read/write grant. S3 uses the same separation with s3_bucket_registry and @grant_s3; registration identifies the CDK resource and the decorator requests permission for it.

Authorizers

The recommended registry API works with REST or HTTP CDK authorizer objects. For a REST Cognito authorizer:

from aws_cdk import aws_apigateway as apigateway
from aws_cdk import aws_cognito as cognito

from lambda_api_decorators import GET, public
from lambda_api_decorators_cdk import LambdaApiConfig


cognito_pool = cognito.UserPool(self, "Users")
cognito_authorizer = apigateway.CognitoUserPoolsAuthorizer(
    self,
    "CognitoAuthorizer",
    cognito_user_pools=[cognito_pool],
)
config = LambdaApiConfig(
    default_runtime="python3.14",
    authorizer_registry={
        "cognito": cognito_authorizer,
    },
    default_authorizer="cognito",
)


@GET("/me")
def me(event, context):
    return {"statusCode": 200, "body": "{}"}


@GET("/health")
@public
def health(event, context):
    return {"statusCode": 200, "body": "ok"}

me inherits the default authorizer. @public has no parentheses and makes a REST route use AuthorizationType.NONE. With no default authorizer, routes are public and CDK emits LAD_AUTH_PUBLIC_DEFAULT. Authorizer, VPC, and role deviations are reported through consolidated diagnostics. API keys and usage plans are outside this contract.

Source layouts

SourceLayout.ROOT packages handlers relative to lambda_path. Use SourceLayout.SERVICE when the first directory is the service boundary:

from lambda_api_decorators_cdk import LambdaApi, SourceLayout


LambdaApi(
    self,
    "ServiceApi",
    lambda_path="services",
    source_layout=SourceLayout.SERVICE,
)

The Lambda source boundary also determines where requirements are installed. SERVICE requires a first-level service directory. Use enum members, not the strings "root" or "service", as the public API.

Layers

Discover direct child layer directories and reference a layer by key:

from lambda_api_decorators import GET, layer
from lambda_api_decorators_cdk import LambdaApi


LambdaApi(
    self,
    "LayeredApi",
    lambda_path="lambdas",
    layers_path="layers",
)


@GET("/orders")
@layer("orders")
def orders(event, context):
    return {"statusCode": 200, "body": "[]"}

Only visible direct children are discovery keys, and only referenced Layers are synthesized. An explicit layer_registry entry can win over discovery. A Layer shares code; it does not share roles or permissions.

ResourceBuilder

ResourceBuilder remains a supported low-level API when direct control of an API resource and build lifecycle is needed. LambdaApi is preferred for new code and delegates option resolution to isolated builder snapshots. A minimal low-level call uses the existing methods:

from aws_cdk import Duration
from lambda_api_decorators_cdk import ResourceBuilder


builder = ResourceBuilder()
builder.set_default_timeout(Duration.seconds(30))
builder.build(self, rest_api.root, "lambdas")

Examples

The integrated examples repository contains:

Releases

Tags are the source of the version through setuptools-scm, and this package is released independently from the runtime package:

git switch main
git pull --ff-only
git tag vX.Y.Z
git push origin vX.Y.Z

The tag triggers the release workflow, which tests, builds, verifies the generated version, and publishes through PyPI trusted publishing.

Release files for lambda-api-decorators-cdk 0.4.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lambda-api-decorators-cdk 0.4.6
File Size Uploaded
lambda_api_decorators_cdk-0.4.6.tar.gz 65.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lambda-api-decorators-cdk 0.4.6
File Interpreter ABI Platform
lambda_api_decorators_cdk-0.4.6-py3-none-any.whl Python 3 none any Details

Total release size: 90.3 kB

Release files / lambda_api_decorators_cdk-0.4.6.tar.gz

Download URL lambda_api_decorators_cdk-0.4.6.tar.gz
Size 65.0 kB
Tags Source
SHA-256 checksum
How to use checksums
836bc7ae087ab8e0b3104bb7c63baad2fb23b6665b6dcb9b84ddc282e3079d5b
BLAKE2b-256 checksum
How to use checksums
90f4ad879283ce22266c2488df761b8418c7af8954451f535cc67569efb6b553
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / lambda_api_decorators_cdk-0.4.6-py3-none-any.whl

Download URL lambda_api_decorators_cdk-0.4.6-py3-none-any.whl
Size 25.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
81ad000a6e5420c1f23574f1fc5e5fbba9f768a4b96e8cb688c1239173217b3e
BLAKE2b-256 checksum
How to use checksums
5e04f0339eee3c1c4b533c99b24e41c476cf9ff4cf6bad805348ba133ee43431
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.6 This release

2 release files

0.4.5

2 release files

0.4.4

2 release files

0.4.1

2 release files

0.4.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page