@aws/nx-plugin-mcp 0.120.0 → 0.121.0
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.
- package/bin/aws-nx-mcp.js +23 -35
- package/docs/guides/astro-docs.mdx +142 -0
- package/docs/guides/connection/py-agent-a2a.mdx +105 -0
- package/docs/guides/connection/py-agent-mcp.mdx +147 -0
- package/docs/guides/connection/react-agui.mdx +240 -0
- package/docs/guides/connection/react-fastapi.mdx +1476 -0
- package/docs/guides/connection/react-py-agent.mdx +198 -0
- package/docs/guides/connection/react-smithy.mdx +1355 -0
- package/docs/guides/connection/react-trpc.mdx +447 -0
- package/docs/guides/connection/react-ts-agent.mdx +198 -0
- package/docs/guides/connection/smithy-rdb.mdx +161 -0
- package/docs/guides/connection/trpc-rdb.mdx +127 -0
- package/docs/guides/connection/ts-agent-a2a.mdx +106 -0
- package/docs/guides/connection/ts-agent-mcp.mdx +144 -0
- package/docs/guides/connection/ts-agent-rdb.mdx +141 -0
- package/docs/guides/connection/ts-mcp-server-rdb.mdx +135 -0
- package/docs/guides/connection.mdx +126 -0
- package/docs/guides/docker-bundling.mdx +403 -0
- package/docs/guides/fastapi.mdx +509 -0
- package/docs/guides/license.mdx +293 -0
- package/docs/guides/nx-generator.mdx +588 -0
- package/docs/guides/py-agent.mdx +483 -0
- package/docs/guides/py-mcp-server.mdx +161 -0
- package/docs/guides/python-lambda-function.mdx +207 -0
- package/docs/guides/python-project.mdx +228 -0
- package/docs/guides/react-website-auth.mdx +216 -0
- package/docs/guides/react-website.mdx +421 -0
- package/docs/guides/runtime-config.mdx +312 -0
- package/docs/guides/terraform-project.mdx +317 -0
- package/docs/guides/trpc.mdx +816 -0
- package/docs/guides/ts-agent.mdx +436 -0
- package/docs/guides/ts-lambda-function.mdx +218 -0
- package/docs/guides/ts-mcp-server.mdx +169 -0
- package/docs/guides/ts-nx-plugin.mdx +159 -0
- package/docs/guides/ts-rdb.mdx +759 -0
- package/docs/guides/ts-smithy-api.mdx +661 -0
- package/docs/guides/typescript-infrastructure.mdx +408 -0
- package/docs/guides/typescript-project.mdx +312 -0
- package/docs/guides/workspace.mdx +181 -0
- package/docs/snippets/agent/architecture.mdx +72 -0
- package/docs/snippets/agent/bedrock-deployment.mdx +172 -0
- package/docs/snippets/agent/runtime-arn.mdx +64 -0
- package/docs/snippets/api/api-architecture.mdx +93 -0
- package/docs/snippets/api/api-choice-note.mdx +6 -0
- package/docs/snippets/api/cors-configuration-cdk-note.mdx +25 -0
- package/docs/snippets/api/cors-configuration-terraform-note.mdx +28 -0
- package/docs/snippets/api/shared-constructs.mdx +38 -0
- package/docs/snippets/api/type-safe-api-integrations.mdx +643 -0
- package/docs/snippets/api/waf-configuration.mdx +37 -0
- package/docs/snippets/connection/a2a-infrastructure.mdx +63 -0
- package/docs/snippets/connection/lambda-rdb-ssl-requirements.mdx +40 -0
- package/docs/snippets/connection/mcp-server-rdb-ssl-requirements.mdx +35 -0
- package/docs/snippets/connection/rdb-api-infrastructure.mdx +72 -0
- package/docs/snippets/connection/react-agent-infrastructure.mdx +61 -0
- package/docs/snippets/connection/strands-agent-rdb-ssl-requirements.mdx +35 -0
- package/docs/snippets/lambda-function/architecture.mdx +36 -0
- package/docs/snippets/lambda-function/deploying-your-function.mdx +118 -0
- package/docs/snippets/mcp/architecture.mdx +58 -0
- package/docs/snippets/mcp/assistant-docs.mdx +10 -0
- package/docs/snippets/mcp/bedrock-deployment.mdx +167 -0
- package/docs/snippets/mcp/config.mdx +13 -0
- package/docs/snippets/mcp/configuration-py.mdx +42 -0
- package/docs/snippets/mcp/configuration-ts.mdx +53 -0
- package/docs/snippets/mcp/observability.mdx +8 -0
- package/docs/snippets/mcp/shared-constructs.mdx +32 -0
- package/docs/snippets/pdk-migration/example/01-migrate-api.mdx +602 -0
- package/docs/snippets/pdk-migration/example/02-migrate-website.mdx +915 -0
- package/docs/snippets/pdk-migration/example/03-migrate-infra.mdx +161 -0
- package/docs/snippets/pdk-migration/example/04-deploy.mdx +229 -0
- package/docs/snippets/pdk-migration/faq/aws-arch.mdx +17 -0
- package/docs/snippets/pdk-migration/faq/cdk-graph.mdx +29 -0
- package/docs/snippets/pdk-migration/faq/infrastructure-python-java.mdx +19 -0
- package/docs/snippets/pdk-migration/faq/pdk-nag.mdx +15 -0
- package/docs/snippets/pdk-migration/faq/pipeline.mdx +15 -0
- package/docs/snippets/pdk-migration/faq/type-safe-api.mdx +310 -0
- package/docs/snippets/pdk-migration/faq/use-of-projen.mdx +15 -0
- package/docs/snippets/prerequisites.mdx +20 -0
- package/docs/snippets/required-prerequisites.mdx +12 -0
- package/docs/snippets/shared-constructs.mdx +40 -0
- package/docs/snippets/tools/acurl.mdx +73 -0
- package/docs/snippets/ts-bundle.mdx +14 -0
- package/package.json +1 -1
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: FastAPI
|
|
3
|
+
description: Reference documentation for FastAPI
|
|
4
|
+
generator: py#fast-api
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
import { FileTree, Tabs, TabItem } from '@astrojs/starlight/components';
|
|
8
|
+
import Link from '@components/link.astro';
|
|
9
|
+
import RunGenerator from '@components/run-generator.astro';
|
|
10
|
+
import GeneratorParameters from '@components/generator-parameters.astro';
|
|
11
|
+
import NxCommands from '@components/nx-commands.astro';
|
|
12
|
+
import PackageManagerShortCommand from '@components/package-manager-short-command.astro';
|
|
13
|
+
import Infrastructure from '@components/infrastructure.astro';
|
|
14
|
+
import Snippet from '@components/snippet.astro';
|
|
15
|
+
import OptionFilter from '@components/option-filter.astro';
|
|
16
|
+
|
|
17
|
+
[FastAPI](https://fastapi.tiangolo.com/) is a framework for building APIs in Python.
|
|
18
|
+
|
|
19
|
+
The FastAPI generator creates a new FastAPI with AWS CDK or Terraform infrastructure setup. The generated backend uses AWS Lambda for serverless deployment, exposed via an AWS API Gateway API. It sets up [AWS Lambda Powertools](https://docs.powertools.aws.dev/lambda/python/latest/) for observability, including logging, AWS X-Ray tracing and Cloudwatch Metrics.
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
### Generate a FastAPI
|
|
24
|
+
|
|
25
|
+
You can generate a new FastAPI in two ways:
|
|
26
|
+
|
|
27
|
+
<RunGenerator generator="py#fast-api" />
|
|
28
|
+
|
|
29
|
+
### Options
|
|
30
|
+
|
|
31
|
+
<GeneratorParameters generator="py#fast-api" />
|
|
32
|
+
|
|
33
|
+
<Snippet name="api/api-choice-note" />
|
|
34
|
+
|
|
35
|
+
:::tip[API Type]
|
|
36
|
+
Select `ServerlessApiGatewayRestApi` (default) as your `computeType` if you intend to build any streaming operations.
|
|
37
|
+
:::
|
|
38
|
+
|
|
39
|
+
:::tip[Integration Pattern]
|
|
40
|
+
The `integrationPattern` option defaults to `isolated`, which creates one Lambda per FastAPI operation. Select `shared` if you would prefer a single shared Lambda handler for the whole API, with optional per-operation overrides.
|
|
41
|
+
:::
|
|
42
|
+
|
|
43
|
+
## Generator Output
|
|
44
|
+
|
|
45
|
+
The generator will create the following project structure in the `<directory>/<api-name>` directory:
|
|
46
|
+
|
|
47
|
+
<FileTree>
|
|
48
|
+
|
|
49
|
+
- project.json Project configuration and build targets
|
|
50
|
+
- pyproject.toml Python project configuration and dependencies
|
|
51
|
+
- run.sh Lambda Web Adapter bootstrap script to start the FastAPI app via uvicorn
|
|
52
|
+
- \<module_name>
|
|
53
|
+
- \_\_init\_\_.py Module initialisation
|
|
54
|
+
- init.py Sets the up FastAPI app and configures powertools middleware
|
|
55
|
+
- main.py API implementation
|
|
56
|
+
- scripts
|
|
57
|
+
- generate_open_api.py Script to generate an OpenAPI schema from the FastAPI app
|
|
58
|
+
|
|
59
|
+
</FileTree>
|
|
60
|
+
|
|
61
|
+
### Infrastructure
|
|
62
|
+
|
|
63
|
+
<Snippet name="shared-constructs" />
|
|
64
|
+
|
|
65
|
+
<Snippet name="api/shared-constructs" />
|
|
66
|
+
|
|
67
|
+
#### Architecture
|
|
68
|
+
|
|
69
|
+
<Snippet name="api/api-architecture" />
|
|
70
|
+
|
|
71
|
+
## Implementing your FastAPI
|
|
72
|
+
|
|
73
|
+
The main API implementation is in `main.py`. This is where you define your API routes and their implementations. Here's an example:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from pydantic import BaseModel
|
|
77
|
+
from .init import app, tracer
|
|
78
|
+
|
|
79
|
+
class Item(BaseModel):
|
|
80
|
+
name: str
|
|
81
|
+
|
|
82
|
+
@app.get("/items/{item_id}")
|
|
83
|
+
@tracer.capture_method
|
|
84
|
+
def get_item(item_id: int) -> Item:
|
|
85
|
+
return Item(name=...)
|
|
86
|
+
|
|
87
|
+
@app.post("/items")
|
|
88
|
+
@tracer.capture_method
|
|
89
|
+
def create_item(item: Item):
|
|
90
|
+
return ...
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The generator sets up several features automatically:
|
|
94
|
+
|
|
95
|
+
1. AWS Lambda Powertools integration for observability
|
|
96
|
+
2. Error handling middleware
|
|
97
|
+
3. Request/response correlation
|
|
98
|
+
4. Metrics collection
|
|
99
|
+
5. AWS Lambda deployment via [Lambda Web Adapter](https://github.com/awslabs/aws-lambda-web-adapter) with uvicorn
|
|
100
|
+
6. Type-safe streaming (REST API only)
|
|
101
|
+
|
|
102
|
+
### Observability with AWS Lambda Powertools
|
|
103
|
+
|
|
104
|
+
#### Logging
|
|
105
|
+
|
|
106
|
+
The generator configures structured logging using AWS Lambda Powertools. You can access the logger in your route handlers:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from .init import app, logger
|
|
110
|
+
|
|
111
|
+
@app.get("/items/{item_id}")
|
|
112
|
+
def read_item(item_id: int):
|
|
113
|
+
logger.info("Fetching item", extra={"item_id": item_id})
|
|
114
|
+
return {"item_id": item_id}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The logger automatically includes:
|
|
118
|
+
|
|
119
|
+
- Correlation IDs for request tracing
|
|
120
|
+
- Request path and method
|
|
121
|
+
- Lambda context information
|
|
122
|
+
- Cold start indicators
|
|
123
|
+
|
|
124
|
+
#### Tracing
|
|
125
|
+
|
|
126
|
+
AWS X-Ray tracing is configured automatically. You can add custom subsegments to your traces:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from .init import app, tracer
|
|
130
|
+
|
|
131
|
+
@app.get("/items/{item_id}")
|
|
132
|
+
@tracer.capture_method
|
|
133
|
+
def read_item(item_id: int):
|
|
134
|
+
# Creates a new subsegment
|
|
135
|
+
with tracer.provider.in_subsegment("fetch-item-details"):
|
|
136
|
+
# Your logic here
|
|
137
|
+
return {"item_id": item_id}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### Metrics
|
|
141
|
+
|
|
142
|
+
CloudWatch metrics are collected automatically for each request. You can add custom metrics:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from .init import app, metrics
|
|
146
|
+
from aws_lambda_powertools.metrics import MetricUnit
|
|
147
|
+
|
|
148
|
+
@app.get("/items/{item_id}")
|
|
149
|
+
def read_item(item_id: int):
|
|
150
|
+
metrics.add_metric(name="ItemViewed", unit=MetricUnit.Count, value=1)
|
|
151
|
+
return {"item_id": item_id}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Default metrics include:
|
|
155
|
+
|
|
156
|
+
- Request counts
|
|
157
|
+
- Success/failure counts
|
|
158
|
+
- Cold start metrics
|
|
159
|
+
- Per-route metrics
|
|
160
|
+
|
|
161
|
+
### Error Handling
|
|
162
|
+
|
|
163
|
+
The generator includes comprehensive error handling:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from fastapi import HTTPException
|
|
167
|
+
|
|
168
|
+
@app.get("/items/{item_id}")
|
|
169
|
+
def read_item(item_id: int):
|
|
170
|
+
if item_id < 0:
|
|
171
|
+
raise HTTPException(status_code=400, detail="Item ID must be positive")
|
|
172
|
+
return {"item_id": item_id}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Unhandled exceptions are caught by the middleware and:
|
|
176
|
+
|
|
177
|
+
1. Log the full exception with stack trace
|
|
178
|
+
2. Record a failure metric
|
|
179
|
+
3. Return a safe 500 response to the client
|
|
180
|
+
4. Preserve the correlation ID
|
|
181
|
+
|
|
182
|
+
:::tip[Response Models]
|
|
183
|
+
It's recommended to specify response models for your API operations for better code generation if using the `connection` generator. <Link path="guides/connection/react-fastapi#errors">See here for more details</Link>.
|
|
184
|
+
:::
|
|
185
|
+
|
|
186
|
+
<OptionFilter when={{ computeType: 'ServerlessApiGatewayRestApi' }} description="Streaming — REST API only">
|
|
187
|
+
### Streaming
|
|
188
|
+
|
|
189
|
+
The generated FastAPI supports streaming responses out of the box when using a REST API. The infrastructure is configured to use the [AWS Lambda Web Adapter](https://github.com/awslabs/aws-lambda-web-adapter) to run your FastAPI via uvicorn inside Lambda, with `ResponseTransferMode.STREAM` in API Gateway for all REST API operations, which enables streaming to work alongside non-streaming operations.
|
|
190
|
+
|
|
191
|
+
#### Using `JsonStreamingResponse`
|
|
192
|
+
|
|
193
|
+
The generated `init.py` exports a `JsonStreamingResponse` class that provides type-safe streaming with proper OpenAPI schema generation. This ensures that the <Link path="guides/connection/react-fastapi">`connection` generator</Link> can produce correctly typed streaming client methods.
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from pydantic import BaseModel
|
|
197
|
+
from .init import app, JsonStreamingResponse
|
|
198
|
+
|
|
199
|
+
class Chunk(BaseModel):
|
|
200
|
+
message: str
|
|
201
|
+
|
|
202
|
+
async def generate_chunks():
|
|
203
|
+
for i in range(100):
|
|
204
|
+
yield Chunk(message=f"This is chunk {i}")
|
|
205
|
+
|
|
206
|
+
@app.post(
|
|
207
|
+
"/stream",
|
|
208
|
+
response_class=JsonStreamingResponse,
|
|
209
|
+
responses={200: JsonStreamingResponse.openapi_response(Chunk, "Stream of chunks")},
|
|
210
|
+
)
|
|
211
|
+
async def my_stream() -> JsonStreamingResponse:
|
|
212
|
+
return JsonStreamingResponse(generate_chunks())
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The `JsonStreamingResponse` class:
|
|
216
|
+
|
|
217
|
+
1. Serializes Pydantic models to [JSON Lines](https://jsonlines.org/) format (`application/jsonl`)
|
|
218
|
+
2. Provides an `openapi_response` helper that generates the correct OpenAPI schema with `itemSchema`, enabling the <Link path="guides/connection/react-fastapi#consuming-a-stream">`connection` generator</Link> to produce type-safe streaming client methods
|
|
219
|
+
|
|
220
|
+
#### Consumption
|
|
221
|
+
|
|
222
|
+
To consume a stream of responses, you can make use of the <Link path="guides/connection/react-fastapi#consuming-a-stream">`connection` generator</Link> which will provide a type-safe method for iterating over your streamed chunks.
|
|
223
|
+
</OptionFilter>
|
|
224
|
+
|
|
225
|
+
## Deploying your FastAPI
|
|
226
|
+
|
|
227
|
+
The FastAPI generator creates CDK or Terraform infrastructure as code based on your selected `iacProvider`. You can use this to deploy your FastAPI.
|
|
228
|
+
|
|
229
|
+
<Infrastructure>
|
|
230
|
+
<Fragment slot="cdk">
|
|
231
|
+
The CDK construct for deploying your API in the `common/constructs` folder. You can use this in a CDK application:
|
|
232
|
+
|
|
233
|
+
```ts {6-8}
|
|
234
|
+
import { MyApi } from ':my-scope/common-constructs';
|
|
235
|
+
|
|
236
|
+
export class ExampleStack extends Stack {
|
|
237
|
+
constructor(scope: Construct, id: string) {
|
|
238
|
+
// Add the api to your stack
|
|
239
|
+
const api = new MyApi(this, 'MyApi', {
|
|
240
|
+
integrations: MyApi.defaultIntegrations(this).build(),
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
This sets up:
|
|
247
|
+
|
|
248
|
+
1. An AWS Lambda function for each operation in the FastAPI application
|
|
249
|
+
2. API Gateway HTTP/REST API as the function trigger
|
|
250
|
+
3. IAM roles and permissions
|
|
251
|
+
4. CloudWatch log group
|
|
252
|
+
5. X-Ray tracing configuration
|
|
253
|
+
6. CloudWatch metrics namespace
|
|
254
|
+
|
|
255
|
+
<Snippet name="api/cors-configuration-cdk-note" />
|
|
256
|
+
|
|
257
|
+
<OptionFilter when={{ auth: 'Cognito' }} description="Cognito identity construct wiring">
|
|
258
|
+
:::note[Cognito Authentication]
|
|
259
|
+
If you selected to use `Cognito` authentication, you will need to supply the `identity` property to the API construct:
|
|
260
|
+
|
|
261
|
+
```ts {9}
|
|
262
|
+
import { MyApi, UserIdentity } from ':my-scope/common-constructs';
|
|
263
|
+
|
|
264
|
+
export class ExampleStack extends Stack {
|
|
265
|
+
constructor(scope: Construct, id: string) {
|
|
266
|
+
const identity = new UserIdentity(this, 'Identity');
|
|
267
|
+
|
|
268
|
+
const api = new MyApi(this, 'MyApi', {
|
|
269
|
+
integrations: MyApi.defaultIntegrations(this).build(),
|
|
270
|
+
identity,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
The `UserIdentity` construct can be generated using the <Link path="/guides/react-website-auth">`ts#react-website-auth` generator</Link>
|
|
277
|
+
:::
|
|
278
|
+
</OptionFilter>
|
|
279
|
+
|
|
280
|
+
<OptionFilter when={{ auth: 'Custom' }} description="Custom Lambda Authorizer CDK usage">
|
|
281
|
+
:::caution[Custom Lambda Authorizer]
|
|
282
|
+
When using `Custom` auth, the construct creates a Lambda Authorizer internally from the generated `authorizer.py` file, which **denies all requests by default**. You must implement your authorization logic in that file before your API will accept any traffic.
|
|
283
|
+
:::
|
|
284
|
+
</OptionFilter>
|
|
285
|
+
</Fragment>
|
|
286
|
+
<Fragment slot="terraform">
|
|
287
|
+
The Terraform modules for deploying your API are in the `common/terraform` folder. You can use this in a Terraform configuration.
|
|
288
|
+
|
|
289
|
+
The API module stages its Lambda deployment zip in a shared S3 asset bucket — see the <Link path="/guides/terraform-project">Terraform infrastructure guide</Link> for details. Instantiate the `core/asset-bucket` module once per deployment and pass its `bucket_name` output into every API / Lambda module via the `asset_bucket_name` input:
|
|
290
|
+
|
|
291
|
+
```hcl {1-3, 8}
|
|
292
|
+
module "asset_bucket" {
|
|
293
|
+
source = "../../common/terraform/src/core/asset-bucket"
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
module "my_api" {
|
|
297
|
+
source = "../../common/terraform/src/app/apis/my-api"
|
|
298
|
+
|
|
299
|
+
asset_bucket_name = module.asset_bucket.bucket_name
|
|
300
|
+
|
|
301
|
+
# Environment variables for the Lambda function
|
|
302
|
+
env = {
|
|
303
|
+
ENVIRONMENT = var.environment
|
|
304
|
+
LOG_LEVEL = "INFO"
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
# Additional IAM policies if needed
|
|
308
|
+
additional_iam_policy_statements = [
|
|
309
|
+
# Add any additional permissions your API needs
|
|
310
|
+
]
|
|
311
|
+
|
|
312
|
+
tags = local.common_tags
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
This sets up:
|
|
317
|
+
|
|
318
|
+
1. An AWS Lambda function that serves all FastAPI routes
|
|
319
|
+
2. API Gateway HTTP/REST API as the function trigger
|
|
320
|
+
3. IAM roles and permissions
|
|
321
|
+
4. CloudWatch log group
|
|
322
|
+
5. X-Ray tracing configuration
|
|
323
|
+
6. CORS configuration
|
|
324
|
+
|
|
325
|
+
<Snippet name="api/cors-configuration-terraform-note" />
|
|
326
|
+
|
|
327
|
+
<OptionFilter when={{ auth: 'Cognito' }} description="Cognito module wiring">
|
|
328
|
+
:::note[Cognito Authentication]
|
|
329
|
+
If you selected to use `Cognito` authentication, you will need to supply the Cognito configuration:
|
|
330
|
+
|
|
331
|
+
```hcl {3, 5-6}
|
|
332
|
+
module "my_api" {
|
|
333
|
+
source = "../../common/terraform/src/app/apis/my-api"
|
|
334
|
+
|
|
335
|
+
asset_bucket_name = module.asset_bucket.bucket_name
|
|
336
|
+
|
|
337
|
+
user_pool_id = local.user_pool_id
|
|
338
|
+
user_pool_client_ids = [local.client_id]
|
|
339
|
+
|
|
340
|
+
env = {
|
|
341
|
+
ENVIRONMENT = var.environment
|
|
342
|
+
LOG_LEVEL = "INFO"
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
tags = local.common_tags
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
You can set up Cognito User Pool and Client using the appropriate Terraform resources or modules.
|
|
350
|
+
:::
|
|
351
|
+
</OptionFilter>
|
|
352
|
+
|
|
353
|
+
The Terraform module provides several outputs you can use:
|
|
354
|
+
|
|
355
|
+
```hcl
|
|
356
|
+
# Access the API endpoint
|
|
357
|
+
output "api_url" {
|
|
358
|
+
value = module.my_api.stage_invoke_url
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
# Access Lambda function details
|
|
362
|
+
output "lambda_function_name" {
|
|
363
|
+
value = module.my_api.lambda_function_name
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
# Access IAM role for granting additional permissions
|
|
367
|
+
output "lambda_execution_role_arn" {
|
|
368
|
+
value = module.my_api.lambda_execution_role_arn
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
You can customize CORS settings by passing variables to the module:
|
|
373
|
+
|
|
374
|
+
```hcl
|
|
375
|
+
module "my_api" {
|
|
376
|
+
source = "../../common/terraform/src/app/apis/my-api"
|
|
377
|
+
|
|
378
|
+
asset_bucket_name = module.asset_bucket.bucket_name
|
|
379
|
+
|
|
380
|
+
# Custom CORS configuration
|
|
381
|
+
cors_allow_origins = ["https://myapp.com", "https://staging.myapp.com"]
|
|
382
|
+
cors_allow_methods = ["GET", "POST", "PUT", "DELETE"]
|
|
383
|
+
cors_allow_headers = [
|
|
384
|
+
"authorization",
|
|
385
|
+
"content-type",
|
|
386
|
+
"x-custom-header"
|
|
387
|
+
]
|
|
388
|
+
|
|
389
|
+
tags = local.common_tags
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
<OptionFilter when={{ auth: 'Custom' }} description="Custom Lambda Authorizer usage with Terraform">
|
|
394
|
+
:::caution[Custom Lambda Authorizer]
|
|
395
|
+
When using `Custom` auth, your API is protected by a Lambda Authorizer that **denies all requests by default**. You must implement your authorization logic in the generated `authorizer.py` file before your API will accept any traffic.
|
|
396
|
+
:::
|
|
397
|
+
</OptionFilter>
|
|
398
|
+
</Fragment>
|
|
399
|
+
</Infrastructure>
|
|
400
|
+
|
|
401
|
+
<OptionFilter when={{ computeType: 'ServerlessApiGatewayRestApi' }} description="WAF — REST APIs get a WAF Web ACL by default">
|
|
402
|
+
### WAF
|
|
403
|
+
|
|
404
|
+
<Snippet name="api/waf-configuration" parentHeading="WAF" />
|
|
405
|
+
</OptionFilter>
|
|
406
|
+
|
|
407
|
+
### Integrations
|
|
408
|
+
|
|
409
|
+
<Snippet name="api/type-safe-api-integrations" parentHeading="Integrations" />
|
|
410
|
+
|
|
411
|
+
#### Code Generation
|
|
412
|
+
|
|
413
|
+
<Infrastructure>
|
|
414
|
+
<Fragment slot="cdk">
|
|
415
|
+
Since operations in FastAPI are defined in Python and CDK infrastructure in TypeScript, we instrument code-generation to supply metadata to the CDK construct to provide a type-safe interface for integrations.
|
|
416
|
+
|
|
417
|
+
A `generate:<ApiName>-metadata` target is added to the common constructs `project.json` to facilitate this code generation, which emits a file such as `packages/common/constructs/src/generated/my-api/metadata.gen.ts`. Since this is generated at build time, it is ignored in version control.
|
|
418
|
+
|
|
419
|
+
:::note[Build Before Deploy]
|
|
420
|
+
You will need to run a build whenever you change your API to ensure the types consumed by the CDK construct are up to date.
|
|
421
|
+
|
|
422
|
+
<PackageManagerShortCommand commands={["build"]} />
|
|
423
|
+
:::
|
|
424
|
+
|
|
425
|
+
:::tip[Hot Reloading]
|
|
426
|
+
If you are actively working on both your CDK infrastructure and FastAPI together, you can use [`nx watch`](https://nx.dev/nx-api/nx/documents/watch) to regenerate these types every time you make API changes:
|
|
427
|
+
|
|
428
|
+
<NxCommands
|
|
429
|
+
commands={[
|
|
430
|
+
'watch --projects=<FastAPIProject> -- \\ ',
|
|
431
|
+
'run <InfraProject>:"generate:<ApiName>-metadata"',
|
|
432
|
+
]}
|
|
433
|
+
/>
|
|
434
|
+
:::
|
|
435
|
+
</Fragment>
|
|
436
|
+
<Fragment slot="terraform">
|
|
437
|
+
:::note[Terraform Limitations]
|
|
438
|
+
We do not support type-safe integrations for Terraform, and therefore no code generation targets are configured if you selected Terraform for your `iacProvider`.
|
|
439
|
+
:::
|
|
440
|
+
</Fragment>
|
|
441
|
+
</Infrastructure>
|
|
442
|
+
|
|
443
|
+
<OptionFilter when={{ auth: 'IAM' }} description="IAM-authenticated APIs only">
|
|
444
|
+
### Granting Access (IAM Only)
|
|
445
|
+
|
|
446
|
+
If you selected to use `IAM` authentication, you can use the `grantInvokeAccess` method to grant access to your API:
|
|
447
|
+
|
|
448
|
+
<Infrastructure>
|
|
449
|
+
<Fragment slot="cdk">
|
|
450
|
+
```ts
|
|
451
|
+
api.grantInvokeAccess(myIdentityPool.authenticatedRole);
|
|
452
|
+
```
|
|
453
|
+
</Fragment>
|
|
454
|
+
<Fragment slot="terraform">
|
|
455
|
+
```hcl
|
|
456
|
+
# Create an IAM policy to allow invoking the API
|
|
457
|
+
resource "aws_iam_policy" "api_invoke_policy" {
|
|
458
|
+
name = "MyApiInvokePolicy"
|
|
459
|
+
description = "Policy to allow invoking the FastAPI"
|
|
460
|
+
|
|
461
|
+
policy = jsonencode({
|
|
462
|
+
Version = "2012-10-17"
|
|
463
|
+
Statement = [
|
|
464
|
+
{
|
|
465
|
+
Effect = "Allow"
|
|
466
|
+
Action = "execute-api:Invoke"
|
|
467
|
+
Resource = "${module.my_api.api_execution_arn}/*/*"
|
|
468
|
+
}
|
|
469
|
+
]
|
|
470
|
+
})
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
# Attach the policy to an IAM role (e.g., for authenticated users)
|
|
474
|
+
resource "aws_iam_role_policy_attachment" "api_invoke_access" {
|
|
475
|
+
role = aws_iam_role.authenticated_user_role.name
|
|
476
|
+
policy_arn = aws_iam_policy.api_invoke_policy.arn
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
# Or attach to an existing role by name
|
|
480
|
+
resource "aws_iam_role_policy_attachment" "api_invoke_access_existing" {
|
|
481
|
+
role = "MyExistingRole"
|
|
482
|
+
policy_arn = aws_iam_policy.api_invoke_policy.arn
|
|
483
|
+
}
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
The key outputs from the API module that you can use for IAM policies are:
|
|
487
|
+
|
|
488
|
+
- `module.my_api.api_execution_arn` - For granting execute-api:Invoke permissions
|
|
489
|
+
- `module.my_api.api_arn` - The API Gateway ARN
|
|
490
|
+
- `module.my_api.lambda_function_arn` - The Lambda function ARN
|
|
491
|
+
</Fragment>
|
|
492
|
+
</Infrastructure>
|
|
493
|
+
</OptionFilter>
|
|
494
|
+
|
|
495
|
+
## Local Development
|
|
496
|
+
|
|
497
|
+
The generator configures a local development server that you can run with:
|
|
498
|
+
|
|
499
|
+
<NxCommands commands={['serve my-api']} />
|
|
500
|
+
|
|
501
|
+
This starts a local FastAPI development server with:
|
|
502
|
+
|
|
503
|
+
- Auto-reload on code changes
|
|
504
|
+
- Interactive API documentation at `/docs` or `/redoc`
|
|
505
|
+
- OpenAPI schema at `/openapi.json`
|
|
506
|
+
|
|
507
|
+
## Invoking your FastAPI
|
|
508
|
+
|
|
509
|
+
To invoke your API from a React website, you can use the <Link path="guides/connection/react-fastapi">`connection` generator</Link>.
|