Skip to main content

LangGraph integration for Azure Functions Python v2 — deploy compiled graphs as HTTP endpoints

Project description

Azure Functions LangGraph

PyPI Python Version CI Release Security Scans codecov pre-commit Docs License: MIT

Read this in: 한국어 | 日本語 | 简体中文

Beta Notice — This package is under active development (0.4.0). Core APIs are stabilizing but may still change between minor releases. Please report issues on GitHub.

Deploy LangGraph graphs as Azure Functions HTTP endpoints with minimal boilerplate.


Part of the Azure Functions Python DX Toolkit

Why this exists

Deploying LangGraph on Azure Functions is harder than it should be.

  • LangGraph does not provide an Azure Functions-native deployment adapter
  • Exposing compiled graphs as HTTP endpoints requires repetitive wiring
  • Teams often rebuild the same invoke/stream wrapper for every project

This package provides a focused adapter for serving LangGraph graphs on Azure Functions Python v2.

What it does

  • Zero-boilerplate deployment — register a compiled graph, get HTTP endpoints automatically
  • Invoke endpointPOST /api/graphs/{name}/invoke for synchronous execution
  • Stream endpointPOST /api/graphs/{name}/stream for buffered SSE responses
  • Health endpointGET /api/health listing registered graphs with checkpointer status
  • Checkpointer pass-through — thread-based conversation state works via LangGraph's native config
  • State endpointGET /api/graphs/{name}/threads/{thread_id}/state for thread state inspection (when supported)
  • Per-graph auth — override app-level auth with register(..., auth_level=...)
  • LangGraph Platform API compatibility — SDK-compatible endpoints for threads, runs, assistants, and state (v0.3+)
  • Persistent storage backends — Azure Blob Storage checkpointer and Azure Table Storage thread store (v0.4+)

LangGraph Platform comparison

Feature LangGraph Platform azure-functions-langgraph
Hosting LangChain Cloud (paid) Your Azure subscription
Assistants Built-in SDK-compatible API (v0.3+)
Thread lifecycle Built-in Create, get, update, delete, search, count (v0.3+)
Runs Built-in Threaded + threadless runs (v0.4+)
State read/update Built-in get_state + update_state (v0.4+)
State history Built-in Checkpoint history with filtering (v0.4+)
Streaming True SSE Buffered SSE
Persistent storage Built-in Azure Blob + Table Storage (v0.4+)
Infrastructure Managed Azure Functions (serverless)
Cost model Per-seat/usage Azure Functions pricing

Scope

  • Azure Functions Python v2 programming model
  • LangGraph graph deployment and HTTP exposure
  • LangGraph runtime concerns: invoke, stream, threads, runs, and state
  • Optional integration points for validation and OpenAPI via companion packages

This package is a deployment adapter — it wraps LangGraph, it does not replace it.

Internally, graph registration remains protocol-based (LangGraphLike), so any object satisfying the protocol works — but the package's documentation and examples focus on LangGraph use cases.

What this package does not do

This package does not own:

Note: For OpenAPI spec generation, use the azure-functions-openapi package with the bridge module (azure_functions_langgraph.openapi.register_with_openapi).

Installation

pip install azure-functions-langgraph

For persistent storage with Azure services:

# Azure Blob Storage checkpointer
pip install azure-functions-langgraph[azure-blob]

# Azure Table Storage thread store
pip install azure-functions-langgraph[azure-table]

# Both
pip install azure-functions-langgraph[azure-blob,azure-table]

Your Azure Functions app should also include:

azure-functions
langgraph
azure-functions-langgraph

For local development:

git clone https://github.com/yeongseon/azure-functions-langgraph.git
cd azure-functions-langgraph
pip install -e .[dev]

Quick Start

from langgraph.graph import END, START, StateGraph
from typing_extensions import TypedDict

import azure.functions as func

from azure_functions_langgraph import LangGraphApp


# 1. Define your state
class AgentState(TypedDict):
    messages: list[dict[str, str]]


# 2. Define your nodes
def chat(state: AgentState) -> dict:
    user_msg = state["messages"][-1]["content"]
    return {"messages": state["messages"] + [{"role": "assistant", "content": f"Echo: {user_msg}"}]}


# 3. Build graph
builder = StateGraph(AgentState)
builder.add_node("chat", chat)
builder.add_edge(START, "chat")
builder.add_edge("chat", END)
graph = builder.compile()

