lambda-api-decorators-cdk 0.4.5__tar.gz → 0.4.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/.github/workflows/release.yml +3 -0
  2. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/AGENTS.md +8 -0
  3. lambda_api_decorators_cdk-0.4.7/PKG-INFO +405 -0
  4. lambda_api_decorators_cdk-0.4.7/README.md +357 -0
  5. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/pyproject.toml +3 -0
  6. lambda_api_decorators_cdk-0.4.7/src/lambda_api_decorators_cdk/_agent/api-contract.json +23 -0
  7. lambda_api_decorators_cdk-0.4.7/src/lambda_api_decorators_cdk/_agent/behavior.md +15 -0
  8. lambda_api_decorators_cdk-0.4.7/src/lambda_api_decorators_cdk.egg-info/PKG-INFO +405 -0
  9. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/src/lambda_api_decorators_cdk.egg-info/SOURCES.txt +5 -1
  10. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/src/lambda_api_decorators_cdk.egg-info/scm_file_list.json +5 -1
  11. lambda_api_decorators_cdk-0.4.7/src/lambda_api_decorators_cdk.egg-info/scm_version.json +8 -0
  12. lambda_api_decorators_cdk-0.4.7/tests/test_contract_packaging.py +21 -0
  13. lambda_api_decorators_cdk-0.4.7/tests/verify_contract_artifacts.py +38 -0
  14. lambda_api_decorators_cdk-0.4.5/PKG-INFO +0 -197
  15. lambda_api_decorators_cdk-0.4.5/README.md +0 -149
  16. lambda_api_decorators_cdk-0.4.5/src/lambda_api_decorators_cdk.egg-info/PKG-INFO +0 -197
  17. lambda_api_decorators_cdk-0.4.5/src/lambda_api_decorators_cdk.egg-info/scm_version.json +0 -8
  18. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/.github/workflows/tests.yml +0 -0
  19. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/.gitignore +0 -0
  20. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/LICENSE +0 -0
  21. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/setup.cfg +0 -0
  22. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/src/lambda_api_decorators_cdk/__init__.py +0 -0
  23. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/src/lambda_api_decorators_cdk/api_type.py +0 -0
  24. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/src/lambda_api_decorators_cdk/ast_helper.py +0 -0
  25. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/src/lambda_api_decorators_cdk/lambda_api.py +0 -0
  26. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/src/lambda_api_decorators_cdk/lambda_api_config.py +0 -0
  27. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/src/lambda_api_decorators_cdk/resource_builder.py +0 -0
  28. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/src/lambda_api_decorators_cdk/source_layout.py +0 -0
  29. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/src/lambda_api_decorators_cdk.egg-info/dependency_links.txt +0 -0
  30. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/src/lambda_api_decorators_cdk.egg-info/requires.txt +0 -0
  31. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/src/lambda_api_decorators_cdk.egg-info/top_level.txt +0 -0
  32. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/conftest.py +0 -0
  33. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_ast_decorator_invocations.py +0 -0
  34. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_ast_helper.py +0 -0
  35. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_auth_ast.py +0 -0
  36. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_authorization_diagnostics.py +0 -0
  37. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_authorization_http.py +0 -0
  38. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_authorization_lambda_api.py +0 -0
  39. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_authorization_resolution.py +0 -0
  40. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_authorization_rest.py +0 -0
  41. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_authorizer_config.py +0 -0
  42. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_config_override_diagnostics.py +0 -0
  43. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_config_resource_registries.py +0 -0
  44. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_http_builder.py +0 -0
  45. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_lambda_api.py +0 -0
  46. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_lambda_api_config.py +0 -0
  47. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_lambda_function.py +0 -0
  48. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_layer_autodiscovery.py +0 -0
  49. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_packaging_current.py +0 -0
  50. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_permission_resolution.py +0 -0
  51. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_public_api.py +0 -0
  52. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_python_compatibility.py +0 -0
  53. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_resource_builder_options.py +0 -0
  54. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_resource_builder_state.py +0 -0
  55. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_resource_graph.py +0 -0
  56. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_resource_registries.py +0 -0
  57. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_rest_builder.py +0 -0
  58. {lambda_api_decorators_cdk-0.4.5 → lambda_api_decorators_cdk-0.4.7}/tests/test_source_layout.py +0 -0
