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:
peterstone2017 2022-07-01 11:00:05 -05:00 коммит произвёл GitHub
Родитель f51a1f1b0f
Коммит 1b52d72d8b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
13 изменённых файлов: 198 добавлений и 14 удалений

Просмотреть файл

@ -143,18 +143,19 @@ def index_function_app(function_path: str):
module_name = pathlib.Path(function_path).stem module_name = pathlib.Path(function_path).stem
imported_module = importlib.import_module(module_name) imported_module = importlib.import_module(module_name)
from azure.functions import FunctionApp from azure.functions import FunctionRegister
app: Optional[FunctionApp] = None app: Optional[FunctionRegister] = None
for i in imported_module.__dir__(): 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: if not app:
app = getattr(imported_module, i, None) app = getattr(imported_module, i, None)
else: else:
raise ValueError( 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: 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}.") f"{SCRIPT_FILE_NAME}.")
return app.get_functions() return app.get_functions()

Просмотреть файл

@ -105,7 +105,7 @@ INSTALL_REQUIRES = [
"grpcio~=1.43.0", "grpcio~=1.43.0",
"grpcio-tools~=1.43.0", "grpcio-tools~=1.43.0",
"protobuf~=3.19.3", "protobuf~=3.19.3",
'azure-functions==1.11.3b2', "azure-functions==1.11.3b2",
"python-dateutil~=2.8.2" "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") raise HTTPException(status_code=404, detail="Item not found")
app = func.FunctionApp(asgi_app=fast_app, app = func.AsgiFunctionApp(app=fast_app,
http_auth_level=func.AuthLevel.ANONYMOUS) http_auth_level=func.AuthLevel.ANONYMOUS)

Просмотреть файл

@ -32,5 +32,5 @@ def raise_http_exception():
return {"detail": "Item not found"}, 404 return {"detail": "Item not found"}, 404
app = func.FunctionApp(wsgi_app=flask_app.wsgi_app, app = func.WsgiFunctionApp(app=flask_app.wsgi_app,
http_auth_level=func.AuthLevel.ANONYMOUS) http_auth_level=func.AuthLevel.ANONYMOUS)

Просмотреть файл

@ -172,5 +172,5 @@ async def unhandled_unserializable_error():
raise UnserializableException('foo') raise UnserializableException('foo')
app = func.FunctionApp(asgi_app=fast_app, app = func.AsgiFunctionApp(app=fast_app,
http_auth_level=func.AuthLevel.ANONYMOUS) http_auth_level=func.AuthLevel.ANONYMOUS)

Просмотреть файл

@ -99,5 +99,5 @@ def unhandled_unserializable_error():
raise UnserializableException('foo') raise UnserializableException('foo')
app = func.FunctionApp(wsgi_app=flask_app.wsgi_app, app = func.WsgiFunctionApp(app=flask_app.wsgi_app,
http_auth_level=func.AuthLevel.ANONYMOUS) http_auth_level=func.AuthLevel.ANONYMOUS)