# 4. Deploy (ANONYMOUS for local dev; use FUNCTION in production — see below)
app = LangGraphApp(auth_level=func.AuthLevel.ANONYMOUS)
app.register(graph=graph, name="echo_agent")
func_app = app.function_app  # ← use this as your Azure Functions app

Start the Functions host locally:

func start

Verify locally and on Azure

After deploying (see docs/deployment.md), the same request produces the same response in both environments. Azure requires a function key (?code=<FUNCTION_KEY>) when auth_level is set to FUNCTION.

Local

curl -s http://localhost:7071/api/health
{"status": "ok", "graphs": [{"name": "echo_agent", "description": null, "has_checkpointer": false}]}

Azure

curl -s "https://<your-app>.azurewebsites.net/api/health?code=<FUNCTION_KEY>"
{"status": "ok", "graphs": [{"name": "echo_agent", "description": null, "has_checkpointer": false}]}

Response format verified against a temporary Azure Functions deployment of the simple_agent example in koreacentral (Python 3.12, Consumption plan). The Quick Start uses echo_agent for illustration; the health endpoint returns the same JSON structure regardless of graph name. URL anonymized.

Production authentication

Important: LangGraphApp defaults to AuthLevel.ANONYMOUS for local development convenience. This default will change to AuthLevel.FUNCTION in v1.0. For production deployments, always set auth_level explicitly:

import azure.functions as func

from azure_functions_langgraph import LangGraphApp

# Production: require function key authentication
app = LangGraphApp(auth_level=func.AuthLevel.FUNCTION)

Per-graph auth

Override app-level auth settings per graph:

# Per-graph authentication override
app.register(graph=public_graph, name="public", auth_level=func.AuthLevel.ANONYMOUS)
app.register(graph=private_graph, name="private", auth_level=func.AuthLevel.FUNCTION)

Example request using a function key:

curl -X POST "https://<app>.azurewebsites.net/api/graphs/echo_agent/invoke?code=<FUNCTION_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"input": {"messages": [{"role": "human", "content": "Hello!"}]}}'

What you get

  1. POST /api/graphs/echo_agent/invoke — invoke the agent
  2. POST /api/graphs/echo_agent/stream — stream agent responses (buffered SSE)
  3. GET /api/graphs/echo_agent/threads/{thread_id}/state — inspect thread state
  4. GET /api/health — health check

With platform_compat=True, you also get SDK-compatible endpoints:

  1. POST /assistants/search — list registered assistants
  2. GET /assistants/{id} — get assistant details
  3. POST /assistants/count — count assistants
  4. POST /threads — create thread
  5. GET /threads/{id} — get thread
  6. PATCH /threads/{id} — update thread metadata
  7. DELETE /threads/{id} — delete thread
  8. POST /threads/search — search threads
  9. POST /threads/count — count threads
  10. POST /threads/{id}/runs/wait — run and wait for result
  11. POST /threads/{id}/runs/stream — run and stream result
  12. POST /runs/wait — threadless run
  13. POST /runs/stream — threadless stream
  14. GET /threads/{id}/state — get thread state
  15. POST /threads/{id}/state — update thread state
  16. POST /threads/{id}/history — get state history

Request format

{
    "input": {
        "messages": [{"role": "human", "content": "Hello!"}]
    },
    "config": {
        "configurable": {"thread_id": "conversation-1"}
    }
}

Persistent storage (v0.4+)

Use Azure Blob Storage for checkpoint persistence and Azure Table Storage for thread metadata:

import azure.functions as func

from azure.storage.blob import ContainerClient
from langgraph.graph import END, START, StateGraph
from typing_extensions import TypedDict

from azure_functions_langgraph import LangGraphApp
from azure_functions_langgraph.checkpointers.azure_blob import AzureBlobCheckpointSaver
from azure_functions_langgraph.stores.azure_table import AzureTableThreadStore


class AgentState(TypedDict):
    messages: list[dict[str, str]]


def chat(state: AgentState) -> dict:
    user_msg = state["messages"][-1]["content"]
    return {"messages": state["messages"] + [{"role": "assistant", "content": f"Echo: {user_msg}"}]}


# Build graph with Azure Blob checkpointer
container_client = ContainerClient.from_connection_string(
    "DefaultEndpointsProtocol=https;AccountName=...", "checkpoints"
)
saver = AzureBlobCheckpointSaver(container_client=container_client)

