blueprint change: worker indexing functionregister (#1065)
* blueprint change: worker indexing functionregister * fix flakey8 * temp update to 3b2 * update unit tests * fix functionregister err msg Co-authored-by: peterstone2017 <yunchuwang5@gmail.com> Co-authored-by: Varad Meru <vrdmr@users.noreply.github.com>
This commit is contained in:
Родитель
f51a1f1b0f
Коммит
1b52d72d8b
|
@ -143,18 +143,19 @@ def index_function_app(function_path: str):
|
|||
module_name = pathlib.Path(function_path).stem
|
||||
imported_module = importlib.import_module(module_name)
|
||||
|
||||
from azure.functions import FunctionApp
|
||||
app: Optional[FunctionApp] = None
|
||||
from azure.functions import FunctionRegister
|
||||
app: Optional[FunctionRegister] = None
|
||||
for i in imported_module.__dir__():
|
||||
if isinstance(getattr(imported_module, i, None), FunctionApp):
|
||||
if isinstance(getattr(imported_module, i, None), FunctionRegister):
|
||||
if not app:
|
||||
app = getattr(imported_module, i, None)
|
||||
else:
|
||||
raise ValueError(
|
||||
"Multiple instances of FunctionApp are defined")
|
||||
f"More than one {app.__class__.__name__} or other top "
|
||||
f"level function app instances are defined.")
|
||||
|
||||
if not app:
|
||||
raise ValueError("Could not find instance of FunctionApp in "
|
||||
raise ValueError("Could not find top level function app instances in "
|
||||
f"{SCRIPT_FILE_NAME}.")
|
||||
|
||||
return app.get_functions()
|
||||
|
|
2
setup.py
2
setup.py
|
@ -105,7 +105,7 @@ INSTALL_REQUIRES = [
|
|||
"grpcio~=1.43.0",
|
||||
"grpcio-tools~=1.43.0",
|
||||
"protobuf~=3.19.3",
|
||||
'azure-functions==1.11.3b2',
|
||||
"azure-functions==1.11.3b2",
|
||||
"python-dateutil~=2.8.2"
|
||||
]
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import logging
|
||||
|
||||
import azure.functions as func
|
||||
|
||||
bp = func.Blueprint()
|
||||
|
||||
|
||||
@bp.route(route="default_template")
|
||||
def default_template(req: func.HttpRequest) -> func.HttpResponse:
|
||||
logging.info('Python HTTP trigger function processed a request.')
|
||||
|
||||
name = req.params.get('name')
|
||||
if not name:
|
||||
try:
|
||||
req_body = req.get_json()
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
name = req_body.get('name')
|
||||
|
||||
if name:
|
||||
return func.HttpResponse(
|
||||
f"Hello, {name}. This HTTP triggered function "
|
||||
f"executed successfully.")
|
||||
else:
|
||||
return func.HttpResponse(
|
||||
"This HTTP triggered function executed successfully. "
|
||||
"Pass a name in the query string or in the request body for a"
|
||||
" personalized response.",
|
||||
status_code=200
|
||||
)
|
|
@ -0,0 +1,6 @@
|
|||
import azure.functions as func
|
||||
from blueprint import bp
|
||||
|
||||
app = func.FunctionApp()
|
||||
|
||||
app.register_functions(bp)
|
|
@ -0,0 +1,31 @@
|
|||
import logging
|
||||
|
||||
import azure.functions as func
|
||||
|
||||
bp = func.Blueprint()
|
||||
|
||||
|
||||
@bp.route(route="default_template")
|
||||
def default_template(req: func.HttpRequest) -> func.HttpResponse:
|
||||
logging.info('Python HTTP trigger function processed a request.')
|
||||
|
||||
name = req.params.get('name')
|
||||
if not name:
|
||||
try:
|
||||
req_body = req.get_json()
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
name = req_body.get('name')
|
||||
|
||||
if name:
|
||||
return func.HttpResponse(
|
||||
f"Hello, {name}. This HTTP triggered function "
|
||||
f"executed successfully.")
|
||||
else:
|
||||
return func.HttpResponse(
|
||||
"This HTTP triggered function executed successfully. "
|
||||
"Pass a name in the query string or in the request body for a"
|
||||
" personalized response.",
|
||||
status_code=200
|
||||
)
|
|
@ -0,0 +1,13 @@
|
|||
import azure.functions as func
|
||||
|
||||
from blueprint import bp
|
||||
|
||||
app = func.FunctionApp()
|
||||
|
||||
app.register_blueprint(bp)
|
||||
|
||||
|
||||
@app.route(route="return_http")
|
||||
def return_http(req: func.HttpRequest):
|
||||
return func.HttpResponse('<h1>Hello World™</h1>',
|
||||
mimetype='text/html')
|
|
@ -0,0 +1,12 @@
|
|||
import azure.functions as func
|
||||
|
||||
app = func.FunctionApp()
|
||||
|
||||
|
||||
@app.route(route="return_http")
|
||||
def return_http(req: func.HttpRequest):
|
||||
return func.HttpResponse('<h1>Hello World™</h1>',
|
||||
mimetype='text/html')
|
||||
|
||||
|
||||
asgi_app = func.AsgiFunctionApp()
|
|
@ -0,0 +1,31 @@
|
|||
import logging
|
||||
|
||||
import azure.functions as func
|
||||
|
||||
bp = func.Blueprint()
|
||||
|
||||
|
||||
@bp.route(route="default_template")
|
||||
def default_template(req: func.HttpRequest) -> func.HttpResponse:
|
||||
logging.info('Python HTTP trigger function processed a request.')
|
||||
|
||||
name = req.params.get('name')
|
||||
if not name:
|
||||
try:
|
||||
req_body = req.get_json()
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
name = req_body.get('name')
|
||||
|
||||
if name:
|
||||
return func.HttpResponse(
|
||||
f"Hello, {name}. This HTTP triggered function "
|
||||
f"executed successfully.")
|
||||
else:
|
||||
return func.HttpResponse(
|
||||
"This HTTP triggered function executed successfully. "
|
||||
"Pass a name in the query string or in the request body for a"
|
||||
" personalized response.",
|
||||
status_code=200
|
||||
)
|
|
@ -0,0 +1,59 @@
|
|||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
from azure_functions_worker import testutils
|
||||
|
||||
|
||||
class TestFunctionInBluePrintOnly(testutils.WebHostTestCase):
|
||||
@classmethod
|
||||
def get_script_dir(cls):
|
||||
return testutils.E2E_TESTS_FOLDER / 'blueprint_functions' / \
|
||||
'functions_in_blueprint_only'
|
||||
|
||||
@testutils.retryable_test(3, 5)
|
||||
def test_function_in_blueprint_only(self):
|
||||
r = self.webhost.request('GET', 'default_template')
|
||||
self.assertTrue(r.ok)
|
||||
|
||||
|
||||
class TestFunctionsInBothBlueprintAndFuncApp(testutils.WebHostTestCase):
|
||||
@classmethod
|
||||
def get_script_dir(cls):
|
||||
return testutils.E2E_TESTS_FOLDER / 'blueprint_functions' / \
|
||||
'functions_in_both_blueprint_functionapp'
|
||||
|
||||
@testutils.retryable_test(3, 5)
|
||||
def test_functions_in_both_blueprint_functionapp(self):
|
||||
r = self.webhost.request('GET', 'default_template')
|
||||
self.assertTrue(r.ok)
|
||||
|
||||
r = self.webhost.request('GET', 'return_http')
|
||||
self.assertTrue(r.ok)
|
||||
|
||||
|
||||
class TestMultipleFunctionRegisters(testutils.WebHostTestCase):
|
||||
@classmethod
|
||||
def get_script_dir(cls):
|
||||
return testutils.E2E_TESTS_FOLDER / 'blueprint_functions' / \
|
||||
'multiple_function_registers'
|
||||
|
||||
@testutils.retryable_test(3, 5)
|
||||
def test_function_in_blueprint_only(self):
|
||||
r = self.webhost.request('GET', 'return_http')
|
||||
self.assertEqual(r.status_code, 404)
|
||||
|
||||
|
||||
class TestOnlyBlueprint(testutils.WebHostTestCase):
|
||||
@classmethod
|
||||
def get_script_dir(cls):
|
||||
return testutils.E2E_TESTS_FOLDER / 'blueprint_functions' / \
|
||||
'only_blueprint'
|
||||
|
||||
@testutils.retryable_test(3, 5)
|
||||
def test_only_blueprint(self):
|
||||
"""Test if the default template of Http trigger in Python
|
||||
Function app
|
||||
will return OK
|
||||
"""
|
||||
r = self.webhost.request('GET', 'default_template')
|
||||
self.assertEqual(r.status_code, 404)
|
|
@ -37,5 +37,5 @@ async def raise_http_exception():
|
|||
raise HTTPException(status_code=404, detail="Item not found")
|
||||
|
||||
|
||||
app = func.FunctionApp(asgi_app=fast_app,
|
||||
http_auth_level=func.AuthLevel.ANONYMOUS)
|
||||
app = func.AsgiFunctionApp(app=fast_app,
|
||||
http_auth_level=func.AuthLevel.ANONYMOUS)
|
||||
|
|
|
@ -32,5 +32,5 @@ def raise_http_exception():
|
|||
return {"detail": "Item not found"}, 404
|
||||
|
||||
|
||||
app = func.FunctionApp(wsgi_app=flask_app.wsgi_app,
|
||||
http_auth_level=func.AuthLevel.ANONYMOUS)
|
||||
app = func.WsgiFunctionApp(app=flask_app.wsgi_app,
|
||||
http_auth_level=func.AuthLevel.ANONYMOUS)
|
||||
|
|
|
@ -172,5 +172,5 @@ async def unhandled_unserializable_error():
|
|||
raise UnserializableException('foo')
|
||||
|
||||
|
||||
app = func.FunctionApp(asgi_app=fast_app,
|
||||
http_auth_level=func.AuthLevel.ANONYMOUS)
|
||||
app = func.AsgiFunctionApp(app=fast_app,
|
||||
http_auth_level=func.AuthLevel.ANONYMOUS)
|
||||
|
|
|
@ -99,5 +99,5 @@ def unhandled_unserializable_error():
|
|||
raise UnserializableException('foo')
|
||||
|
||||
|
||||
app = func.FunctionApp(wsgi_app=flask_app.wsgi_app,
|
||||
http_auth_level=func.AuthLevel.ANONYMOUS)
|
||||
app = func.WsgiFunctionApp(app=flask_app.wsgi_app,
|
||||
http_auth_level=func.AuthLevel.ANONYMOUS)
|
||||
|
|
Загрузка…
Ссылка в новой задаче