Skip to content

Feat/python313 fastapi template - #549

Open
JeevaByte wants to merge 7 commits into
aws:masterfrom
JeevaByte:feat/python313-fastapi-template
Open

Feat/python313 fastapi template#549
JeevaByte wants to merge 7 commits into
aws:masterfrom
JeevaByte:feat/python313-fastapi-template

Conversation

@JeevaByte

Copy link
Copy Markdown

Issue #, if available:

Description of changes:

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@JeevaByte
JeevaByte requested a review from a team as a code owner April 26, 2026 23:45
@github-actions github-actions Bot added pr/external stage/needs-triage Automatically applied to new issues and PRs, indicating they haven't been looked at. labels Apr 26, 2026

@roger-zhangg roger-zhangg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the contribution! A FastAPI template for Python 3.13 would be a great addition. However, there are several issues that need to be addressed before this can be merged:

Critical Issues

  1. Wrong dependencyManager in manifest-v2.json: You used "dependencyManager": "cli-package" but all python3.13 templates use "dependencyManager": "pip". This will cause SAM CLI to not properly resolve dependencies.

  2. Conflicting appTemplate value: You used "appTemplate": "hello-world" which already exists for the python3.13 hello-world template. This needs to be a unique identifier like "appTemplate": "hello-world-fastapi".

  3. Incomplete cookiecutter.json: The existing python3.13 templates include architectures, _copy_without_render, and __stack_name fields. Your cookiecutter.json should look like:

    {
        "project_name": "sam-fastapi-app",
        "runtime": "python3.13",
        "architectures": {
            "value": ["x86_64", "arm64"]
        },
        "_copy_without_render": [".gitignore"],
        "__stack_name": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}"
    }
  4. Missing standard template files: All python3.13 templates include:

    • __init__.py at the template root
    • setup.cfg (with [install]\nprefix=)
    • .gitignore files (both at root and inside {{cookiecutter.project_name}}/)
    • __init__.py inside {{cookiecutter.project_name}}/
    • tests/__init__.py

Other Issues

  1. Missing trailing newlines: Several files are missing the trailing newline (requirements.txt, main.py, template.yaml, README.md). This causes the "No newline at end of file" warnings.

  2. template.yaml missing Globals section: Standard templates include Globals: Function: Timeout: 3.

  3. template.yaml Architecture should use cookiecutter variable: Instead of hardcoding x86_64, use the cookiecutter architectures variable like other templates do.

  4. No events directory: Other templates include events/event.json for local testing with sam local invoke. The integration test class BuildInvokeBase.BuildInvokeBase may expect this.

  5. Unrelated whitespace changes in manifest-v2.json: The PR removes trailing spaces on unrelated lines and removes the final newline from the file. Please revert these changes to keep the diff minimal.

Suggested Template Structure

Please look at python3.13/hello/ or python3.13/hello-durable/ as reference templates and mirror their structure, adapting for FastAPI.

roger-zhangg and others added 2 commits July 2, 2026 15:20
- Add missing cookiecutter.json fields: architectures, _copy_without_render, __stack_name
- Fix manifest-v2.json: change dependencyManager from "cli-package" to "pip",
  set unique appTemplate value "fastapi-hello-world", remove non-standard description field
- Use architectures variable in template.yaml instead of hardcoded x86_64
- Add Globals section with Function Timeout in template.yaml
- Add proper Outputs section with Function ARN and IAM Role
- Add missing standard files: root .gitignore, root __init__.py,
  inner .gitignore, inner __init__.py, events/event.json,
  tests/__init__.py, tests/unit/__init__.py
- Add trailing newlines to main.py and requirements.txt

@aws-sam-tooling-bot aws-sam-tooling-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review Results

Reviewed: 5b0b240..76b0239
Files: 16
Comments: 2