builder = StateGraph(AgentState)
builder.add_node("chat", chat)
builder.add_edge(START, "chat")
builder.add_edge("chat", END)
graph = builder.compile(checkpointer=saver)

# Deploy with Azure Table thread store
thread_store = AzureTableThreadStore.from_connection_string(
    "DefaultEndpointsProtocol=https;AccountName=...", table_name="threads"
)

# Production: always set auth_level explicitly
app = LangGraphApp(platform_compat=True, auth_level=func.AuthLevel.FUNCTION)
app.thread_store = thread_store
app.register(graph=graph, name="echo_agent")
func_app = app.function_app

Checkpoints and thread metadata survive Azure Functions restarts and scale across instances.

Upgrading

v0.3.0 → v0.4.0

Fully backward-compatible. No breaking changes.

  • New optional extras: pip install azure-functions-langgraph[azure-blob,azure-table] for persistent storage
  • New platform endpoints: thread CRUD, state update/history, threadless runs, assistants count
  • New protocols: UpdatableStateGraph, StateHistoryGraph (available from azure_functions_langgraph.protocols)

v0.4.0 → v0.5.0

Fully backward-compatible. No breaking changes.

  • Metadata API: app.metadata() returns an immutable snapshot of all registered routes and graph info
  • OpenAPI bridge: azure_functions_langgraph.openapi.register_with_openapi integrates with azure-functions-openapi
  • CloneableGraph protocol: thread-isolated graph cloning for safe concurrent execution

When to use

  • You have LangGraph agents and want to deploy them on Azure Functions
  • You want serverless deployment without LangGraph Platform costs
  • You need HTTP endpoints for your compiled graphs with minimal setup
  • You want thread-based conversation state via LangGraph checkpointers
  • You need durable state persistence with Azure Blob/Table Storage

Documentation

  • Project docs live under docs/
  • Smoke-tested examples live under examples/
  • Product requirements: PRD.md
  • Design principles: DESIGN.md

Ecosystem

This package is part of the Azure Functions Python DX Toolkit.

Design principle: azure-functions-langgraph owns LangGraph runtime exposure. azure-functions-validation owns validation. azure-functions-openapi owns API documentation.

Package Role
azure-functions-langgraph LangGraph deployment adapter for Azure Functions
azure-functions-validation Request/response validation and serialization
azure-functions-openapi OpenAPI spec generation and Swagger UI
azure-functions-logging Structured logging and observability
azure-functions-doctor Pre-deploy diagnostic CLI
azure-functions-scaffold Project scaffolding
azure-functions-durable-graph Manifest-first graph runtime with Durable Functions
azure-functions-python-cookbook Recipes and examples

Disclaimer

This project is an independent community project and is not affiliated with, endorsed by, or maintained by Microsoft or LangChain.

Azure and Azure Functions are trademarks of Microsoft Corporation. LangGraph and LangChain are trademarks of LangChain, Inc.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

azure_functions_langgraph-0.5.0.tar.gz (163.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

azure_functions_langgraph-0.5.0-py3-none-any.whl (46.7 kB view details)

Uploaded Python 3

File details

Details for the file azure_functions_langgraph-0.5.0.tar.gz.

File metadata

File hashes

Hashes for azure_functions_langgraph-0.5.0.tar.gz
Algorithm Hash digest
SHA256 5deca88c5c6c07a1f3239d3142c7fe8357ea2367b97e00635f885f9c8342867c
MD5 bab093d02a9c27c7df432d39af4447d7
BLAKE2b-256 80c5113cd53ff154606ed512bb8bc7f6069dbe30765cc6d7de4608c79db458ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for azure_functions_langgraph-0.5.0.tar.gz:

Publisher: publish-pypi.yml on yeongseon/azure-functions-langgraph

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file azure_functions_langgraph-0.5.0-py3-none-any.whl.

File metadata

File hashes

Hashes for azure_functions_langgraph-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2d8c34ad597fa76147fac006ee1073d94123ad3e86f83300f5cc4b643d261ec0
MD5 0587d6c31768395eb08b459ca03b36ed
BLAKE2b-256 528be8b7f7de20bf6ff000aa77a47ec5ec79f3c973279c468ffcb133afaa20c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for azure_functions_langgraph-0.5.0-py3-none-any.whl:

Publisher: publish-pypi.yml on yeongseon/azure-functions-langgraph

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page