首页 > 编程问答 >如何修复我的 Python Azure Function DevOps Pipeline 上的“找到 1 个函数(自定义)加载 0 个函数”

如何修复我的 Python Azure Function DevOps Pipeline 上的“找到 1 个函数(自定义)加载 0 个函数”

时间:2024-07-30 05:56:18浏览次数:14  
标签:python azure azure-functions devops

我正在尝试使用 Azure DevOps 构建管道将 Python Azure Function 部署到 Azure 门户。 由于某种原因,代码被部署到服务器,但我在尝试访问端点时收到 404 错误。 我收到一个错误,显示 1 functions found (Custom) 0 functions loaded ,以及在服务器上显示 ModuleNotFoundError: No module named 'requests' 的错误。 我已经这样做了几个小时,但没有运气。 我有以下与我遇到的错误有关的详细信息(见下文)。 我想知道是否有人可以帮助我排除故障,看看我是否可以正确部署此 DevOps 管道。 请告诉我,谢谢!

function_app.py:

import logging
import azure.functions as func

from src.api.controllers.etl_controller import ETLController
from src.helpers.configuration_helper import fetch_configurations

# Define your function
app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)

# Define your routes
@app.route(route="run", methods=["POST"])
def run(req: func.HttpRequest) -> func.HttpResponse:
    # Fetch updated configurations
    fetch_configurations()
    
    # Process the request
    logging.info(f'Processing request: {req.method} {req.url}')
    controller = ETLController()
    return controller.run_elphi_etl(req)

function.json:

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": ["post"]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}

host.json:

{
  "version": "2.0",
  "functionTimeout": "00:30:00",
  "logging": {
    "logLevel": {
      "default": "Debug"
    },
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  }
}

requirements.txt:

asgiref==3.8.1
asn1crypto==1.5.1
azure-appconfiguration==1.6.0
azure-core==1.30.2
azure-core-tracing-opentelemetry==1.0.0b11
azure-functions==1.20.0
azure-identity==1.17.1
azure-keyvault-secrets==4.8.0
azure-monitor-opentelemetry==1.6.0
azure-monitor-opentelemetry-exporter==1.0.0b27
certifi==2024.7.4
cffi==1.16.0
cfgv==3.4.0
charset-normalizer==3.3.2
colorama==0.4.6
coverage==7.5.4
cryptography==42.0.8
debugpy==1.8.2
Deprecated==1.2.14
distlib==0.3.8
filelock==3.15.4
fixedint==0.1.6
flatten-json==0.1.14
identify==2.6.0
idna==3.7
importlib_metadata==8.0.0
iniconfig==2.0.0
isodate==0.6.1
msal==1.30.0
msal-extensions==1.2.0
msrest==0.7.1
nodeenv==1.9.1
oauthlib==3.2.2
opentelemetry-api==1.26.0
opentelemetry-instrumentation==0.47b0
opentelemetry-instrumentation-asgi==0.47b0
opentelemetry-instrumentation-dbapi==0.47b0
opentelemetry-instrumentation-django==0.47b0
opentelemetry-instrumentation-fastapi==0.47b0
opentelemetry-instrumentation-flask==0.47b0
opentelemetry-instrumentation-psycopg2==0.47b0
opentelemetry-instrumentation-requests==0.47b0
opentelemetry-instrumentation-urllib==0.47b0
opentelemetry-instrumentation-urllib3==0.47b0
opentelemetry-instrumentation-wsgi==0.47b0
opentelemetry-resource-detector-azure==0.1.5
opentelemetry-sdk==1.26.0
opentelemetry-semantic-conventions==0.47b0
opentelemetry-util-http==0.47b0
packaging==24.1
platformdirs==4.2.2
pluggy==1.5.0
portalocker==2.10.1
pre-commit==3.7.1
psutil==5.9.8
pycparser==2.22
PyJWT==2.8.0
pyOpenSSL==24.2.1
pytest==8.2.2
pytest-cov==5.0.0
python-dotenv==1.0.1
pytz==2024.1
pywin32==306; sys_platform == 'win32'
PyYAML==6.0.1
requests==2.32.3
requests-oauthlib==2.0.0
six==1.16.0
snowflake-connector-python==3.11.0
sortedcontainers==2.4.0
tomlkit==0.13.0
typing_extensions==4.12.2
urllib3==2.2.2
virtualenv==20.26.3
wrapt==1.16.0
zipp==3.19.2

azure-pipelines-dev.yaml:

trigger:
  branches:
    include:
      - develop

pool:
  vmImage: "ubuntu-latest"

variables:
  PYTHON_VERSION: "3.11.8"
  FUNCTIONAPP_NAME: "fn-elphi-etl-dev"
  SERVICE_CONNECTION: "Elphi-ETL-Dev"
  RESOURCE_GROUP: "fn-elphi-etl-dev"
  PACKAGE_PATH: "$(Build.ArtifactStagingDirectory)/fn_elphi_etl.zip"

steps:
  - task: UsePythonVersion@0
    inputs:
      versionSpec: "$(PYTHON_VERSION)"
      addToPath: true
    displayName: "Install Python $(PYTHON_VERSION)"

  - script: |
      python -m pip install --upgrade pip
    displayName: "Upgrade pip"

  - script: |
      python -m pip install -r requirements.txt
    displayName: "Install dependencies"

  - script: |
      python -m pytest -v --cov=src --cov-report=term --cov-report=html --cov-report=xml:coverage.xml --junitxml=test-results.xml
    displayName: "Run tests with coverage"

  - task: PublishTestResults@2
    inputs:
      testResultsFormat: "JUnit"
      testResultsFiles: "test-results.xml"
      failTaskOnFailedTests: true
      testRunTitle: "Pytest Results"
    displayName: "Publish Pytest Results"

  - script: |
      mkdir -p $(Build.ArtifactStagingDirectory)/src
      shopt -s dotglob
      cp -r * $(Build.ArtifactStagingDirectory)/src/
      ls -l $(Build.ArtifactStagingDirectory)/src
    displayName: "Copy sources and all directories to artifact staging directory and list contents"

  - task: ArchiveFiles@2
    inputs:
      rootFolderOrFile: "$(Build.ArtifactStagingDirectory)/src"
      includeRootFolder: false
      archiveType: "zip"
      archiveFile: "$(PACKAGE_PATH)"
      replaceExistingArchive: true
    displayName: "Archive files"

  - task: PublishPipelineArtifact@1
    inputs:
      targetPath: "$(Build.ArtifactStagingDirectory)/src"
      artifact: "$(FUNCTIONAPP_NAME)"
    displayName: "Publish Python project as artifact"

  - task: PublishCodeCoverageResults@2
    inputs:
      summaryFileLocation: "$(Build.SourcesDirectory)/coverage.xml"
    displayName: "Publish code coverage results"

  - task: AzureFunctionApp@1
    inputs:
      azureSubscription: "$(SERVICE_CONNECTION)"
      appType: "functionAppLinux"
      appName: "$(FUNCTIONAPP_NAME)"
      package: "$(PACKAGE_PATH)"
      runtimeStack: "python|3.11"
      startUpCommand: "func start"
    displayName: "Deploy Azure Function App"

服务器日志:

2024-07-26T17:36:54.860 [Information] Starting JobHost
2024-07-26T17:36:54.861 [Information] Starting Host (HostId=fn-elphi-etl-dev, InstanceId=f791376b-5871-4ad4-ab78-47b08af12162, Version=4.34.2.2, ProcessId=26, AppDomainId=1, InDebugMode=True, InDiagnosticMode=False, FunctionsExtensionVersion=~4)
2024-07-26T17:36:54.863 [Information] Loading functions metadata
2024-07-26T17:36:54.869 [Information] Reading functions metadata (Custom)
2024-07-26T17:36:54.871 [Information] 1 functions found (Custom)
2024-07-26T17:36:54.873 [Information] 0 functions loaded
2024-07-26T17:36:54.875 [Debug] FUNCTIONS_WORKER_RUNTIME value: 'python'
2024-07-26T17:36:54.876 [Debug] Adding Function descriptor provider for language python.
2024-07-26T17:36:54.876 [Debug] Creating function descriptors.
2024-07-26T17:36:54.877 [Debug] Function descriptors created.
2024-07-26T17:36:54.878 [Debug] Placeholder mode is enabled: False
2024-07-26T17:36:54.878 [Debug] RpcFunctionInvocationDispatcher received no functions
2024-07-26T17:36:54.878 [Information] Generating 0 job function(s)
2024-07-26T17:36:54.885 [Warning] No job functions found. Try making your job classes and methods public. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).
2024-07-26T17:36:54.888 [Information] Initializing function HTTP routes
2024-07-26T21:00:17.863 [Debug] Hosting starting
2024-07-26T21:00:17.950 [Information] Traceback (most recent call last):
2024-07-26T21:00:17.950 [Information] File "/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/utils/wrappers.py", line 44, in call
2024-07-26T21:00:17.950 [Information] return func(*args, **kwargs)
2024-07-26T21:00:17.950 [Information] ^^^^^^^^^^^^^^^^^^^^^
2024-07-26T21:00:17.950 [Information] File "/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/loader.py", line 238, in index_function_app
2024-07-26T21:00:17.950 [Information] imported_module = importlib.import_module(module_name)
2024-07-26T21:00:17.950 [Information] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-07-26T21:00:17.950 [Information] File "/usr/local/lib/python3.11/importlib/__init__.py", line 126, in import_module
2024-07-26T21:00:17.950 [Information] return _bootstrap._gcd_import(name[level:], package, level)
2024-07-26T21:00:17.950 [Information] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-07-26T21:00:17.950 [Information] File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
2024-07-26T21:00:17.950 [Information] File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
2024-07-26T21:00:17.950 [Information] File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
2024-07-26T21:00:17.950 [Information] File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
2024-07-26T21:00:17.950 [Information] File "<frozen importlib._bootstrap_external>", line 940, in exec_module
2024-07-26T21:00:17.950 [Information] File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
2024-07-26T21:00:17.950 [Information] File "/home/site/wwwroot/function_app.py", line 4, in <module>
2024-07-26T21:00:17.950 [Information] from src.api.controllers.etl_controller import ETLController
2024-07-26T21:00:17.950 [Information] File "/home/site/wwwroot/src/api/controllers/etl_controller.py", line 6, in <module>
2024-07-26T21:00:17.950 [Information] from src.api.services.etl_service import ETLService
2024-07-26T21:00:17.950 [Information] File "/home/site/wwwroot/src/api/services/etl_service.py", line 4, in <module>
2024-07-26T21:00:17.950 [Information] from src.api.services.elphi_service import ElphiService
2024-07-26T21:00:17.950 [Information] File "/home/site/wwwroot/src/api/services/elphi_service.py", line 3, in <module>
2024-07-26T21:00:17.950 [Information] from src.clients.elphi_client import ElphiClient
2024-07-26T21:00:17.950 [Information] File "/home/site/wwwroot/src/clients/elphi_client.py", line 3, in <module>
2024-07-26T21:00:17.950 [Information] import requests
2024-07-26T21:00:17.950 [Error] ModuleNotFoundError: No module named 'requests'

错误信息“找到 1 个函数(自定义)加载 0 个函数”以及“ModuleNotFoundError: No module named 'requests'”表明,虽然你的 Azure Function 应用已部署,但它无法加载你的函数,因为它无法找到 requests 模块。

以下是修复此问题需要注意的几点:

1. Requirements.txt 文件的位置:

  • 确保 requirements.txt 文件位于你的 Function 应用项目的 根目录 中,与 host.json function_app.py 位于同一级别。

2. requirements.txt 文件的内容:

  • 验证 requests 包是否已包含在你的 requirements.txt 文件中。 你提供的文件中确实包含它,但请务必仔细检查。

3. 部署包:

  • 确保你的部署包 ( fn_elphi_etl.zip ) 包含 requirements.txt 文件和所有必要的代码文件。 看起来你正在将所有内容打包到 src 文件夹中,但请确保包含根级别的 requirements.txt 文件。

4. 依赖项安装:

  • 在你的 azure-pipelines-dev.yaml 文件中,你正在安装依赖项,但这发生在构建阶段,而不是在部署阶段。 你需要在部署阶段之后添加一个步骤,以确保在 Function 应用运行时安装依赖项。

修改后的 azure-pipelines-dev.yaml 文件示例:

# ...(现有步骤)...

  - task: AzureFunctionApp@1
    inputs:
      # ...(现有输入)...
    displayName: "Deploy Azure Function App"

  - task: AzureCLI@2 # 在部署后添加此步骤
    inputs:
      azureSubscription: $(SERVICE_CONNECTION)
      scriptType: 'bash'
      scriptLocation: 'inlineScript'
      inlineScript: |
        az functionapp config appsettings set --name $(FUNCTIONAPP_NAME) --resource-group $(RESOURCE_GROUP) --settings WEBSITE_RUN_FROM_PACKAGE="1"
        az webapp ssh -g $(RESOURCE_GROUP) -n $(FUNCTIONAPP_NAME) --command "python3 -m pip install -r requirements.txt"

这段代码添加了一个新的步骤,该步骤使用 Azure CLI 在部署后的 Function 应用中执行以下操作:

  • 设置 WEBSITE_RUN_FROM_PACKAGE 应用程序设置: 此设置强制 Function 应用从部署包运行,确保所有依赖项都可用。
  • 通过 SSH 连接到 Function 应用并安装依赖项: 此步骤使用 pip requirements.txt 文件安装所有必需的 Python 包。

5. 重启 Function 应用:

  • 在对部署流程进行任何更改后,请确保 重启你的 Function 应用 。 你可以在 Azure 门户中或使用 Azure CLI 执行此操作。

