Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(apigateway): fix sample layout provided #864

Merged
merged 2 commits into from
Dec 3, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 30 additions & 39 deletions docs/core/event_handler/api_gateway.md
Original file line number Diff line number Diff line change
Expand Up @@ -1027,43 +1027,42 @@ When necessary, you can set a prefix when including a router object. This means

#### Sample layout

!!! info "We use ALB to demonstrate that the UX remains the same"

This sample project contains an Users function with two distinct set of routes, `/users` and `/health`. The layout optimizes for code sharing, no custom build tooling, and it uses [Lambda Layers](../../index.md#lambda-layer) to install Lambda Powertools.
This sample project contains a Users function with two distinct set of routes, `/users` and `/health`. The layout optimizes for code sharing, no custom build tooling, and it uses [Lambda Layers](../../index.md#lambda-layer) to install Lambda Powertools.

=== "Project layout"


```python hl_lines="6 8 10-13"
```python hl_lines="1 8 10 12-15"
.
├── Pipfile # project app & dev dependencies; poetry, pipenv, etc.
├── Pipfile # project app & dev dependencies; poetry, pipenv, etc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we update to poetry pyproject.tomo since we're gonna update the sample cookiecutter already?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@heitorlessa - currently I like Pipefile as this is the default for SAM cli and Amplify templates. However I am cool to switch to Poetry

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So let's keep as-is until we migrate others.

├── Pipfile.lock
├── mypy.ini # namespace_packages = True
├── .env # VSCode only. PYTHONPATH="users:${PYTHONPATH}"
├── users
│ ├── requirements.txt # sam build detect it automatically due to CodeUri: users, e.g. pipenv lock -r > users/requirements.txt
│ ├── lambda_function.py # this will be our users Lambda fn; it could be split in folders if we want separate fns same code base
│ ├── constants.py
│ └── routers # routers module
├── README.md
├── src
│ ├── __init__.py
│ ├── users.py # /users routes, e.g. from routers import users; users.router
│ ├── health.py # /health routes, e.g. from routers import health; health.router
├── template.yaml # SAM template.yml, CodeUri: users, Handler: users.main.lambda_handler
│ ├── requirements.txt # sam build detect it automatically due to CodeUri: src, e.g. pipenv lock -r > src/requirements.txt
│ └── users
│ ├── __init__.py
│ ├── main.py # this will be our users Lambda fn; it could be split in folders if we want separate fns same code base
│ └── routers # routers module
│ ├── __init__.py
│ ├── health.py # /users routes, e.g. from routers import users; users.router
│ └── users.py # /users routes, e.g. from .routers import users; users.router
├── template.yml # SAM template.yml, CodeUri: src, Handler: users.main.lambda_handler
└── tests
├── __init__.py
├── unit
│ ├── __init__.py
│ └── test_users.py # unit tests for the users router
│ └── test_health.py # unit tests for the health router
│ └── test_users.py # unit tests for the users router
│ └── test_health.py # unit tests for the health router
└── functional
├── __init__.py
├── conftest.py # pytest fixtures for the functional tests
└── test_lambda_function.py # functional tests for the main lambda handler
├── conftest.py # pytest fixtures for the functional tests
└── test_main.py # functional tests for the main lambda handler
```

=== "template.yml"

```yaml hl_lines="20-21"
```yaml hl_lines="22-23"
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Example service with multiple routes
Expand All @@ -1073,6 +1072,8 @@ This sample project contains an Users function with two distinct set of routes,
MemorySize: 512
Runtime: python3.9
Tracing: Active
Architectures:
- x86_64
Environment:
Variables:
LOG_LEVEL: INFO
Expand All @@ -1083,11 +1084,11 @@ This sample project contains an Users function with two distinct set of routes,
UsersService:
Type: AWS::Serverless::Function
Properties:
Handler: lambda_function.lambda_handler
CodeUri: users
Handler: users.main.lambda_handler
CodeUri: src
Layers:
# Latest version: https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer
- !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPython:3
- !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPython:4
Events:
ByUser:
Type: Api
Expand Down Expand Up @@ -1119,7 +1120,7 @@ This sample project contains an Users function with two distinct set of routes,
Value: !GetAtt UsersService.Arn
```

=== "users/lambda_function.py"
=== "src/users/main.py"

```python hl_lines="9 15-16"
from typing import Dict
Expand All @@ -1130,23 +1131,23 @@ This sample project contains an Users function with two distinct set of routes,
from aws_lambda_powertools.logging.correlation_paths import APPLICATION_LOAD_BALANCER
from aws_lambda_powertools.utilities.typing import LambdaContext

from routers import health, users
from .routers import health, users

tracer = Tracer()
logger = Logger()
app = ApiGatewayResolver(proxy_type=ProxyEventType.ALBEvent)
app = ApiGatewayResolver(proxy_type=ProxyEventType.APIGatewayProxyEvent)

app.include_router(health.router)
app.include_router(users.router)


@logger.inject_lambda_context(correlation_id_path=APPLICATION_LOAD_BALANCER)
@logger.inject_lambda_context(correlation_id_path=API_GATEWAY_REST)
@tracer.capture_lambda_handler
def lambda_handler(event: Dict, context: LambdaContext):
return app.resolve(event, context)
```

=== "users/routers/health.py"
=== "src/users/routers/health.py"

```python hl_lines="4 6-7 10"
from typing import Dict
Expand All @@ -1169,7 +1170,7 @@ This sample project contains an Users function with two distinct set of routes,
```python hl_lines="3"
import json

from users import main # follows namespace package from root
from src.users import main # follows namespace package from root


def test_lambda_handler(apigw_event, lambda_context):
Expand All @@ -1180,16 +1181,6 @@ This sample project contains an Users function with two distinct set of routes,
assert ret["body"] == expected
```

=== ".env"

> Note: It is not needed for PyCharm (select folder as source).

This is necessary for Visual Studio Code, so integrated tooling works without failing import.

```bash
PYTHONPATH="users:${PYTHONPATH}"
```

### Considerations

This utility is optimized for fast startup, minimal feature set, and to quickly on-board customers familiar with frameworks like Flask — it's not meant to be a fully fledged framework.
Expand Down