Skip to content

Commit da95aec

Browse files
Addressing Ran's feedback
1 parent dd694ff commit da95aec

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

aws_lambda_powertools/event_handler/openapi/merge.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import importlib.util
88
import logging
99
import sys
10+
import warnings
1011
from pathlib import Path
1112
from typing import TYPE_CHECKING, Any, Literal
1213

@@ -232,7 +233,13 @@ def _load_resolver_with_dependencies(
232233
_load_module(dep_file, dep_module_name)
233234
logger.debug(f"Loaded dependent file: {dep_file}")
234235
except Exception as e:
235-
logger.warning(f"Failed to load dependent file {dep_file}: {e}")
236+
warnings.warn(
237+
f"Failed to load dependent file {dep_file}: {e}. "
238+
"If your handler module has side effects at import time "
239+
"(e.g. environment variable validation, database connections), "
240+
"consider deferring them to runtime.",
241+
stacklevel=2,
242+
)
236243

237244
# Now get the resolver - it should already be loaded by the dependent files
238245
# Try to get it from the module that was loaded by dependents
@@ -409,9 +416,25 @@ def get_openapi_schema(self) -> dict[str, Any]:
409416
if hasattr(resolver, "get_openapi_schema"):
410417
self._schemas.append(_model_to_dict(resolver.get_openapi_schema()))
411418
except (ImportError, AttributeError, FileNotFoundError) as e:
412-
logger.warning(f"Failed to load resolver from {file_path}: {e}")
419+
warnings.warn(
420+
f"Failed to load resolver from {file_path}: {e}. "
421+
"If your handler module has side effects at import time "
422+
"(e.g. environment variable validation, database connections), "
423+
"consider deferring them to runtime.",
424+
stacklevel=1,
425+
)
413426

414427
self._cached_schema = self._merge_schemas()
428+
429+
if self._discovered_files and not self._cached_schema.get("paths"):
430+
warnings.warn(
431+
f"OpenAPIMerge discovered {len(self._discovered_files)} handler file(s) "
432+
"but the final schema has no paths. "
433+
"Check if your handler modules have side effects at import time "
434+
"that prevent route registration.",
435+
stacklevel=1,
436+
)
437+
415438
return self._cached_schema
416439

417440
def get_openapi_json_schema(self) -> str:

docs/core/event_handler/openapi.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,6 @@ The Swagger UI appears by default at the `/swagger` path, but you can customize
6161

6262
## Customization
6363

64-
???+ warning "OpenAPI schema version depends on the installed version of Pydantic"
65-
Pydantic v1 generates [valid OpenAPI 3.0.3 schemas](https://docs.pydantic.dev/1.10/usage/schema/){target="_blank" rel="nofollow"}, and Pydantic v2 generates [valid OpenAPI 3.1.0 schemas](https://docs.pydantic.dev/latest/why/#json-schema){target="_blank" rel="nofollow"}.
66-
6764
### Customizing parameters
6865

6966
--8<-- "docs/core/event_handler/_openapi_customization_parameters.md"
@@ -185,6 +182,11 @@ OpenAPI Merge uses AST (Abstract Syntax Tree) analysis to detect resolver instan
185182
* No security concerns from arbitrary code execution
186183
* Fast discovery across many files
187184

185+
???+ warning "Handler modules must be side-effect-free at import time"
186+
While discovery uses static analysis (AST), **schema generation requires importing your handler modules** to extract route definitions. If a handler module runs code at import time - such as validating environment variables, opening database connections, or calling external services — the import will fail silently and its routes will be missing from the final schema.
187+
188+
If your schema is unexpectedly empty, check whether your handler files have decorators or top-level code that depends on runtime state. Move these to the handler function body or guard them with `if __name__ == "__main__"`.
189+
188190
### Discovery parameters
189191

190192
The `discover()` method accepts the following parameters:

0 commit comments

Comments
 (0)