其他提示:

  • 仔细检查你的服务器日志,查找可能提供有关此问题的更多上下文的任何其他错误消息。
  • 如果问题仍然存在,请尝试创建一个简单的 Python 函数应用(例如,使用 func init ),并仅使用 requests 依赖项进行部署。 这将有助于你确定问题是否与你的代码或部署流程有关。

通过执行这些步骤,你应该能够解决“找到 1 个函数(自定义)加载 0 个函数”和“ModuleNotFoundError”错误,并使你的 Python Azure Function 应用按预期工作。

标签:python,azure,azure-functions,devops
From: 78809134

相关文章

  • 使用 kivy 从 python 脚本的 buildozer 构建 android apk 时出错
    我想从使用kivy包构建的Python脚本构建apk为此,我使用googlecollab.这里是main.py脚本:importyoutube_dlfromkivy.appimportAppfromkivy.uix.boxlayoutimportBoxLayoutfromkivy.uix.buttonimportButtonfromkivy.uix.tex......
  • 自动解码并检索 S/MIME 加密电子邮件的正文 (python)
    我如何:用python代码连接我的邮件收件箱以自动获取未读电子邮件的加密内容;解码S/MIME加密电子邮件(我有密钥);检索电子邮件正文纯文本;检查正文(或主题)是否与某个关键字(现在为“test”)匹配,并在匹配时打印一些内容;在树莓派上使用此代码,无需手动......
  • Python 3 写入 DBF(带有 Memo 的 dBase IV)
    我需要在Python3中写入带有备注字段的dBaseIVdbf文件,但找不到合适的模块来执行此操作。我尝试过的包:Simpledbf-只读dbf-不支持dBaseIVdbfpy-不支持Python3dbfpy3-不支持dBaseIVYDbf-不支持备注字段pyshp-无法仅使用dbf文件......
  • Robin-Stocks Python 中的 order_buy_fractional_by_price 问题
    我在Robin-StocksPython包中的order_buy_fractional_by_price函数中遇到问题。在正常市场交易时间内下达以美元为基础的买入订单时,该订单被错误地设置为限价订单。对我来说看起来有问题的代码似乎是导致此问题的原因。我尝试在包管理器中本地修改或删除有问题的代码,但遇......
  • 在python中使用turtle绘制图案(带点)
    我正在尝试使用python中的海龟制作一幅赫斯特画(点图案)。我设法实现了它。Hirst_painting_dot_pattern但是我的for循环没有按照我预期的方式工作。它省略了最后一次迭代。在下面的代码中,我的for循环没有生成最后一个点。因此,我在循环末尾添加了一行来制作最后......
  • 使用 Python 进行 QuantLib Vanilla 掉期定价 - 错误
    我真的需要帮助...我有一个使用QuantLib构建自己的VanillaSwapPricer的项目。我想根据ois掉期的市场价格进行计算以进行贴现,并根据Euribor6M掉期+FRA进行预测固定。总而言之,我的目标是尽可能接近彭博社对标准Euribor6M掉期的定价(贴现ois)-fwdEuribor6M)。......
  • 我正在制作一个可以打开wav文件的python程序,我想知道wav文件的格式是什么
    因此,我已经通过此网站的研究编写了验证并读取wav标头的代码。但我想知道,data段中的数据是如何存储的?它们位于16位部分中,彼此相邻放置。我认为在Audacity中制作440hz正弦波,然后导出它,会显示一些结果,并且字节确实看起来更整齐,但仍然像废话一样接缝。相信我,我已经......
  • python - 面板库 - PasswordInput 不会对回车做出反应
    我试图避免需要提交按钮。以下代码当前正在远程jupyter实验室运行。仅当光标焦点从密码小部件中移除后,才会打印该消息。我想要回车来触发消息打印。有什么线索吗?frompanel.widgetsimportPasswordInput,TextInputpn.extension()defon_enter(event=None):message_p......
  • 即使安装了软件包,也找不到 python 模块句子转换器
    对于我的python脚本(如下所示),我使用句子转换器包,其中包含SBERT模型。即使在执行“piplist”时明确列出该软件包,并且还安装了torch,所有内容都更新到最新版本,但仍然找不到该模块。脚本:importnumpyasnpimportpandasaspdfromsentence_transformersimportSenten......
  • 有没有办法在 python 中返回类实例的布尔属性?
    我想组织我玩的游戏中的汽车数据。为此,我创建了一个“Car”类。我希望将此类实例的一些属性作为布尔值,这样我就可以将此类的所有实例放入列表中并过滤它们。我当前的解决方案不起作用,因为,我收到以下错误消息:TypeError:__repr__returnednon-string(typeCar)我使用......