@@ -0,0 +1,48 @@
{

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[BUG] The template.yaml declares the event source as Type: HttpApi (API Gateway HTTP API), which by default delivers a payload format version 2.0 event to the Lambda function. However, events/event.json is a REST API (v1.0) proxy event — it uses top-level httpMethod, resource, path, and a v1-style requestContext (with identity, resourcePath, etc.), and it lacks the version: "2.0" and requestContext.http block expected by HTTP API v2.

As a result, when users follow the standard flow and run:

sam local invoke FastApiFunction --event events/event.json

they will exercise Mangum's REST-API/v1 code path, which does not match what the deployed HTTP API will actually send in production. This produces misleading local-vs-cloud behavior and can hide bugs.

Either change the event source in template.yaml to REST Api (matching the existing v1 event), or replace events/event.json with an HTTP API v2.0 payload event (with "version": "2.0", requestContext.http.method, rawPath, rawQueryString, etc.).

@@ -0,0 +1,20 @@
from fastapi.testclient import TestClient

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[BUG] The test imports from fastapi.testclient import TestClient, which is a re-export of Starlette's TestClient and requires the httpx package at runtime. Neither app/requirements.txt (which contains only fastapi and mangum) nor the README install command:

python -m pip install -r app/requirements.txt pytest pytest-mock

installs httpx. Users following the README to run python -m pytest tests/unit will hit an ImportError/RuntimeError from TestClient about the missing httpx dependency, so the shipped tests will not actually run.

Add httpx (or install fastapi[testclient]) as a test dependency — for example, add a tests/requirements.txt with pytest and httpx, and update the README to install it. Also, pytest-mock is not used anywhere in the tests and can be dropped from the install instructions.

Note: the manifest concerns raised in the earlier review (dependencyManager and appTemplate) appear addressed in this diff — the new entry uses "dependencyManager": "pip" and "appTemplate": "fastapi-hello-world", which is unique across manifest-v2.json.

Keep only the FastAPI entry addition; remove trailing-space cleanup
and preserved the file's trailing newline.
- setup.cfg with [install] prefix= (standard for all python templates)
- tests/requirements.txt (pytest, httpx, fastapi for TestClient)
- tests/integration/__init__.py placeholder

@aws-sam-tooling-bot aws-sam-tooling-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review Results

Reviewed: 5b0b240..659aab3
Files: 19
Comments: 3

@@ -0,0 +1,48 @@
{

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[BUG] Re-raising a previously flagged issue that was not addressed. The template.yaml declares the event source as Type: HttpApi (API Gateway v2), which uses payload format version 2.0 by default. This event.json is a REST API / v1.0 proxy event — it uses top-level httpMethod, resource, path, and a v1-style requestContext with identity/resourcePath, and is missing the v2.0 fields (version: "2.0", routeKey, rawPath, rawQueryString, requestContext.http.method, etc.). This means sam local invoke -e events/event.json exercises a different payload shape than what the deployed HttpApi will actually deliver, and users copying this event as a reference will be misled. Replace with an API Gateway HTTP API v2.0 payload (or, alternatively, switch the event source to Type: Api if a REST API is what's intended).

Install the application dependencies and test dependencies, then run pytest.

```bash
python -m pip install -r app/requirements.txt pytest pytest-mock

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[BUG] Re-raising a previously flagged issue that was only partially addressed. tests/requirements.txt was updated to include httpx, but the README's install command still doesn't reference it:

python -m pip install -r app/requirements.txt pytest pytest-mock

tests/unit/test_handler.py imports from fastapi.testclient import TestClient, which requires httpx at runtime. A user following the README verbatim will get an ImportError when running pytest. Update the install command to also install the test requirements, e.g.:

python -m pip install -r app/requirements.txt -r tests/requirements.txt

should_test_lint = False


class UnitTest_python3_13_cookiecutter_aws_sam_python_fastapi(UnitTestBase.Python313UnitTestBase):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[BUG] The new test class does not set test_dependencies = True:

class UnitTest_python3_13_cookiecutter_aws_sam_python_fastapi(UnitTestBase.Python313UnitTestBase):
   directory = "python3.13/cookiecutter-aws-sam-python-fastapi"
   code_directories = ["app"]
   should_test_lint = False

Looking at PythonUnitTestBase._test_unit_tests in unit_test_base.py, tests/requirements.txt (which contains httpx) is only installed when test_dependencies = True. Without it, running the integration unit test will invoke pytest tests/unit without httpx installed, causing from fastapi.testclient import TestClient to fail at collection time (pytest prints an ERRORS section, which the base class's assertNotIn("ERRORS", result.stdout) will catch as a failure). Add test_dependencies = True as done in UnitTest_python3_13_cookiecutter_aws_sam_hello_durable_python.

- Replace REST API v1.0 event.json with HTTP API v2.0 payload format
  to match the HttpApi event source in template.yaml
- Fix README to reference tests/requirements.txt instead of inline deps

@aws-sam-tooling-bot aws-sam-tooling-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review Results

Reviewed: 5b0b240..84cd0e3
Files: 19
Comments: 1

should_test_lint = False


class UnitTest_python3_13_cookiecutter_aws_sam_python_fastapi(UnitTestBase.Python313UnitTestBase):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[BUG] The new test class does not set test_dependencies = True:

class UnitTest_python3_13_cookiecutter_aws_sam_python_fastapi(UnitTestBase.Python313UnitTestBase):
   directory = "python3.13/cookiecutter-aws-sam-python-fastapi"
   code_directories = ["app"]
   # TODO: remove the line remove once python3.13 is GA
   should_test_lint = False

In PythonUnitTestBase._test_unit_tests (tests/integration/unit_test/unit_test_base.py:107), tests/requirements.txt is only installed when test_dependencies is True — otherwise only app/requirements.txt plus pytest and pytest-mock are installed. The template's tests/unit/test_handler.py imports from fastapi.testclient import TestClient, which requires httpx at runtime. httpx is declared in tests/requirements.txt (not app/requirements.txt), so under the default setting the integration unit test will fail with ModuleNotFoundError: No module named 'httpx'. This exact issue was flagged in a previous bot review and has not been addressed. Add test_dependencies = True to the class (matching the pattern used by UnitTest_python3_13_cookiecutter_aws_sam_hello_durable_python and the python3.14 fastapi equivalent).

@roger-zhangg roger-zhangg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All review feedback addressed:

  • Fixed dependencyManager, appTemplate, and cookiecutter.json fields
  • Added all missing standard template files (setup.cfg, .gitignore, events/, tests/)
  • Replaced REST API v1.0 event.json with HTTP API v2.0 payload format
  • Reverted unrelated whitespace changes in manifest-v2.json
  • Fixed README test install command
  • Used cookiecutter architectures variable in template.yaml

Thanks @JeevaByte for the contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr/external stage/needs-triage Automatically applied to new issues and PRs, indicating they haven't been looked at.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants