我在 python 中创建了一个简单的基于 HTTP 触发器的 azure 函数,该函数调用另一个 python 脚本在 azure 数据湖第 1 代中创建示例文件。我的解决方案结构如下:-
Requirements.txt 包含以下导入:-
- azure 函数
- azure 管理资源
- azure-mgmt-datalake-store
- azure-datalake-store
init.py
import logging, os, sys
import azure.functions as func
import json
def main(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:
full_path_to_script = os.path.join(os.path.dirname( __file__ ) + '/Test.py')
logging.info(f"Path: - {full_path_to_script}")
os.system(f"python {full_path_to_script}")
return func.HttpResponse(f"Hello {name}!")
else:
return func.HttpResponse(
"Please pass a name on the query string or in the request body",
status_code=400
)
测试.py
import json
from azure.datalake.store import core, lib, multithread
directoryId = ''
applicationKey = ''
applicationId = ''
adlsCredentials = lib.auth(tenant_id = directoryId, client_secret = applicationKey, client_id = applicationId)
adlsClient = core.AzureDLFileSystem(adlsCredentials, store_name = '')
with adlsClient.open('stage1/largeFiles/TestFile.json', 'rb') as input_file:
data = json.load(input_file)
with adlsClient.open('stage1/largeFiles/Result.json', 'wb') as responseFile:
responseFile.write(data)
Test.py 失败,并出现未找到模块 azure.datalake.store 的错误 为什么其他必需的模块不适用于 Test.py,因为它位于同一目录中?
pip 卡住输出:-
adal==1.2.2
azure-common==1.1.23
azure-datalake-store==0.0.48
azure-functions==1.0.4
azure-mgmt-datalake-nspkg==3.0.1
azure-mgmt-datalake-store==0.5.0
azure-mgmt-nspkg==3.0.2
azure-mgmt-resource==6.0.0
azure-nspkg==3.0.2
certifi==2019.9.11
cffi==1.13.2
chardet==3.0.4
cryptography==2.8
idna==2.8
isodate==0.6.0
msrest==0.6.10
msrestazure==0.6.2
oauthlib==3.1.0
pycparser==2.19
PyJWT==1.7.1
python-dateutil==2.8.1
requests==2.22.0
requests-oauthlib==1.3.0
six==1.13.0
urllib3==1.25.6
最佳答案
问题
os.system(f"python {full_path_to_script}")
您的函数项目导致了该问题。
Azure Functions Runtime 设置环境,并修改进程级别变量,如 os.path
以便您的函数可以加载您可能拥有的任何依赖项。当您创建这样的子流程时,并非所有信息都会流过。此外,您将面临日志记录问题 - 来自 test.py
的日志。除非明确处理,否则不会正确显示。
导入可以在本地进行,因为您拥有所有 requirements.txt
模块已安装并可用于test.py
。 Azure 中的情况并非如此。作为发布的一部分进行远程构建后,您的模块将作为发布的代码包的一部分包含在内。它本身并未全局“安装”在 Azure 环境中。
解决方案
您不必像那样运行脚本。在上面的示例中,您可以导入 test.py
来自您的__init__.py
文件,其行为应该类似于 python test.py
(至少在上述情况下)。您是否有理由想要这样做 python test.py
在子流程中导入它?
以下是有关如何构建应用程序以导入共享代码的官方指南 -- https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-python#folder-structure
旁注
我想一旦你完成了import
问题,您可能还会遇到 adlsClient.open('stage1/largeFiles/TestFile.json', 'rb')
的问题。我们建议按照上面的开发人员指南来构建您的项目并使用 __file__
获取绝对路径( reference )。
例如——
import pathlib
with open(pathlib.Path(__file__).parent / 'stage1' / 'largeFiles' /' TestFile.json'):
....
<小时/>
现在,如果你真的想制作os.system(f"python {full_path_to_script}")
工作,我们有解决导入问题的方法。但是,我宁愿不推荐这种方法,除非您确实有迫切的需求。 :)
关于python - Azure Functions - 无法在调用的脚本中导入其他Python模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59244744/