You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Throughout the documentation we had a bit of inconsistency around
admonitions.
As such we added few rules to keep the consistency which will improve
the UX:
* we should use `???+` instead of `!!!` so we can have a collapse block
(default open)
* for admonitions with default title, we should write the description
on a new line
* for admonitions which has a custom title as well as a description, we
should adhere to the format `<admonitions type>: <custom title>`.
E.g - for a tip admonitions with a custom title "Did you know?" and
description of "Powertools is a brilliant library"
```
???+ tip "Tip: Did you know?"
Powertools is a brilliant library
```
Copy file name to clipboardExpand all lines: docs/core/event_handler/api_gateway.md
+28-17
Original file line number
Diff line number
Diff line change
@@ -71,7 +71,8 @@ You can define your functions to match a path and HTTP method, when you use the
71
71
72
72
Here's an example where we have two separate functions to resolve two paths: `/hello`.
73
73
74
-
!!! info "We automatically serialize `Dict` responses as JSON, trim whitespaces for compact responses, and set content-type to `application/json`"
74
+
???+ info
75
+
We automatically serialize `Dict` responses as JSON, trim whitespaces for compact responses, and set content-type to `application/json`.
75
76
76
77
=== "app.py"
77
78
@@ -309,13 +310,15 @@ You can also nest paths as configured earlier in [our sample infrastructure](#re
309
310
310
311
#### Catch-all routes
311
312
312
-
!!! note "We recommend having explicit routes whenever possible; use catch-all routes sparingly"
313
+
???+ note
314
+
We recommend having explicit routes whenever possible; use catch-all routes sparingly.
313
315
314
316
You can use a regex string to handle an arbitrary number of paths within a request, for example `.+`.
315
317
316
318
You can also combine nested paths with greedy regex to catch in between routes.
317
319
318
-
!!! warning "We will choose the more explicit registered route that match incoming event"
320
+
???+ warning
321
+
We will choose the more explicit registered route that match incoming event.
319
322
320
323
=== "app.py"
321
324
@@ -421,8 +424,8 @@ HTTP methods.
421
424
}
422
425
```
423
426
424
-
!!! note "It is usually better to have separate functions for each HTTP method, as the functionality tends to differ
425
-
depending on which method is used."
427
+
???+ note
428
+
It is usually better to have separate functions for each HTTP method, as the functionality tends to differ depending on which method is used.
426
429
427
430
### Accessing request details
428
431
@@ -569,7 +572,8 @@ You can use **`exception_handler`** decorator with any Python exception. This al
569
572
570
573
You can easily raise any HTTP Error back to the client using `ServiceError` exception.
571
574
572
-
!!! info "If you need to send custom headers, use [Response](#fine-grained-responses) class instead."
575
+
???+ info
576
+
If you need to send custom headers, use [Response](#fine-grained-responses) class instead.
573
577
574
578
Additionally, we provide pre-defined errors for the most popular ones such as HTTP 400, 401, 404, 500.
575
579
@@ -664,7 +668,8 @@ This will lead to a HTTP 404 despite having your Lambda configured correctly. Se
664
668
}
665
669
```
666
670
667
-
Note: After removing a path prefix with `strip_prefixes`, the new root path will automatically be mapped to the path argument of `/`. For example, when using `strip_prefixes` value of `/pay`, there is no difference between a request path of `/pay` and `/pay/`; and the path argument would be defined as `/`.
671
+
???+ note
672
+
After removing a path prefix with `strip_prefixes`, the new root path will automatically be mapped to the path argument of `/`. For example, when using `strip_prefixes` value of `/pay`, there is no difference between a request path of `/pay` and `/pay/`; and the path argument would be defined as `/`.
668
673
669
674
## Advanced
670
675
@@ -732,7 +737,8 @@ This will ensure that CORS headers are always returned as part of the response w
732
737
}
733
738
```
734
739
735
-
!!! tip "Optionally disable class on a per path basis with `cors=False` parameter"
740
+
???+ tip
741
+
Optionally disable class on a per path basis with `cors=False` parameter.
736
742
737
743
#### Pre-flight
738
744
@@ -744,7 +750,8 @@ For convenience, we automatically handle that for you as long as you [setup CORS
744
750
745
751
For convenience, these are the default values when using `CORSConfig` to enable CORS:
746
752
747
-
!!! warning "Always configure `allow_origin` when using in production"
753
+
???+ warning
754
+
Always configure `allow_origin` when using in production.
@@ -797,7 +804,8 @@ You can use the `Response` class to have full control over the response, for exa
797
804
798
805
You can compress with gzip and base64 encode your responses via `compress` parameter.
799
806
800
-
!!! warning "The client must send the `Accept-Encoding` header, otherwise a normal response will be sent"
807
+
???+ warning
808
+
The client must send the `Accept-Encoding` header, otherwise a normal response will be sent.
801
809
802
810
=== "app.py"
803
811
@@ -847,7 +855,8 @@ For convenience, we automatically base64 encode binary responses. You can also u
847
855
848
856
Like `compress` feature, the client must send the `Accept` header with the correct media type.
849
857
850
-
!!! warning "This feature requires API Gateway to configure binary media types, see [our sample infrastructure](#required-resources) for reference"
858
+
???+ warning
859
+
This feature requires API Gateway to configure binary media types, see [our sample infrastructure](#required-resources) for reference.
851
860
852
861
=== "app.py"
853
862
@@ -942,7 +951,8 @@ You can enable debug mode via `debug` param, or via `POWERTOOLS_EVENT_HANDLER_DE
942
951
943
952
This will enable full tracebacks errors in the response, print request and responses, and set CORS in development mode.
944
953
945
-
!!! warning "This might reveal sensitive information in your logs and relax CORS restrictions, use it sparingly."
954
+
???+ warning
955
+
This might reveal sensitive information in your logs and relax CORS restrictions, use it sparingly.
946
956
947
957
=== "debug.py"
948
958
@@ -1276,21 +1286,22 @@ Event Handler naturally leads to a single Lambda function handling multiple rout
1276
1286
1277
1287
Both single (monolithic) and multiple functions (micro) offer different set of trade-offs worth knowing.
1278
1288
1279
-
!!! tip "TL;DR. Start with a monolithic function, add additional functions with new handlers, and possibly break into micro functions if necessary."
1289
+
???+ tip
1290
+
TL;DR. Start with a monolithic function, add additional functions with new handlers, and possibly break into micro functions if necessary.
1280
1291
1281
1292
#### Monolithic function
1282
1293
1283
1294

