Triggers in Azure Function Apps with Python V2
Azure Function Apps offer a variety of triggers that respond to different events, allowing for efficient and responsive cloud-based applications. In this blog post, we will explore the different types of triggers available in Azure Function Apps, specifically for Python V2 programming model. We’ll cover HTTP trigger, schedule trigger, blob trigger, and event grid trigger, providing insights and code examples.
1. HTTP trigger
The HTTP trigger is perhaps the most straightforward and easy to understand for beginners. It allows your function to be invoked by an HTTP request.
Code example:
import azure.functions as func
import logging
import datetime
app = func.FunctionApp()
@app.function_name(name="HttpTriggerThis")
@app.route(route="dothis")
def test_function(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger do this')
return func.HttpResponse(
"This HTTP triggered do this function and executed it successfully.",
status_code=200
)
@app.function_name(name="HttpTriggerThat")
@app.route(route="dothat")
def test_function(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger do that')
return func.HttpResponse(
"This HTTP triggered do that function and executed it successfully.",
status_code=200
)
Please note that each function can only have a sigle trigger.
However, as you can see from the above example, we can define multiple functions within a single Function App, and for those we can define differnet endpoint routes (suffixes). In our example above we defined two of those: dothis
and dothat
.
We can also pass http parameters through this trigger. See the following code example:
import azure.functions as func
import logging
app = func.FunctionApp()
@app.function_name(name="HttpTrigger1")
@app.route(route="hello")
def test_function(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:
return func.HttpResponse(f"Hello, {name}. This HTTP triggered function executed successfully.")
else:
return func.HttpResponse(
"This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.",
status_code=200
)
In this example we are retrieving the name
parameter from the http call that triggered the function.
Note: Execution of functions using HTTP triggers is limited to a maximum of 230 seconds (Azure Functions Timeout Documentation).
2. Schedule trigger
Schedule triggers are used to run a function at a specified time, using a CRON expression which has 6 components.
Code example:
import azure.functions as func
import logging
import datetime
app = func.FunctionApp()
@app.function_name(name="ScheduleTrigger")
@app.schedule(schedule="*/10 * * * * *", arg_name="mytimer", run_on_startup=False,
use_monitor=True)
def test_function(mytimer: func.TimerRequest) -> None:
utc_timestamp = datetime.datetime.utcnow().replace(
tzinfo=datetime.timezone.utc).isoformat()
if mytimer.past_due:
logging.info('The timer is past due!')
logging.info('Python timer trigger function ran at %s', utc_timestamp)
We can also have multiple schedules in a single function app, however they need to be under separate event handling functions. Please see the example below:
import logging
import azure.functions as func
app = func.FunctionApp()
@app.schedule(schedule="* * * * * *", arg_name="myTimer", run_on_startup=False,
use_monitor=True)
def timer_trigger1(myTimer: func.TimerRequest) -> None:
if myTimer.past_due:
logging.info('The timer 1 is past due!')
logging.info('Python timer 1 trigger function executed.')
@app.schedule(schedule="*/5 * * * * *", arg_name="myTimer", run_on_startup=False,
use_monitor=True)
def timer_trigger2(myTimer: func.TimerRequest) -> None:
if myTimer.past_due:
logging.info('The timer 2 is past due!')
logging.info('Python timer 2 trigger function executed.')
Reference:
- Detailed guide on schedule triggers (Azure Schedule Trigger Guide).
3. Blob trigger
Blob triggers react to events in Azure Blob Storage, such as the creation of a new blob.
Code example:
import logging
import azure.functions as func
app = func.FunctionApp()
@app.function_name(name="BlobTrigger1")
@app.blob_trigger(arg_name="myblob",
path="mycontainer",
connection="BLOB_CONNECTION_STRING")
def test_function(myblob: func.InputStream):
logging.info(f"Python blob trigger function processed blob \n"
f"Name: {myblob.name}\n"
f"Blob Size: {myblob.length} bytes")
Please note it is not possible for the function app to listen to events in multiple storage containers. To do that, this is a potential workaround:
import logging
import azure.functions as func
app = func.FunctionApp()
def show_blob_details(blob_name, blob_length):
logging.info(f"Python blob trigger function processed blob \n"
f"Name: {blob_name}\n"
f"Blob Size: {blob_length} bytes")
@app.blob_trigger(arg_name="myblob", path="container-a", connection="BLOB_CONNECTION_STRING")
def test_function_a(myblob: func.InputStream):
show_blob_details(myblob.name, myblob.length)
@app.blob_trigger(arg_name="myblob", path="container-b", connection="BLOB_CONNECTION_STRING")
def test_function_b(myblob: func.InputStream):
show_blob_details(myblob.name, myblob.length)
Reference:
- Blob Trigger Overview (Azure Blob Trigger Documentation).
- Blob Storage Trigger Tutorial (Azure Blob Storage Trigger Tutorial).
- Creating a Blob-Triggered Function in Azure Portal (Azure Blob Triggered Function Tutorial).
- Blob trigger vs listenining to multiple containers (see this)
Note:
- For blob event triggers, the metadata available is limited to
name, length, uri
(as per the Azure Functions InputStream Documentation).- Blob trigger is not the only trigger type usable with blob container events.
4. Event Grid Trigger
Event Grid triggers respond to events sent to Azure Event Grid. This can be an efficient way to handle events at scale.
Using event grid requires an Event Grid topic, with your Function App Function being subscribed to that topic. If your function needs to handle events from specific container, you need to set a filter on the subscription (all this can be done in Azure Portal, for more details please consult this resource):
Subject filters: Enable subject filtering
Subject Begins With: /blobServices/default/containers/<your_container_name>/blobs/
Code example:
import logging
import azure.functions as func
import json
app = func.FunctionApp()
@app.event_grid_trigger(arg_name="azeventgrid")
def EventGridTrigger(azeventgrid: func.EventGridEvent):
result = json.dumps({
'id': azeventgrid.id,
'data': azeventgrid.get_json(),
'topic': azeventgrid.topic,
'subject': azeventgrid.subject,
'event_type': azeventgrid.event_type,
})
logging.info('Python EventGrid trigger processed an event: %s', result)
Reference:
- Understanding Event Grid (Event Grid Video Explanation).
- Tutorial: Trigger Azure Functions on blob containers using an event subscription
The trigger selection dilemma
Please note that for the same type of event, such as a file upload to a storage container, you can choose from several trigger types depending on your specific requirements. Handling blob storage events efficiently is pivotal for many cloud-based applications. Azure provides several trigger options, each designed to respond to different types of blob storage events, enabling developers to tailor their applications to specific needs.
The primary trigger for blob storage events in Azure Functions is the Blob Trigger. This trigger is specifically designed to react when a new blob is added to a container, or an existing blob is updated. It’s particularly useful for scenarios like processing data as soon as it arrives in the storage. The Blob Trigger ensures that your function is invoked as soon as the specified event occurs in the blob storage. However, it’s important to note that the Blob Trigger may have a slight delay in processing large volumes of blobs due to its polling mechanism.
Another important trigger is the Event Grid Trigger, which integrates Azure Functions with Azure Event Grid. This trigger is more event-driven compared to the Blob Trigger and offers near-real-time processing capabilities. It’s ideal for scenarios where you need to react promptly to changes in your Azure resources, including blob storage events. Unlike the Blob Trigger, the Event Grid Trigger is pushed-based, meaning it receives events as they happen, which can lead to more responsive and efficient processing.
For a more general-purpose trigger that can handle HTTP requests, the HTTP Trigger can be used. Though not directly related to blob storage events, this trigger can be configured to respond to HTTP requests that signify a change or an update in blob storage, often acting as a webhook.
Additionally, the Queue Trigger can indirectly respond to blob storage events. In this scenario, a separate process would monitor the blob storage and place messages into a queue whenever a specific event occurs. The Queue Trigger would then respond to these messages, allowing for a decoupled architecture that can be more scalable and manageable.
Each of these triggers has its use cases, strengths, and considerations. The choice of trigger depends on factors such as the required responsiveness to events, the volume of data to be processed, and the overall architecture of the application.
For in-depth understanding and guidance, Microsoft offers extensive documentation and resources:
Advanced notes: trigger syncing
When you change any of your triggers, the Functions infrastructure must be aware of the changes. Synchronization happens automatically for many deployment technologies. However, in some cases, you must manually sync your triggers. Please refer to this resource for more details.