@@ -81,5 +81,8 @@ jobs:
81
81
  print(f"Wheel metadata version: {metadata['Version']}")
82
82
  PY
83
83
 
84
+ - name: Verify packaged API contract
85
+ run: python tests/verify_contract_artifacts.py dist
86
+
84
87
  - name: Publish distributions to PyPI
85
88
  uses: pypa/gh-action-pypi-publish@release/v1
@@ -230,3 +230,11 @@ Keep public APIs intentionally small.
230
230
  When an implementation detail is not useful to callers, keep it private.
231
231
 
232
232
  If repository behavior contradicts an assumption in the task, report the conflict rather than silently redesigning unrelated code.
233
+
234
+ ## Packaged contract
235
+
236
+ When available, use `lambda-api-decorators-development` and load the local
237
+ `_agent/api-contract.json` and `_agent/behavior.md` before changing public
238
+ behavior. Public changes update the contract and focused tests together; the
239
+ contract contains no package version or future release. Validate focused and
240
+ full tests, `compileall`, built artifacts, and `git diff --check`.
@@ -0,0 +1,405 @@
1
+ Metadata-Version: 2.4
2
+ Name: lambda-api-decorators-cdk
3
+ Version: 0.4.7
4
+ Summary: AWS CDK integration for Lambda API Decorators. Generate AWS Lambda and API Gateway infrastructure from decorated Python handlers.
5
+ Author: Mateo Marcos, Emanuel Arguinarena, Lucas Picchi
6
+ License: MIT License
7
+
8
+ Copyright (c) 2024 Lambda API Decorators CDK
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ Project-URL: Homepage, https://infrastructure-as-decorator.github.io/
28
+ Project-URL: Documentation, https://infrastructure-as-decorator.github.io/docs/api-reference/index
29
+ Project-URL: Repository, https://github.com/infrastructure-as-decorator/lambda-api-decorators-cdk
30
+ Project-URL: Bug Reports, https://github.com/infrastructure-as-decorator/lambda-api-decorators-cdk/issues
31
+ Keywords: cdk,lambda,aws,api gateway,ast
32
+ Classifier: Development Status :: 2 - Pre-Alpha
33
+ Classifier: Intended Audience :: Developers
34
+ Classifier: Framework :: AWS CDK :: 2
35
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
36
+ Classifier: Topic :: Software Development :: Build Tools
37
+ Classifier: License :: OSI Approved :: MIT License
38
+ Classifier: Programming Language :: Python :: 3.10
39
+ Classifier: Programming Language :: Python :: 3.11
40
+ Classifier: Programming Language :: Python :: 3.12
41
+ Classifier: Programming Language :: Python :: 3.13
42
+ Classifier: Programming Language :: Python :: 3.14
43
+ Requires-Python: >=3.10
44
+ Description-Content-Type: text/markdown
45
+ License-File: LICENSE
46
+ Requires-Dist: aws-cdk.aws-lambda-python-alpha
47
+ Dynamic: license-file
48
+
49
+ # Lambda API Decorators CDK
50
+
51
+ AWS CDK integration for [Lambda API Decorators](https://github.com/infrastructure-as-decorator/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.
52
+
53
+ [The central documentation](https://infrastructure-as-decorator.github.io/) contains the complete cross-package architecture and guides.
54
+
55
+ ## Installation
56
+
57
+ ```bash
58
+ pip install lambda-api-decorators-cdk
59
+ ```
60
+
61
+ The package supports Python 3.10 or newer and AWS CDK v2. The runtime package
62
+ must be present at the Lambda source boundary when deployed, for example in
63
+ the handler directory's `requirements.txt`:
64
+
65
+ ```text
66
+ lambda-api-decorators
67
+ ```
68
+
69
+ The CDK and runtime packages are versioned independently. Installing the CDK
70
+ package does not make the runtime package a Lambda dependency automatically.
71
+
72
+ ## Quick start
73
+
74
+ A small project can look like this:
75
+
76
+ ```text
77
+ project/
78
+ ├── app.py
79
+ ├── lambdas/
80
+ │ ├── __init__.py
81
+ │ ├── health.py
82
+ │ └── orders.py
83
+ └── requirements.txt
84
+ ```
85
+
86
+ Each handler has one route. Two handlers in one file still produce two
87
+ independent Lambdas; there is no runtime router.
88
+
89
+ ```python
90
+ # lambdas/orders.py
91
+ from lambda_api_decorators import GET, POST
92
+
93
+
94
+ @GET("/orders")
95
+ def list_orders(event, context):
96
+ return {"statusCode": 200, "body": "[]"}
97
+
98
+
99
+ @POST("/orders")
100
+ def create_order(event, context):
101
+ return {"statusCode": 201, "body": "{}"}
102
+ ```
103
+
104
+ ```python
105
+ # app.py
106
+ from aws_cdk import App, Stack
107
+ from constructs import Construct
108
+
109
+ from lambda_api_decorators_cdk import LambdaApi, LambdaApiConfig
110
+
111
+
112
+ class OrdersStack(Stack):
113
+ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
114
+ super().__init__(scope, construct_id, **kwargs)
115
+ LambdaApi(
116
+ self,
117
+ "OrdersApi",
118
+ lambda_path="lambdas",
119
+ config=LambdaApiConfig(default_runtime="python3.14"),
120
+ )
121
+
122
+
123
+ app = App()
124
+ OrdersStack(app, "OrdersStack")
125
+ app.synth()
126
+ ```
127
+
128
+ `lambda_path` is resolved from the directory where the CDK command runs.
129
+
130
+ ## `LambdaApi`
131
+
132
+ The high-level construct builds immediately during construction. It accepts:
133
+
134
+ - `lambda_path`: source directory to scan;
135
+ - `source_layout`: `SourceLayout.ROOT` by default;
136
+ - `layers_path`: optional layer-discovery directory;
137
+ - `api`: a supported existing REST API or concrete `aws_apigatewayv2.HttpApi`;
138
+ - `api_type`: `ApiType.REST` or `ApiType.HTTP`;
139
+ - `config`: a `LambdaApiConfig` snapshot source.
140
+
141
+ REST is the default. HTTP APIs use `ApiType.HTTP`:
142
+
143
+ ```python
144
+ from lambda_api_decorators_cdk import ApiType, LambdaApi
145
+
146
+
147
+ LambdaApi(self, "HttpApi", lambda_path="lambdas", api_type=ApiType.HTTP)
148
+ ```
149
+
150
+ Created and imported REST APIs are supported. Concrete `HttpApi` instances are
151
+ supported for HTTP; the contract does not promise general support for every
152
+ `IHttpApi` implementation. When `api` is supplied, its family is checked
153
+ against `api_type`.
154
+
155
+ ## `LambdaApiConfig`
156
+
157
+ Use current defaults and registries when configuring a construct:
158
+
159
+ ```python
160
+ from aws_cdk import Duration
161
+ from lambda_api_decorators_cdk import LambdaApiConfig
162
+
163
+
164
+ config = LambdaApiConfig(
165
+ default_runtime="python3.14",
166
+ timeout=Duration.seconds(30),
167
+ memory_size=512,
168
+ common_environment={
169
+ "SERVICE": "orders",
170
+ },
171
+ environment_registry={
172
+ "production": {
173
+ "ENVIRONMENT": "production",
174
+ },
175
+ },
176
+ )
177
+ ```
178
+
179
+ The handler can select a registered environment and override the default
180
+ runtime:
181
+
182
+ ```python
183
+ from lambda_api_decorators import GET, environment, runtime
184
+
185
+
186
+ @GET("/orders")
187
+ @environment("production")
188
+ @runtime("python3.12")
189
+ def orders(event, context):
190
+ return {"statusCode": 200, "body": "[]"}
191
+ ```
192
+
193
+ Precedence is `@runtime` > `default_runtime`. The selected environment is
194
+ merged with `common_environment`; the selected value wins collisions.
195
+ Supported runtime aliases are `python3.10`, `python3.11`, `python3.12`,
196
+ `python3.13`, and `python3.14`.
197
+
198
+ ### Registries
199
+
200
+ | Registry | Method | Decorator consumer |
201
+ | --- | --- | --- |
202
+ | `role_registry` | `register_role` | `@role` |
203
+ | `environment_registry` | `register_environment` | `@environment` |
204
+ | `layer_registry` | `register_layer` | `@layer` |
205
+ | `security_group_registry` | `register_security_group` | `@security_group` |
206
+ | `vpc_registry` | `register_vpc` | `@vpc` |
207
+ | `dynamodb_table_registry` | `register_dynamodb_table` | `@grant_dynamodb` |
208
+ | `s3_bucket_registry` | `register_s3_bucket` | `@grant_s3` |
209
+ | `authorizer_registry` | `register_authorizer` | `@authorizer` or default |
210
+
211
+ Registry keys must be non-empty strings. Duplicate keys are rejected and a
212
+ missing key is an error. Configuration snapshots isolate mutable mappings while
213
+ preserving the identity of supplied CDK/JSII objects.
214
+
215
+ Other supported configuration values include `timeout`, `memory_size`,
216
+ `default_role`, `vpc`/`vpc_subnets`, `layers`, and `security_groups`. A
217
+ configuration object must be complete before passing it to `LambdaApi`.
218
+
219
+ ## Roles
220
+
221
+ Role selection follows:
222
+
223
+ ```text
224
+ @role > default_role > role generated by CDK
225
+ ```
226
+
227
+ A Lambda has one execution role. A registry supplies alternatives; it does not
228
+ attach multiple roles to one function. Without a default or override, CDK
229
+ creates an independent role. When one explicit role is shared, its grants are
230
+ the union required by the functions that use it; CDK emits
231
+ `LAD_ROLE_SHARED_PERMISSIONS` as a diagnostic.
232
+
233
+ ## DynamoDB and S3 grants
234
+
235
+ Register a CDK resource, then declare the handler's intent separately:
236
+
237
+ ```python
238
+ from aws_cdk import Stack
239
+ from aws_cdk import aws_dynamodb as dynamodb
240
+ from constructs import Construct
241
+
242
+ from lambda_api_decorators import GET, grant_dynamodb
243
+ from lambda_api_decorators_cdk import LambdaApi, LambdaApiConfig
244
+
245
+
246
+ class DataStack(Stack):
247
+ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
248
+ super().__init__(scope, construct_id, **kwargs)
249
+ orders_table = dynamodb.Table(
250
+ self,
251
+ "Orders",
252
+ partition_key=dynamodb.Attribute(
253
+ name="id", type=dynamodb.AttributeType.STRING
254
+ ),
255
+ )
256
+ config = LambdaApiConfig(
257
+ dynamodb_table_registry={"orders": orders_table},
258
+ )
259
+ LambdaApi(self, "DataApi", lambda_path="lambdas", config=config)
260
+
261
+
262
+ @GET("/orders")
263
+ @grant_dynamodb("orders", "read")
264
+ def list_orders(event, context):
265
+ return {"statusCode": 200, "body": "[]"}
266
+ ```
267
+
268
+ `read` produces a read grant. `write` represents the native cumulative
269
+ read/write grant. S3 uses the same separation with `s3_bucket_registry` and
270
+ `@grant_s3`; registration identifies the CDK resource and the decorator
271
+ requests permission for it.
272
+
273
+ ## Authorizers
274
+
275
+ The recommended registry API works with REST or HTTP CDK authorizer objects.
276
+ For a REST Cognito authorizer:
277
+
278
+ ```python
279
+ from aws_cdk import aws_apigateway as apigateway
280
+ from aws_cdk import aws_cognito as cognito
281
+
282
+ from lambda_api_decorators import GET, public
283
+ from lambda_api_decorators_cdk import LambdaApiConfig
284
+
285
+
286
+ cognito_pool = cognito.UserPool(self, "Users")
287
+ cognito_authorizer = apigateway.CognitoUserPoolsAuthorizer(
288
+ self,
289
+ "CognitoAuthorizer",
290
+ cognito_user_pools=[cognito_pool],
291
+ )
292
+ config = LambdaApiConfig(
293
+ default_runtime="python3.14",
294
+ authorizer_registry={
295
+ "cognito": cognito_authorizer,
296
+ },
297
+ default_authorizer="cognito",
298
+ )
299
+
300
+
301
+ @GET("/me")
302
+ def me(event, context):
303
+ return {"statusCode": 200, "body": "{}"}
304
+
305
+
306
+ @GET("/health")
307
+ @public
308
+ def health(event, context):
309
+ return {"statusCode": 200, "body": "ok"}
310
+ ```
311
+
312
+ `me` inherits the default authorizer. `@public` has no parentheses and makes a
313
+ REST route use `AuthorizationType.NONE`. With no default authorizer, routes
314
+ are public and CDK emits `LAD_AUTH_PUBLIC_DEFAULT`. Authorizer, VPC, and role
315
+ deviations are reported through consolidated diagnostics. API keys and usage
316
+ plans are outside this contract.
317
+
318
+ ## Source layouts
319
+
320
+ `SourceLayout.ROOT` packages handlers relative to `lambda_path`. Use
321
+ `SourceLayout.SERVICE` when the first directory is the service boundary:
322
+
323
+ ```python
324
+ from lambda_api_decorators_cdk import LambdaApi, SourceLayout
325
+
326
+
327
+ LambdaApi(
328
+ self,
329
+ "ServiceApi",
330
+ lambda_path="services",
331
+ source_layout=SourceLayout.SERVICE,
332
+ )
333
+ ```
334
+
335
+ The Lambda source boundary also determines where requirements are installed.
336
+ `SERVICE` requires a first-level service directory. Use enum members, not the
337
+ strings `"root"` or `"service"`, as the public API.
338
+
339
+ ## Layers
340
+
341
+ Discover direct child layer directories and reference a layer by key:
342
+
343
+ ```python
344
+ from lambda_api_decorators import GET, layer
345
+ from lambda_api_decorators_cdk import LambdaApi
346
+
347
+
348
+ LambdaApi(
349
+ self,
350
+ "LayeredApi",
351
+ lambda_path="lambdas",
352
+ layers_path="layers",
353
+ )
354
+
355
+
356
+ @GET("/orders")
357
+ @layer("orders")
358
+ def orders(event, context):
359
+ return {"statusCode": 200, "body": "[]"}
360
+ ```
361
+
362
+ Only visible direct children are discovery keys, and only referenced Layers
363
+ are synthesized. An explicit `layer_registry` entry can win over discovery.
364
+ A Layer shares code; it does not share roles or permissions.
365
+
366
+ ## `ResourceBuilder`
367
+
368
+ `ResourceBuilder` remains a supported low-level API when direct control of an
369
+ API resource and build lifecycle is needed. `LambdaApi` is preferred for new
370
+ code and delegates option resolution to isolated builder snapshots. A minimal
371
+ low-level call uses the existing methods:
372
+
373
+ ```python
374
+ from aws_cdk import Duration
375
+ from lambda_api_decorators_cdk import ResourceBuilder
376
+
377
+
378
+ builder = ResourceBuilder()
379
+ builder.set_default_timeout(Duration.seconds(30))
380
+ builder.build(self, rest_api.root, "lambdas")
381
+ ```
382
+
383
+ ## Examples
384
+
385
+ The integrated examples repository contains:
386
+
387
+ - [Quickstart REST](https://github.com/infrastructure-as-decorator/lambda-api-decorators-examples/tree/main/quickstart-rest)
388
+ - [HTTP API](https://github.com/infrastructure-as-decorator/lambda-api-decorators-examples/tree/main/http-api)
389
+ - [REST API DynamoDB](https://github.com/infrastructure-as-decorator/lambda-api-decorators-examples/tree/main/rest-api-dynamodb)
390
+ - [REST API Cognito authorizer](https://github.com/infrastructure-as-decorator/lambda-api-decorators-examples/tree/main/rest-api-cognito-authorizer)
391
+
392
+ ## Releases
393
+
394
+ Tags are the source of the version through `setuptools-scm`, and this package
395
+ is released independently from the runtime package:
396
+
397
+ ```bash
398
+ git switch main
399
+ git pull --ff-only
400
+ git tag vX.Y.Z
401
+ git push origin vX.Y.Z
402
+ ```
403
+
404
+ The tag triggers the release workflow, which tests, builds, verifies the
405
+ generated version, and publishes through PyPI trusted publishing.