# Azure Functions — Azure

Source: https://www.skillbyai.com/en/azure/s-functions

> Write event-driven functions with triggers and bindings, and choose a hosting plan.

## Code that runs when something happens

**Azure Functions** runs small pieces of code in response to a **trigger**: an HTTP request, a timer, a message on a queue, a new blob, a Cosmos DB change and more. **Bindings** connect inputs and outputs declaratively, so writing to a queue can be a return value rather than SDK code. Hosting plans change behaviour: the **Flex Consumption** plan (the newer serverless option) and the older **Consumption** plan scale to zero and bill per execution, at the cost of **cold starts**; the **Premium** plan keeps pre-warmed instances and supports VNet integration; a **Dedicated** plan runs on an App Service plan. Functions should be short, stateless and idempotent, because triggers can retry. For long-running, stateful workflows, **Durable Functions** adds orchestrations that checkpoint their progress.

## Trigger, function, binding

An event arrives, your code runs, and bindings move data in and out.

![An incoming event arrow enters a small function block, with an input arrow from a data store on top and an output arrow to a queue on the right.](assets/figures/azure/section-4-map.svg) — Figure 4.1 — Triggers start a function; bindings connect it to data.

## An HTTP function and a queue-triggered function (Python v2 model)

Decorators declare the trigger and output binding; `AzureWebJobsStorage` is the connection setting name.

```python
import azure.functions as func
import logging

app = func.FunctionApp()

@app.route(route="orders", methods=["POST"], auth_level=func.AuthLevel.FUNCTION)
@app.queue_output(arg_name="msg", queue_name="orders", connection="AzureWebJobsStorage")
def create_order(req: func.HttpRequest, msg: func.Out[str]) -> func.HttpResponse:
    msg.set(req.get_body().decode())
    return func.HttpResponse("accepted", status_code=202)

@app.queue_trigger(arg_name="item", queue_name="orders", connection="AzureWebJobsStorage")
def process_order(item: func.QueueMessage) -> None:
    logging.info("processing %s", item.get_body().decode())
```

## Make handlers idempotent

Queue triggers deliver at least once. If a function crashes after charging a card but before completing, the message comes back. Store an order ID and skip work that is already done.

**Quiz:** Which plan avoids cold starts with pre-warmed instances?

- [ ] Consumption
- [ ] Free App Service
- [x] Premium
- [ ] Azure Container Instances

*Answer:* Premium. The Premium plan keeps always-ready instances warm; consumption-style plans scale to zero.
