Skip to content

Commit fc49d15

Browse files
tonybaloneyHazhzengAzureFunctionsPythonvrdmr
authored
Async handle adaptor (#143)
* Add AnatoliB to CodeOwners * Create an async handler and deprecate the old * DeprecationWarning is a builtin * fix flake8 violations Co-authored-by: Hanzhang Zeng <48038149+Hazhzeng@users.noreply.github.com> Co-authored-by: AzureFunctionsPython <funcdisc@microsoft.com> Co-authored-by: Varad <varad.meru@gmail.com>
1 parent f59de66 commit fc49d15

File tree

2 files changed

+54
-5
lines changed

2 files changed

+54
-5
lines changed

azure/functions/_http_asgi.py

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import Dict, List, Tuple, Optional, Any, Union
55
import logging
66
import asyncio
7+
from warnings import warn
78
from wsgiref.headers import Headers
89

910
from ._abc import Context
@@ -149,18 +150,20 @@ def __init__(self, app):
149150
self.main = self._handle
150151

151152
def handle(self, req: HttpRequest, context: Optional[Context] = None):
152-
"""Method to convert an Azure Functions HTTP request into a ASGI
153-
Python object. Example on handling ASGI app in a HTTP trigger by
154-
calling .handle() in .main() method:
153+
"""Deprecated. Please use handle_async instead:
155154
156155
import azure.functions as func
157156
158157
from FastapiApp import app
159158
160-
def main(req, context):
161-
return func.AsgiMiddleware(app).handle(req, context)
159+
async def main(req, context):
160+
return await func.AsgiMiddleware(app).handle_async(req, context)
162161
"""
162+
warn("handle() is deprecated. Please use handle_async() instead.",
163+
DeprecationWarning, stacklevel=2)
163164
self._logger.debug(f"Handling {req.url} as an ASGI request.")
165+
self._logger.warning(
166+
"handle() is deprecated. Please `await .handle_async()` instead.")
164167
return self._handle(req, context)
165168

166169
def _handle(self, req, context):
@@ -172,3 +175,29 @@ def _handle(self, req, context):
172175
)
173176

174177
return asgi_response.to_func_response()
178+
179+
async def handle_async(self,
180+
req: HttpRequest,
181+
context: Optional[Context] = None):
182+
"""Method to convert an Azure Functions HTTP request into a ASGI
183+
Python object. Example on handling ASGI app in a HTTP trigger by
184+
calling .handle_async() in .main() method:
185+
186+
import azure.functions as func
187+
188+
from FastapiApp import app
189+
190+
async def main(req, context):
191+
return await func.AsgiMiddleware(app).handle_async(req,
192+
context)
193+
"""
194+
self._logger.debug(f"Awaiting {req.url} as an ASGI request.")
195+
return await self._handle_async(req, context)
196+
197+
async def _handle_async(self, req, context):
198+
asgi_request = AsgiRequest(req, context)
199+
scope = asgi_request.to_asgi_http_scope()
200+
asgi_response = await AsgiResponse.from_app(self._app,
201+
scope,
202+
req.get_body())
203+
return asgi_response.to_func_response()

tests/test_http_asgi.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Copyright (c) Microsoft Corporation. All rights reserved.
22
# Licensed under the MIT License.
33

4+
import asyncio
45
import unittest
56

67
import azure.functions as func
@@ -194,3 +195,22 @@ def test_middleware_wrapper(self):
194195
# Verify asserted
195196
self.assertEqual(response.status_code, 200)
196197
self.assertEqual(response.get_body(), test_body)
198+
199+
def test_middleware_async_calls_app_with_context(self):
200+
"""Test the middleware with the awaitable handle_async() method
201+
async def main(req, context):
202+
return await AsgiMiddleware(app).handle_async(req, context)
203+
"""
204+
app = MockAsgiApplication()
205+
test_body = b'Hello world!'
206+
app.response_body = test_body
207+
app.response_code = 200
208+
req = self._generate_func_request()
209+
ctx = self._generate_func_context()
210+
response = asyncio.get_event_loop().run_until_complete(
211+
AsgiMiddleware(app).handle_async(req, ctx)
212+
)
213+
214+
# Verify asserted
215+
self.assertEqual(response.status_code, 200)
216+
self.assertEqual(response.get_body(), test_body)

0 commit comments

Comments
 (0)