我正在尝试使用 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