Skip to content

Security configuration for route does not work for APIGatewayHttpRouter #4375

Closed
@ghost

Description

Expected Behaviour

Method get_openapi_json_schema from APIGatewayHttpResolver should work for routes from APIGatewayHttpRouter with the security parameter.

Current Behaviour

When the security parameter is a part of the router (APIGatewayHttpRouter), it doesn't work - /openapispec has: {"message": "Internal Server Error"}.

If I remove the security parameter from the router file, it works, and it means that the security configuration is correct only for APIGatewayHttpResolver.

Error in CloudWatch after /openapispec execution:

[ERROR] TypeError: unhashable type: 'list' Traceback (most recent call last): File "/var/lang/lib/python3.12/importlib/__init__.py", line 90, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 1387, in _gcd_import File "<frozen importlib._bootstrap>", line 1360, in _find_and_load File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 935, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 995, in exec_module File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed File "/var/task/app.py", line 14, in <module> from project_member_v1 import router as project_member_router File "/var/task/project_member_v1/router.py", line 27, in <module> @router.get( File "/opt/python/aws_lambda_powertools/event_handler/api_gateway.py", line 2412, in register_route self._routes_with_middleware[route_key] = []

Code snippet

`
app = APIGatewayHttpResolver(enable_validation=True)
logger = Logger()
metrics = Metrics(namespace="Powertools")

OpenApiConfiguration.configure_swagger(app)

app.include_router(test_router.router, prefix="/v1/test")

@app.get("/hello", tags=["Test"], summary="An endpoint to test", security=[{"TestAuth": []}],)
def hello():
    return {"message": f"Hello!"}

@app.get("/openapispec", tags=["Docs"], summary="Get the OpenAPI specification")
def get_openapi():
    return app.get_openapi_json_schema(**OpenApiConfiguration.get_meta_data())


@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST)
@metrics.log_metrics(capture_cold_start_metric=True)
def lambda_handler(event: dict, context: LambdaContext) -> dict:
    return app.resolve(event, context)
`

Router file:
`
router = APIGatewayHttpRouter()

@router.get(
    "/<test_id>",
    tags=["Test"],
    summary="Test endpoint",
    security=[{"TestAuth": []}],
)
def get_test_item(test_id: str) -> TestItemResponse:
    return TestItemResponse(test_id= test_id)
`

`
class OpenApiConfiguration:
    @staticmethod
    def get_meta_data():
        return {
            "title": "TestAPI",
            "version": "0.0.1",
            Contact(name="Test", url=Url("test.com")),
            "description": "TestAPI",
            "terms_of_service": None,
            "license_info": None,
            "openapi_version": "3.0.1",
            "security_schemes": {
                "TestAuth": HTTPBearer(scheme="bearer", bearerFormat="JWT", description="JWT token authentication"),
            },
        }

    @staticmethod
    def configure_swagger(resolver: ApiGatewayResolver) -> None:
        resolver.enable_swagger(
            **OpenApiConfiguration.get_meta_data(),
            path="/swagger",
            swagger_base_url="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.11.0"
        )
`

Route `openspec` should returns a definition of 3 endpoints:
- `/hello` with `TestAuth` security
- `/openapispec` without security
- `/test/< test_id >`  with `TestAuth` security

Possible Solution

No response

Steps to Reproduce

  1. Create instance of APIGatewayHttpResolver
  2. Create instance of APIGatewayHttpRouter
  3. Implement OpenApiConfiguration and define security_schemes
  4. Add route to APIGatewayHttpRouter with security
  5. Add route to openapispec:
    @app.get("/openapispec", tags=["Docs"], summary="Get the OpenAPI specification") def get_openapi(): return app.get_openapi_json_schema(**OpenApiConfiguration.get_meta_data())
  6. Execute /openapispec

Powertools for AWS Lambda (Python) version

latest

AWS Lambda function runtime

3.12

Packaging format used

Lambda Layers

Debugging logs

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Shipped

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions