Skip to content

Getting Started

This quickstart takes you from zero to a working Azure Functions API with:

  • a documented HTTP endpoint (@openapi)
  • generated OpenAPI JSON and YAML routes
  • Swagger UI route

Prerequisites

Before you begin, make sure you have:

  • Python 3.10+
  • Azure Functions Core Tools v4
  • An Azure Functions Python v2 app (func.FunctionApp)

Warning

azure-functions-openapi targets the Azure Functions Python v2 decorator model. It does not support the legacy function.json model.

Install dependencies

pip install azure-functions azure-functions-openapi

If you use Pydantic models in your function contracts:

pip install pydantic

Create your first documented endpoint

Add a file like function_app.py:

import json

import azure.functions as func
from pydantic import BaseModel

from azure_functions_openapi import get_openapi_json, get_openapi_yaml, openapi, render_swagger_ui

app = func.FunctionApp()


class HelloResponse(BaseModel):
    message: str


@app.function_name(name="http_trigger")
@app.route(route="http_trigger", methods=["GET"], auth_level=func.AuthLevel.ANONYMOUS)
@openapi(
    summary="Greet user",
    description="Returns a greeting using the `name` query parameter.",
    tags=["Hello"],
    operation_id="greetUser",
    route="/api/http_trigger",
    method="get",
    parameters=[
        {
            "name": "name",
            "in": "query",
            "required": True,
            "schema": {"type": "string"},
            "description": "Name to greet",
        }
    ],
    response_model=HelloResponse,
    response={
        200: {"description": "Successful greeting"},
        400: {"description": "Missing name"},
    },
)
def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
    name = req.params.get("name")
    if not name:
        return func.HttpResponse("Missing name", status_code=400)

    return func.HttpResponse(
        json.dumps({"message": f"Hello, {name}!"}),
        mimetype="application/json",
        status_code=200,
    )

Add spec endpoints

Add JSON and YAML routes to publish the generated spec:

@app.function_name(name="openapi_json")
@app.route(route="openapi.json", methods=["GET"], auth_level=func.AuthLevel.ANONYMOUS)
def openapi_json(req: func.HttpRequest) -> func.HttpResponse:
    return func.HttpResponse(
        get_openapi_json(
            title="Hello API",
            version="1.0.0",
            description="OpenAPI spec for Hello API",
        ),
        mimetype="application/json",
    )


@app.function_name(name="openapi_yaml")
@app.route(route="openapi.yaml", methods=["GET"], auth_level=func.AuthLevel.ANONYMOUS)
def openapi_yaml(req: func.HttpRequest) -> func.HttpResponse:
    return func.HttpResponse(
        get_openapi_yaml(
            title="Hello API",
            version="1.0.0",
            description="OpenAPI spec for Hello API",
        ),
        mimetype="application/x-yaml",
    )

Note

get_openapi_json() and get_openapi_yaml() return strings. Wrap them in func.HttpResponse as shown above.

Add Swagger UI endpoint

@app.function_name(name="swagger_ui")
@app.route(route="docs", methods=["GET"], auth_level=func.AuthLevel.ANONYMOUS)
def swagger_ui(req: func.HttpRequest) -> func.HttpResponse:
    return render_swagger_ui(
        title="Hello API Docs",
        openapi_url="/api/openapi.json",
    )

Run locally

func start

When startup succeeds, test all routes.

Test with curl

Call your endpoint:

curl "http://localhost:7071/api/http_trigger?name=Azure"

Expected response:

{"message":"Hello, Azure!"}

Fetch JSON spec:

curl "http://localhost:7071/api/openapi.json"

Fetch YAML spec:

curl "http://localhost:7071/api/openapi.yaml"

View Swagger UI

Open:

http://localhost:7071/api/docs

You should see:

  • one operation (http_trigger)
  • operation summary and description
  • query parameter name
  • response schema generated from HelloResponse

Next steps

  1. Add request validation and richer models (Usage)
  2. Configure security schemes and OpenAPI versions (Configuration)
  3. Explore complete examples (Hello, Todo API, With Validation)

Troubleshooting quick checks

If docs are blank:

  • confirm endpoint functions are imported during app startup
  • confirm target handlers are decorated with @openapi
  • confirm openapi_url in render_swagger_ui() points to a valid route

For deeper issues, see Troubleshooting.