1284
1295
1285
1296
A monolithic function means that your final code artifact will be deployed to a single function. This is generally the best approach to start.
1286
1297
1287
-
**Benefits**
1298
+
_**Benefits**_
1288
1299
1289
1300
***Code reuse**. It's easier to reason about your service, modularize it and reuse code as it grows. Eventually, it can be turned into a standalone library.
1290
1301
***No custom tooling**. Monolithic functions are treated just like normal Python packages; no upfront investment in tooling.
1291
1302
***Faster deployment and debugging**. Whether you use all-at-once, linear, or canary deployments, a monolithic function is a single deployable unit. IDEs like PyCharm and VSCode have tooling to quickly profile, visualize, and step through debug any Python package.
1292
1303
1293
-
**Downsides**
1304
+
_**Downsides**_
1294
1305
1295
1306
***Cold starts**. Frequent deployments and/or high load can diminish the benefit of monolithic functions depending on your latency requirements, due to [Lambda scaling model](https://docs.aws.amazon.com/lambda/latest/dg/invocation-scaling.html){target="_blank"}. Always load test to pragmatically balance between your customer experience and development cognitive load.
1296
1307
***Granular security permissions**. The micro function approach enables you to use fine-grained permissions & access controls, separate external dependencies & code signing at the function level. Conversely, you could have multiple functions while duplicating the final code artifact in a monolithic approach.
@@ -1303,13 +1314,13 @@ A monolithic function means that your final code artifact will be deployed to a
1303
1314
1304
1315
A micro function means that your final code artifact will be different to each function deployed. This is generally the approach to start if you're looking for fine-grain control and/or high load on certain parts of your service.
1305
1316
1306
-
**Benefits**
1317
+
_**Benefits**_
1307
1318
1308
1319
***Granular scaling**. A micro function can benefit from the [Lambda scaling model](https://docs.aws.amazon.com/lambda/latest/dg/invocation-scaling.html){target="_blank"} to scale differently depending on each part of your application. Concurrency controls and provisioned concurrency can also be used at a granular level for capacity management.
1309
1320
***Discoverability**. Micro functions are easier do visualize when using distributed tracing. Their high-level architectures can be self-explanatory, and complexity is highly visible — assuming each function is named to the business purpose it serves.
1310
1321
***Package size**. An independent function can be significant smaller (KB vs MB) depending on external dependencies it require to perform its purpose. Conversely, a monolithic approach can benefit from [Lambda Layers](https://docs.aws.amazon.com/lambda/latest/dg/invocation-layers.html){target="_blank"} to optimize builds for external dependencies.
1311
1322
1312
-
**Downsides**
1323
+
_**Downsides**_
1313
1324
1314
1325
***Upfront investment**. Python ecosystem doesn't use a bundler — you need a custom build tooling to ensure each function only has what it needs and account for [C bindings for runtime compatibility](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html){target="_blank"}. Operations become more elaborate — you need to standardize tracing labels/annotations, structured logging, and metrics to pinpoint root causes.
1315
1326
- Engineering discipline is necessary for both approaches. Micro-function approach however requires further attention in consistency as the number of functions grow, just like any distributed system.
Copy file name to clipboardExpand all lines: docs/core/event_handler/appsync.md
+9-7
Original file line number
Diff line number
Diff line change
@@ -27,10 +27,10 @@ You must have an existing AppSync GraphQL API and IAM permissions to invoke your
27
27
28
28
This is the sample infrastructure we are using for the initial examples with a AppSync Direct Lambda Resolver.
29
29
30
-
=== "schema.graphql"
30
+
???+ tip "Tip: Designing GraphQL Schemas for the first time?"
31
+
Visit [AWS AppSync schema documentation](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html){target="_blank"} for understanding how to define types, nesting, and pagination.
31
32
32
-
!!! tip "Designing GraphQL Schemas for the first time?"
33
-
Visit [AWS AppSync schema documentation](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html){target="_blank"} for understanding how to define types, nesting, and pagination.
@@ -176,7 +176,8 @@ You can define your functions to match GraphQL types and fields with the `app.re
176
176
177
177
Here's an example where we have two separate functions to resolve `getTodo` and `listTodos` fields within the `Query` type. For completion, we use Scalar type utilities to generate the right output based on our schema definition.
178
178
179
-
!!! info "GraphQL arguments are passed as function arguments"
179
+
???+ info
180
+
GraphQL arguments are passed as function arguments.
180
181
181
182
=== "app.py"
182
183
@@ -456,8 +457,8 @@ Assuming you have [Amplify CLI installed](https://docs.amplify.aws/cli/start/ins
456
457
457
458
[Create two new basic Python functions](https://docs.amplify.aws/cli/function#set-up-a-function){target="_blank"} via `amplify add function`.
458
459
459
-
!!! note "Amplify CLI generated functions use `Pipenv` as a dependency manager"
460
-
Your function source code is located at **`amplify/backend/function/your-function-name`**.
460
+
???+ note
461
+
Amplify CLI generated functions use `Pipenv` as a dependency manager. Your function source code is located at **`amplify/backend/function/your-function-name`**.
461
462
462
463
Within your function's folder, add Lambda Powertools as a dependency with `pipenv install aws-lambda-powertools`.
463
464
@@ -713,7 +714,8 @@ You can subclass `AppSyncResolverEvent` to bring your own set of methods to hand
713
714
714
715
### Split operations with Router
715
716
716
-
!!! tip "Read the **[considerations section for trade-offs between monolithic and micro functions](./api_gateway.md#considerations){target="_blank"}**, as it's also applicable here."
717
+
???+ tip
718
+
Read the **[considerations section for trade-offs between monolithic and micro functions](./api_gateway.md#considerations){target="_blank"}**, as it's also applicable here.
717
719
718
720
As you grow the number of related GraphQL operations a given Lambda function should handle, it is natural to split them into separate files to ease maintenance - That's where the `Router` feature is useful.
0 commit comments