如何为Azure函数Python V2连接依赖注入

yyyllmsg  于 2023-11-20  发布在  Python
关注(0)|答案(1)|浏览(89)

我是一名.net开发人员,最近开始使用python,我正在尝试使用python创建Azure函数v2,并寻求有关如何将依赖项注入到我的函数中的帮助。我查看了各种python依赖项注入的示例,并且通常能够做到这一点。但我无法弄清楚在哪里调用我的引导。
在.net中,这可以简单地通过扩展FunctionStarup类来完成,我在python azure-functions包中找不到这样的东西。Microsoft文档在python函数v2编程指南python developer guidance for azure function v2中也没有提到任何关于Dependent注入的内容
这是我试过的示例的部分代码片段,但它不起作用。我在下面的示例中使用了kink作为DI
类我试图注入

class IocService:
        def __init__(self, message: str):
            self.message = message
    
        def say_hello(self, name: str) -> str:
            return f"{self.message}, {name}!"

字符串

使用blueprint定义函数

from kink import inject
import logging

from IocService import IocService

import azure.functions as func 

bp = func.Blueprint() 
@inject
@bp.route(route="default_template") 
def default_template(req: func.HttpRequest, context: func.Context, service: IocService) -> func.HttpResponse: 
    logging.info('Python HTTP trigger function processed a request.') 
    #ioc_service = context.get_service(IocService)

    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 
        )


function_app.py

import azure.functions as func 
from http_blueprint import bp
from bootstrap import start_up

print("before start up")
start_up()
print("After start up")
app = func.FunctionApp() 
app.register_functions(bp)


下面是错误消息

>       File "<path>\function_app.py", line 2, in <module>
>     from http_blueprint import bp   File "<path>\http_blueprint.py", line 9, in <module>
>     @inject
>      ^^^^^^   File "<path>\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\kink\inject.py",
> line 203, in inject
>     return _decorator(_service)
>            ^^^^^^^^^^^^^^^^^^^^   File "<Path>\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\kink\inject.py",
> line 193, in _decorator
>     service_function = _decorate(bind or {}, _service, container)
>                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   File
> "<Path>\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\kink\inject.py",
> line 105, in _decorate
>     service in [ABC.__init__, _no_init] or service.__name__ == "_no_init"
> 
>


https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-python?tabs=asgi%2Capplication-level&pivots=python-mode-decorators
当我通过从httptrigger方法中删除注入来运行函数时,日志显示了非常有趣的事情:
1.它打印函数中的日志
1.然后打印function_app.py中的日志

flseospp

flseospp1#

您可以直接将依赖类或方法添加到Function Trigger目录中的不同文件中,并在Function App中调用它。参考如下:
我的**sidblueprint.py**:-

import azure.functions as func
import logging
from IocService import IocService


app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)

bp = func.Blueprint() 

@bp.route(route="HttpRequest") 
def main(req: func.HttpRequest) -> func.HttpResponse:
    message = "Hello from IocService"  # Define your message
    ioc_service = IocService(message)  # Instantiate the IocService

    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:
        response = ioc_service.say_hello(name)
        return func.HttpResponse(response, status_code=200)
    else:
        return func.HttpResponse(
             "name with query string or body",
             status_code=400
        )

字符串
我的**function_app.py**:-

import azure.functions as func 
from sidblueprint import bp

app = func.FunctionApp() 

app.register_functions(bp)


我的**IocService.py:-**

class IocService:
    def __init__(self, message: str):
        self.message = message

    def say_hello(self, name: str) -> str:
        return f"{self.message}, {name}!"

输出:-

x1c 0d1x的数据



根据这个 * SO thread answer,你可以使用Python中的*dependency_injector**模块在Python脚本和函数中注入Dependency注入。

我的sidblueprint.py with dependency_injector模块:-

import azure.functions as func
import logging
# from IocService import IocService

from dependency_injector import containers, providers

from dependency_injector.wiring import Provide, inject

class IocService:
    def __init__(self, message: str):
        self.message = message

    def say_hello(self, name: str) -> str:
        return f"{self.message}, {name}!"

class Container(containers.DeclarativeContainer):
    ioc_service = providers.Factory(
        IocService,
        message="Hello"  # Set your default message here
    )

container = Container()

app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)

bp = func.Blueprint() 
@inject
@bp.route(route="HttpRequest") 
def main(req: func.HttpRequest) -> func.HttpResponse:
    message = "Hello from IocService"  # Define your message
    ioc_service = IocService(message)  # Instantiate the IocService

    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:
        response = ioc_service.say_hello(name)
        return func.HttpResponse(response, status_code=200)
    else:
        return func.HttpResponse(
             "name with query string or body",
             status_code=400
        )

输出:-



requirements.txt:-

azure-functions
dependency_injector

相关问题