Getting Started¶
This quickstart walks you from zero to a validated Azure Functions HTTP endpoint in a few minutes.
By the end, you will have:
- request body validation with Pydantic
- response validation with
response_model - consistent error payloads for invalid input
Who this is for
This page is for teams using the Azure Functions Python v2 programming model
(func.FunctionApp() and decorators).
Prerequisites¶
Before starting, make sure you have:
- Python 3.10 or newer.
- An Azure Functions Python v2 app structure.
- Dependencies installed:
azure-functionsazure-functions-validationpydanticv2.
See Installation for version details.
Model compatibility
Use Pydantic v2 models (BaseModel).
Step 1: Add your first validated handler¶
Create or update function_app.py with this complete example:
import azure.functions as func
from pydantic import BaseModel, EmailStr, Field
from azure_functions_validation import validate_http
class SignupBody(BaseModel):
name: str = Field(min_length=1, max_length=100)
email: EmailStr
class SignupResponse(BaseModel):
message: str
status: str = "created"
app = func.FunctionApp()
@app.function_name(name="signup")
@app.route(route="signup", methods=["POST"], auth_level=func.AuthLevel.ANONYMOUS)
@validate_http(body=SignupBody, response_model=SignupResponse)
def signup(req: func.HttpRequest, body: SignupBody) -> SignupResponse:
return SignupResponse(message=f"Welcome {body.name}")
Why this works¶
body=SignupBodyvalidates incoming JSON.response_model=SignupResponsevalidates output before serialization.- The handler receives a typed
bodyobject.
Decorator order
Place @validate_http(...) closest to the function definition,
below @app.route(...).
Step 2: Run your app locally¶
Start your Azure Functions host as you normally do for local development.
The endpoint will be available at:
POST /api/signup
Step 3: Test with curl (valid request)¶
curl -i -X POST http://localhost:7071/api/signup \
-H "Content-Type: application/json" \
-d '{"name":"Ada","email":"ada@example.com"}'
Expected response:
Step 4: Test with curl (validation error)¶
Send an invalid body:
curl -i -X POST http://localhost:7071/api/signup \
-H "Content-Type: application/json" \
-d '{"name":"","email":"not-an-email"}'
Expected response:
Expanded shape example:
{
"detail": [
{
"loc": ["body", "name"],
"msg": "String should have at least 1 character",
"type": "string_too_short"
},
{
"loc": ["body", "email"],
"msg": "value is not a valid email address",
"type": "value_error"
}
]
}
Client integration
Build client-side error mapping around detail[*].loc, detail[*].msg,
and detail[*].type for stable UX.
Step 5: Understand status code behavior¶
200: handler returned valid output.400: body contained malformed JSON.422: request validation failed.500: response validation failed or internal runtime error.
Optional: Customize error responses¶
If your API has a custom error envelope, pass error_formatter:
from typing import Any
def my_error_formatter(exc: Exception, status_code: int) -> dict[str, Any]:
return {
"error": {
"code": f"VALIDATION_{status_code}",
"message": str(exc),
}
}
@validate_http(body=SignupBody, response_model=SignupResponse, error_formatter=my_error_formatter)
def signup_custom(req: func.HttpRequest, body: SignupBody) -> SignupResponse:
return SignupResponse(message=f"Welcome {body.name}")
Optional: Validate query/path/headers too¶
validate_http can validate more than request body:
query=Modelpath=Modelheaders=Model
See Configuration for all parameters and Usage for multi-source examples.
Troubleshooting checkpoints¶
If something does not work as expected:
- Confirm the handler first positional argument is
req(or equivalent request object). - Confirm your models inherit from
pydantic.BaseModel. - Confirm
@validate_httpis closest to the function definition. - Confirm JSON body is non-empty and valid.
- Confirm returned data matches
response_modelexactly.
For deeper fixes, go to Troubleshooting.
Next steps¶
- Read Configuration to tune each parameter.
- Read Usage for advanced patterns.
- Explore Basic Validation Example.
- Check API Reference for complete signatures.