我是 azure 和 python 的新手。我开发并成功在本地测试了一个将 xlsb 文件转换为 xlsx 的函数。当我尝试在Azure Portal上部署和运行时,我遇到了以下失败
Result: Failure Exception: OSError: [Errno 30] Read-only file system: 'TEST2.xlsx'
所以我尝试研究和阅读,由于Azure Function Python是基于Linux的,文件只能保存到临时目录。我尝试修改我的函数以包含临时目录,但出现新错误Result: Failure Exception: FileNotFoundError: [Errno 2] No such file or directory: '/tmp/TEST2.xlsb'
。由于我对 azure 和 python 都很陌生,因此我在调试问题时遇到了麻烦。关于如何实现此结果的任何建议:blob 触发 azure 函数,将 xlsb 文件(在 blob 容器中)转换为 xlsx 并保存在 blob 容器中?以下是我对临时目录发现的第一次尝试和后续更改:
import os
import logging
import pandas as pd
#from io import BytesIO
import azure.functions as func
from azure.storage.blob import BlobServiceClient, ContainerClient, BlobClient
app = func.FunctionApp()
@app.blob_trigger(arg_name="myblob", path="raw/Input/{name}.xlsb",
connection="BlobStorageConnectionString")
def blob_trigger(myblob: func.InputStream):
logging.info(f"Python blob trigger function processed blob"
f"Name: {myblob.name}"
f"Blob Size: {myblob.length} bytes")
accountName = "name"
accountKey = "key"
connectionString = f"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey};EndpointSuffix=core.windows.net"
containerName = "raw/Input"
inputBlobname = myblob.name.replace("raw/Input/", "")
outputBlobname = inputBlobname.replace(".xlsb", ".xlsx")
blob_service_client = BlobServiceClient.from_connection_string(connectionString)
container_client = blob_service_client.get_container_client(containerName)
blob_client = container_client.get_blob_client(inputBlobname)
blob = BlobClient.from_connection_string(conn_str=connectionString, container_name=containerName, blob_name=outputBlobname)
df = pd.read_excel(blob_client.download_blob().readall(), engine="pyxlsb")
df.to_excel(outputBlobname, index=False)
with open(outputBlobname, "rb") as data:
blob.upload_blob(data, overwrite=True)
import os
import logging
import pandas as pd
#from io import BytesIO
import azure.functions as func
from azure.storage.blob import BlobServiceClient, ContainerClient, BlobClient
app = func.FunctionApp()
@app.blob_trigger(arg_name="myblob", path="raw/Input/{name}.xlsb",
connection="BlobStorageConnectionString")
def blob_trigger(myblob: func.InputStream):
logging.info(f"Python blob trigger function processed blob"
f"Name: {myblob.name}"
f"Blob Size: {myblob.length} bytes")
accountName = "name"
accountKey = "key"
connectionString = f"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey};EndpointSuffix=core.windows.net"
containerName = "raw/Input"
inputBlobname = myblob.name.replace("raw/Input/", "")
localBlobname = "/tmp/" + inputBlobname
outputBlobname = inputBlobname.replace(".xlsb", ".xlsx")
blob_service_client = BlobServiceClient.from_connection_string(connectionString)
container_client = blob_service_client.get_container_client(containerName)
blob_client = container_client.get_blob_client(inputBlobname)
blob = BlobClient.from_connection_string(conn_str=connectionString, container_name=containerName, blob_name=outputBlobname)
df = pd.read_excel(blob_client.download_blob().readall(), engine="pyxlsb")
df.to_excel("/tmp/" + outputBlobname, index=False)
ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
with open(file = os.path.join(ROOT_DIR, localBlobname), mode="rb") as data:
blob.upload_blob(data, overwrite=True)
我尝试使用以下代码使用 Azure Function 应用程序将 .xlsb blob 转换为 Azure 存储容器中的 .xlsx blob。
代码:
import logging
import pandas as pd
import azure.functions as func
from azure.storage.blob import BlobServiceClient
from io import BytesIO
app = func.FunctionApp()
@app.blob_trigger(arg_name="myblob", path="<container_name>/<file_name>.xlsb",
connection="kamblobstr_STORAGE")
def blob_trigger(myblob: func.InputStream):
logging.info(f"Python blob trigger function processed blob"
f"Blob Size: {myblob.length} bytes")
accountName = "<storage_name>"
accountKey = "<strorage_key>"
connectionString = f"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey};EndpointSuffix=core.windows.net"
containerName = "<container_name>"
outputBlobname = "<file_name>.xlsx"
blob_service_client = BlobServiceClient.from_connection_string(connectionString)
container_client = blob_service_client.get_container_client(containerName)
input_data = myblob.read()
df = pd.read_excel(BytesIO(input_data), engine="pyxlsb")
output_data = BytesIO()
df.to_excel(output_data, index=False)
output_data.seek(0)
blob_client = container_client.get_blob_client(outputBlobname)
blob_client.upload_blob(output_data.getvalue(), overwrite=True)
local.settings.json:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "<storage_connec_string>",
"FUNCTIONS_WORKER_RUNTIME": "python",
"AzureWebJobsFeatureFlags": "EnableWorkerIndexing",
"kamblobstr_STORAGE": "<storage_connec_string>"
}
}
输出:
blob触发功能代码正在运行,我将kamb.xlsb文件上传到Azure blob存储容器,如下所示:
我收到消息输出:“blob kamb.xlsb 已转换为 kamb.xlsx”,如下所示:
* Executing task: .venv\Scripts\activate && func host start
Found Python version 3.10.11 (py).
Azure Functions Core Tools
Core Tools Version: 4.0.5030 Commit hash: N/A (64-bit)
Function Runtime Version: 4.15.2.20177
[2024-03-17T04:00:10.684Z] Host lock lease acquired by instance ID '000000xxxxxxxxxxxx'.
[2024-03-17T04:00:22.921Z] Worker process started and initialized.
Functions:
blob_trigger: blobTrigger
For detailed output, run func with --verbose flag.
[2024-03-17T04:00:43.865Z] Executing 'Functions.blob_trigger' (Reason='New blob detected(LogsAndContainerScan): kamcontainer/kamb.xlsb', Id=4c9d45e5xxxxxxxxxxxxxxxx)
[2024-03-17T04:00:43.870Z] Trigger Details: MessageId: a1416e18xxxxxxxxxxxxxx, DequeueCount: 1, InsertedOn: 2024-03-17T04:00:43.000+00:00, BlobCreated: 2024-03-17T04:00:39.000+00:00, BlobLastModified: 2024-03-17T04:00:39.000+00:00
[2024-03-17T04:00:44.005Z] Python blob trigger function processed blobBlob Size: None bytes
[2024-03-17T04:00:47.081Z] Request URL: 'https://kamblobstr.blob.core.windows.net/kamcontainer/kamb.xlsx'
Request method: 'PUT'
Request headers:
'Content-Length': '4976'
'x-ms-blob-type': 'REDACTED'
'x-ms-version': 'REDACTED'
'Content-Type': 'application/octet-stream'
'Accept': 'application/xml'
'User-Agent': 'azsdk-python-storage-blob/12.19.1 Python/3.10.11 (Windows-10-10.0.22631-SP0)'
'x-ms-date': 'REDACTED'
'x-ms-client-request-id': 'ef51c49exxxxxxxxxxxxxxx'
'Authorization': 'REDACTED'
A body is sent with the request
[2024-03-17T04:00:49.113Z] Response status: 201
Response headers:
'Content-Length': '0'
'Content-MD5': 'REDACTED'
'Last-Modified': 'Sun, 17 Mar 2024 04:00:49 GMT'
'ETag': '"0x8DC4636D53FDEE9"'
'Server': 'Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0'
'x-ms-request-id': '94236a36xxxxxxxxxxxxxxxxx'
'x-ms-client-request-id': 'ef51c49exxxxxxxxxxxxxxxxxx'
'x-ms-version': 'REDACTED'
'x-ms-content-crc64': 'REDACTED'
'x-ms-request-server-encrypted': 'REDACTED'
'Date': 'Sun, 17 Mar 2024 04:00:49 GMT'
[2024-03-17T04:00:49.167Z] Executed 'Functions.blob_trigger' (Succeeded, Id=4c9d45e5xxxxxxxxxxxxxxx, Duration=6129ms)
随后我成功将项目部署到Azure function app中,如下图:
我将kamb.xlsb文件上传到Azure Blob存储容器中,它在Azure Portal上的Function应用程序中成功运行,如下所示:
blob kamb.xlsb在存储容器中转换为kamb.xlsx,如下所示。
kamb.xlsx 数据:
功能应用程序监控日志: