-
-
Notifications
You must be signed in to change notification settings - Fork 128
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🎨 Replace abstract handlers, customer handlers, drop 3.6 support, typ…
…ing additions and fixes, refactoring. (#242) * 🎨 Replace abstract handlers and introduce provisional support for custom handlers, various type annotation fixes and additions, remove dataclasses, update README and requirements. * 💥 Drop support for Python 3.6.
- Loading branch information
1 parent
88ae4d9
commit 7ee6846
Showing
30 changed files
with
1,083 additions
and
998 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
from .types import Request, Response | ||
from .adapter import Mangum # noqa: F401 | ||
from mangum.adapter import Mangum | ||
|
||
__all__ = ["Mangum", "Request", "Response"] | ||
__all__ = ["Mangum"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,66 +1,92 @@ | ||
from itertools import chain | ||
import logging | ||
from contextlib import ExitStack | ||
from typing import List, Optional, Type | ||
import warnings | ||
|
||
|
||
from mangum.exceptions import ConfigurationError | ||
from mangum.handlers.abstract_handler import AbstractHandler | ||
from mangum.protocols import HTTPCycle, LifespanCycle | ||
from mangum.types import ASGIApp, LambdaEvent, LambdaContext | ||
from mangum.handlers import ALB, HTTPGateway, APIGateway, LambdaAtEdge | ||
from mangum.exceptions import ConfigurationError | ||
from mangum.types import ( | ||
ASGIApp, | ||
LifespanMode, | ||
LambdaConfig, | ||
LambdaEvent, | ||
LambdaContext, | ||
LambdaHandler, | ||
) | ||
|
||
|
||
DEFAULT_TEXT_MIME_TYPES = [ | ||
"text/", | ||
"application/json", | ||
"application/javascript", | ||
"application/xml", | ||
"application/vnd.api+json", | ||
] | ||
logger = logging.getLogger("mangum") | ||
|
||
|
||
logger = logging.getLogger("mangum") | ||
HANDLERS: List[Type[LambdaHandler]] = [ | ||
ALB, | ||
HTTPGateway, | ||
APIGateway, | ||
LambdaAtEdge, | ||
] | ||
|
||
|
||
class Mangum: | ||
""" | ||
Creates an adapter instance. | ||
* **app** - An asynchronous callable that conforms to version 3.0 of the ASGI | ||
specification. This will usually be an ASGI framework application instance. | ||
* **lifespan** - A string to configure lifespan support. Choices are `auto`, `on`, | ||
and `off`. Default is `auto`. | ||
* **text_mime_types** - A list of MIME types to include with the defaults that | ||
should not return a binary response in API Gateway. | ||
* **api_gateway_base_path** - A string specifying the part of the url path after | ||
which the server routing begins. | ||
""" | ||
|
||
def __init__( | ||
self, | ||
app: ASGIApp, | ||
lifespan: str = "auto", | ||
lifespan: LifespanMode = "auto", | ||
api_gateway_base_path: str = "/", | ||
custom_handlers: Optional[List[Type[LambdaHandler]]] = None, | ||
) -> None: | ||
if lifespan not in ("auto", "on", "off"): | ||
raise ConfigurationError( | ||
"Invalid argument supplied for `lifespan`. Choices are: auto|on|off" | ||
) | ||
|
||
self.app = app | ||
self.lifespan = lifespan | ||
self.api_gateway_base_path = api_gateway_base_path | ||
self.api_gateway_base_path = api_gateway_base_path or "/" | ||
self.config = LambdaConfig(api_gateway_base_path=self.api_gateway_base_path) | ||
|
||
if self.lifespan not in ("auto", "on", "off"): | ||
raise ConfigurationError( | ||
"Invalid argument supplied for `lifespan`. Choices are: auto|on|off" | ||
if custom_handlers is not None: | ||
warnings.warn( # pragma: no cover | ||
"Support for custom event handlers is currently provisional and may " | ||
"drastically change (or be removed entirely) in the future.", | ||
FutureWarning, | ||
) | ||
|
||
def __call__(self, event: LambdaEvent, context: LambdaContext) -> dict: | ||
logger.debug("Event received.") | ||
self.custom_handlers = custom_handlers or [] | ||
|
||
def infer(self, event: LambdaEvent, context: LambdaContext) -> LambdaHandler: | ||
for handler_cls in chain( | ||
self.custom_handlers, | ||
HANDLERS, | ||
): | ||
handler = handler_cls.infer( | ||
event, | ||
context, | ||
self.config, | ||
) | ||
if handler: | ||
break | ||
else: | ||
raise RuntimeError( # pragma: no cover | ||
"The adapter was unable to infer a handler to use for the event. This " | ||
"is likely related to how the Lambda function was invoked. (Are you " | ||
"testing locally? Make sure the request payload is valid for a " | ||
"supported handler.)" | ||
) | ||
|
||
return handler | ||
|
||
def __call__(self, event: LambdaEvent, context: LambdaContext) -> dict: | ||
handler = self.infer(event, context) | ||
with ExitStack() as stack: | ||
if self.lifespan != "off": | ||
if self.lifespan in ("auto", "on"): | ||
lifespan_cycle = LifespanCycle(self.app, self.lifespan) | ||
stack.enter_context(lifespan_cycle) | ||
|
||
handler = AbstractHandler.from_trigger( | ||
event, context, self.api_gateway_base_path | ||
) | ||
http_cycle = HTTPCycle(handler.request) | ||
response = http_cycle(self.app, handler.body) | ||
http_cycle = HTTPCycle(handler.scope, handler.body) | ||
http_response = http_cycle(self.app) | ||
|
||
return handler(http_response) | ||
|
||
return handler.transform_response(response) | ||
assert False, "unreachable" # pragma: no cover |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from mangum.handlers.api_gateway import APIGateway, HTTPGateway | ||
from mangum.handlers.alb import ALB | ||
from mangum.handlers.lambda_at_edge import LambdaAtEdge | ||
|
||
|
||
__all__ = ["APIGateway", "HTTPGateway", "ALB", "LambdaAtEdge"] |
Oops, something went wrong.