I have a Function App in a Python v2 programming model, which has a blob_trigger that is supposed to do sth on new blobs being created in a given storage account and container. I am working in VSCode. The function app works well when running locally with Azurite, however when I deploy it to Azure, there is no "blobTrigger" function under the Function App.
This is a code of my function_app.py
:
import azure.functions as func
from azure.storage.blob.aio import BlobServiceClient
import datetime
import logging
import json
import os
import sys
import asyncio
_KV_SECRET_INPUT_BLOB_CONNECTION_STRING = os.environ["KV_SECRET_INPUT_BLOB_CONNECTION_STRING"]
STORAGE_CONTAINER_NAME = os.environ["STORAGE_CONTAINER_NAME"]
async def read_blob_contents(connection_string: str, input_container_name: str, input_blob_name: str):
blob_service_client = BlobServiceClient.from_connection_string(connection_string)
container_client = blob_service_client.get_container_client(input_container_name)
blob_client = container_client.get_blob_client(input_blob_name)
try:
blob_contents = await blob_client.download_blob(encoding = 'utf-8')
return await blob_contents.readall()
except Exception as e:
logging.error(f"Error reading blob: {str(e)}")
return None
finally:
await blob_service_client.close()
app = func.FunctionApp()
@app.function_name(name="blobTrigger")
@app.blob_trigger(arg_name="myblob", path=STORAGE_CONTAINER_NAME, connection="KV_SECRET_INPUT_BLOB_CONNECTION_STRING")
async def blob_trigger(myblob: func.InputStream, context: func.Context) -> None:
func_invoc_and_event_meta = json.dumps({
"function_name" : context.function_name,
"function_invocation_id" : context.invocation_id,
'blob_name': myblob.name,
'blob_length': myblob.length,
'blob_uri': myblob.uri,
}, indent=4)
logging.info('Blob trigger processed an event:')
logging.info(func_invoc_and_event_meta)
logging.info("Attempting to read the blob...")
try:
blob_url = myblob.uri
logging.info(f"blob_url: '{blob_url}'")
# Read the contents of the blob asynchronously
input_container_name = myblob.name.split('/', maxsplit=1)[0]
input_blob_name = myblob.name.split('/', maxsplit=1)[1]
blob_contents = await read_blob_contents(connection_string=_KV_SECRET_INPUT_BLOB_CONNECTION_STRING, input_container_name=input_container_name, input_blob_name=input_blob_name)
logging.error("blob reading completed")
except:
logging.error("ERROR during blob read : ")
logging.error(str(sys.exc_info()))
I made sure that the Function App has appropriate appsettings i.e. KV_SECRET_INPUT_BLOB_CONNECTION_STRING
and STORAGE_CONTAINER_NAME
. The KV_SECRET_INPUT_BLOB_CONNECTION_STRING
setting contains a connection string to the storage account that aims to store the data (new blobs), and it is a different storage account than the one that is linked to the function app through the AzureWebJobsStorage
appsetting.
So what could be the problem?
On a related note, I also deployed another function app which is triggered by CRON, and for that one everything worked as expected.
After testing and double checking everything I managed to narrow down issues to the following:
requirements.txt
did not contain all the python libs that were referenced in theimport
statements in thefunction_app.py
codeos.environ
statement, and as such could not be foundFixing those fixed the problem. When deployed, the function correctly appears under the function app.