If you’ve been working with Python and want to try serverless on Azure, Azure Functions is one of the easiest places to start.
This post walks you through the basics and gets a working HTTP-triggered function running.
What is Azure Functions?
Azure Functions is a serverless compute service:
- No servers to manage
- Yes, there are servers...but Azure manages them
- No scaling to configure for simple cases.
You write a small piece of code, tell Azure what should trigger it, and Azure handles the rest.
That trigger event can be an HTTP request, a new file in storage, a message on a queue, a timer, and more.
For light workloads, the cost is often very low or even free under the monthly free grant.
Azure Functions has different hosting plans, and billing depends on which one you choose:
- Consumption: You pay based on executions and resource usage, with a monthly free grant for eligible subscriptions. Storage, networking, and related services may cost extra.
- Flex Consumption: On-demand execution is billed by usage, but optional always-ready instances incur charges even while idle.
- Premium or Dedicated: You can pay for allocated compute capacity even when your functions aren't executing
Why use Python?
Python is a great choice for Azure Functions.
It has good tools, a simple programming model, and supports many familiar libraries. If you already use Python to write scripts, build APIs, or process data, you'll feel right at home.
Two things you need to know
- Triggers
Something that starts your function. For this post we’ll use an HTTP trigger - Bindings
A simple way to connect your function to other Azure services without writing a lot of connection code.
Things you will need
- An Azure account (free tier is fine)
- Python 3.10 or newer
- Visual Studio Code (recommended) or just a terminal
- Azure Functions Core Tools
- The Azure Functions extension for VS Code (if you choose to use VS Code)
Create your first function
Open a terminal and run:
macOS / Linux (bash)/ Windows (PowerShell):
func init my-first-function --python -m V2
cd my-first-function
This creates and initializes a new Python Azure Functions project using the Python v2 programming model, which uses decorators and Python code to define functions. Then, it changes the directory to its folder so you can start building your function.
What is the Python programming model V2?
Azure Functions has two Python programming models:
- Model V1: Functions are typically defined using separate folders, each with a
function.jsonfile.- Model V2: Functions are defined directly in Python code, commonly using decorators such as
@app.route()or@app.timer_trigger().
What happens when you run them?
func init my-first-function --python -m V2- Creates a folder named
my-first-function. - Initializes an Azure Functions project using Python.
- Uses the Python programming model V2.
- Creates configuration files such as
host.jsonandfunction_app.py.
- Creates a folder named
cd my-first-function- Moves your terminal into the newly created project folder.
- Does not create any files.
What does the folder look like?
After initialization, you'll typically see something like this:
my-first-function/
├── function_app.py
├── host.json
├── local.settings.json
└── requirements.txt
What is the main file?
The main file is function_app.py.
In Python programming model V2, you define your Azure Functions inside this file using decorators, rather than creating a separate .py file for every function.
Here is our sample function_app.py:
# Import Azure Functions tools
import azure.functions as func
# Import Python logging
import logging
# Create the Azure Functions application
app = func.FunctionApp()
# Create an HTTP endpoint at /api/hello
@app.route(route="hello")
def hello(req: func.HttpRequest) -> func.HttpResponse:
# Log that the function received an HTTP request
logging.info("Python HTTP trigger function processed a request.")
# Try to get "name" from the URL query string
name = req.params.get("name")
# If "name" was not provided in the URL
if not name:
try:
# Try to read the request body as JSON
req_body = req.get_json()
except ValueError:
# Do nothing if the body is not valid JSON
pass
else:
# Try to get "name" from the JSON body
name = req_body.get("name")
# If a name was found
if name:
# Return a personalized response
return func.HttpResponse(
f"Hello, {name}. Nice to meet you."
)
else:
# Return instructions if no name was provided
return func.HttpResponse(
"Please pass a name in the query string or in the request body.",
status_code=200
)
That’s a complete function.
The @app.route decorator turns it into an HTTP endpoint. The function receives an HttpRequest and returns an HttpResponse.
Run it locally
First, create and activate a virtual environment.
macOS / Linux (bash):
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Windows (PowerShell):
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
If PowerShell blocks the activation script, run this once:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserWindows PowerShell blocks scripts by default for security reasons. On most Windows client editions (Windows 10/11), the default execution policy is Restricted.
This PowerShell script does:
- RemoteSigned: Allows scripts that were created locally on your machine to run freely. Scripts downloaded from the internet (marked with the “Mark of the Web”) must be digitally signed by a trusted publisher, or you must explicitly unblock them first. This is a good balance between usability and safety.
- -Scope CurrentUser: Applies the change only to your user account. It does not require administrator rights and does not affect other users on the computer.
Then start the local runtime:
macOS / Linux / Windows:
func start
You’ll see a URL like http://localhost:7071/api/hello.
Open it in the browser or use curl / Invoke-WebRequest:
macOS / Linux:
curl "http://localhost:7071/api/hello?name=Atreyu"
Windows (PowerShell):
Invoke-WebRequest "http://localhost:7071/api/hello?name=Atreyu"
You should get back: Hello, Atreyu. Nice to meet you.
Helpful notes
- The route is relative to
/apiby default. - You can change the route name in the decorator.
req.paramsgives you query string values.req.get_json()reads a JSON body.- Logging goes to the console when running locally and to Application Insights when deployed.
Deploying to Azure
The easiest path for a first try is Visual Studio Code:
- Install the Azure Functions extension.
- Sign in to your Azure account.
- Click the Azure icon in the sidebar, then “Deploy to Function App”.
- Follow the prompts to create a new Function App (Consumption plan is fine for learning).
From the command line you can also use:
func azure functionapp publish <your-function-app-name>
Keep learning
Azure Functions is one of the lower-friction ways to run code in the cloud. The Python experience is clean, especially with the v2 model. I suggest to start small, get something running, then add complexity only when you need it.
Remember to look at the official docs and the Azure Functions GitHub samples. These are great resources If you get stuck.
About the author
- • engineer • learning • 🐍⚙️☁️📄
Comments
Join the discussionNo comments yet. Be the first to comment.


