Python: Add Integration tests for AzureFunctions (#2020)

* Add Integration tests

* Remove DTS extension

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Add pyi file for type safety

* Add samples in readme

* Updated all readme instructions

* Address comments

* Update readmes

* Fix requirements

* Address comments

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Laveesh Rohra
2025-11-10 21:27:17 -08:00
committed by GitHub
Unverified
parent 916b51fe1a
commit 4eb31f120b
50 changed files with 1401 additions and 106 deletions
+12
View File
@@ -193,6 +193,18 @@ This directory contains samples demonstrating the capabilities of Microsoft Agen
| [`getting_started/multimodal_input/azure_responses_multimodal.py`](./getting_started/multimodal_input/azure_responses_multimodal.py) | Azure OpenAI Responses with multimodal (image) input example |
| [`getting_started/multimodal_input/openai_chat_multimodal.py`](./getting_started/multimodal_input/openai_chat_multimodal.py) | OpenAI Chat with multimodal (image) input example |
## Azure Functions
| Sample | Description |
|--------|-------------|
| [`getting_started/azure_functions/01_single_agent/`](./getting_started/azure_functions/01_single_agent/) | Host a single agent in Azure Functions with Durable Extension HTTP endpoints and per-session state. |
| [`getting_started/azure_functions/02_multi_agent/`](./getting_started/azure_functions/02_multi_agent/) | Register multiple agents in one function app with dedicated run routes and a health check endpoint. |
| [`getting_started/azure_functions/03_callbacks/`](./getting_started/azure_functions/03_callbacks/) | Capture streaming response telemetry via Durable Extension callbacks exposed through HTTP APIs. |
| [`getting_started/azure_functions/04_single_agent_orchestration_chaining/`](./getting_started/azure_functions/04_single_agent_orchestration_chaining/) | Chain sequential agent executions inside a durable orchestration while preserving the shared thread context. |
| [`getting_started/azure_functions/05_multi_agent_orchestration_concurrency/`](./getting_started/azure_functions/05_multi_agent_orchestration_concurrency/) | Run two agents concurrently within a durable orchestration and combine their domain-specific outputs. |
| [`getting_started/azure_functions/06_multi_agent_orchestration_conditionals/`](./getting_started/azure_functions/06_multi_agent_orchestration_conditionals/) | Route orchestration logic based on structured agent responses for spam detection and reply drafting. |
| [`getting_started/azure_functions/07_single_agent_orchestration_hitl/`](./getting_started/azure_functions/07_single_agent_orchestration_hitl/) | Implement a human-in-the-loop approval loop that iterates on agent output inside a durable orchestration. |
## Observability
| File | Description |
@@ -28,11 +28,10 @@ source .venv/bin/activate
### 2. Install dependencies
- Azure Functions Core Tools 4.x install from the official docs so you can run `func start` locally.
- Azurite storage emulator the sample uses `AzureWebJobsStorage=UseDevelopmentStorage=true`; start Azurite before launching the app.
- Durable Task local backend `DURABLE_TASK_SCHEDULER_CONNECTION_STRING` expects the Durable Task scheduler listening on `http://localhost:8080` (start the Durable Functions emulator if it is not already running).
- [Azure Functions Core Tools 4.x](https://learn.microsoft.com/azure/azure-functions/functions-run-local?tabs=windows%2Cpython%2Cv2&pivots=programming-language-python#install-the-azure-functions-core-tools) install so you can run `func start` locally.
- [Azurite storage emulator](https://learn.microsoft.com/azure/storage/common/storage-use-azurite?tabs=visual-studio) install and start Azurite before launching the app (the sample uses `AzureWebJobsStorage=UseDevelopmentStorage=true`).
- Python dependencies from this folder, run `pip install -r requirements.txt` (or the equivalent in your active virtual environment).
- Copy `local.settings.json.template` to `local.settings.json` and update the values for `AZURE_OPENAI_ENDPOINT` and `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME` (and optionally `AZURE_OPENAI_API_KEY`) with your Azure OpenAI resource details; keep the other values as provided unless you are using custom infrastructure.
- Copy `local.settings.json.template` to `local.settings.json`, then update `AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`, and `AZURE_OPENAI_API_KEY` so the Azure OpenAI SDK can authenticate; keep `TASKHUB_NAME` set to `default` unless you plan to change the durable task hub name.
## Running the Sample
@@ -14,13 +14,11 @@ Content-Type: application/json
{
"message": "Add a security element to it.",
"sessionId": "session-003",
"waitForCompletion": false
"waitForCompletion": true
}
### Ask for a joke (plain text payload)
POST {{agentRoute}}/run
x-wait-for-completion: true
Give me a programming joke about race conditions.
### Retrieve conversation state
GET {{agentRoute}}/session-001
Give me a programming joke about race conditions.
@@ -22,7 +22,7 @@ def _create_agent() -> Any:
# 2. Register the agent with AgentFunctionApp so Azure Functions exposes the required triggers.
app = AgentFunctionApp(agents=[_create_agent()], enable_health_check=True)
app = AgentFunctionApp(agents=[_create_agent()], enable_health_check=True, max_poll_retries=50)
"""
Expected output when invoking `POST /api/agents/Joker/run` with plain-text input:
@@ -3,5 +3,10 @@
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
},
"extensions": {
"durableTask": {
"hubName": "%TASKHUB_NAME%"
}
}
}
@@ -4,7 +4,9 @@
"FUNCTIONS_WORKER_RUNTIME": "python",
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
"TASKHUB_NAME": "default",
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>"
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>",
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>"
}
}
@@ -1,2 +1,3 @@
agent-framework-azurefunctions
azure-identity
azure-identity
packaging
@@ -27,11 +27,13 @@ source .venv/bin/activate
### 2. Install dependencies
See the [README.md](../README.md) file in the parent directory for more information on how to configure the environment, including how to install and run common sample dependencies.
- [Azure Functions Core Tools 4.x](https://learn.microsoft.com/azure/azure-functions/functions-run-local?tabs=windows%2Cpython%2Cv2&pivots=programming-language-python#install-the-azure-functions-core-tools) install so you can run `func start` locally.
- [Azurite storage emulator](https://learn.microsoft.com/azure/storage/common/storage-use-azurite?tabs=visual-studio) install and start Azurite before launching the app; the sample expects `AzureWebJobsStorage=UseDevelopmentStorage=true`.
- Python dependencies from this folder, run `pip install -r requirements.txt` (or use the equivalent command in your active virtual environment).
### 3. Configure local settings
Copy `local.settings.json.template` to `local.settings.json`, then set the Azure OpenAI values (`AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`, and optionally `AZURE_OPENAI_API_KEY`) to match your environment.
- Copy `local.settings.json.template` to `local.settings.json`, then set the Azure OpenAI values (`AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`, and `AZURE_OPENAI_API_KEY`) so the SDK can authenticate, and keep `TASKHUB_NAME` set to `default` unless you intend to change the durable task hub name.
## Running the Sample
@@ -51,7 +51,8 @@ Content-Type: application/json
{
"message": "Calculate a 20% tip on a $50 bill",
"sessionId": "math-user-001"
"sessionId": "math-user-001",
"waitForCompletion": true
}
###
@@ -67,7 +67,7 @@ math_agent = chat_client.create_agent(
# 2. Register both agents with AgentFunctionApp to expose their HTTP routes and health check.
app = AgentFunctionApp(agents=[weather_agent, math_agent], enable_health_check=True)
app = AgentFunctionApp(agents=[weather_agent, math_agent], enable_health_check=True, max_poll_retries=50)
# Option 2: Add agents after initialization (commented out as we're using Option 1)
# app = AgentFunctionApp(enable_health_check=True)
@@ -11,5 +11,10 @@
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
},
"extensions": {
"durableTask": {
"hubName": "%TASKHUB_NAME%"
}
}
}
@@ -4,7 +4,9 @@
"FUNCTIONS_WORKER_RUNTIME": "python",
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
"TASKHUB_NAME": "default",
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>"
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>",
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>"
}
}
@@ -1,2 +1,3 @@
agent-framework-azurefunctions
packaging
azure-identity
@@ -17,10 +17,10 @@ an HTTP API that can be polled by a web client or dashboard.
## Prerequisites
- Python 3.11+
- Azure Functions Core Tools v4
- Access to an Azure OpenAI deployment (configure the environment variables listed in
`local.settings.json` or export them in your shell)
- Python 3.10+
- [Azure Functions Core Tools 4.x](https://learn.microsoft.com/azure/azure-functions/functions-run-local?tabs=windows%2Cpython%2Cv2&pivots=programming-language-python#install-the-azure-functions-core-tools)
- [Azurite storage emulator](https://learn.microsoft.com/azure/storage/common/storage-use-azurite?tabs=visual-studio) running locally so the sample can use `AzureWebJobsStorage=UseDevelopmentStorage=true`
- Access to an Azure OpenAI deployment with `AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`, and `AZURE_OPENAI_API_KEY` configured (either in `local.settings.json` or exported in your shell)
- Dependencies from `requirements.txt` installed in your environment
> **Note:** The sample stores callback events in memory for simplicity. For production scenarios you
@@ -48,7 +48,7 @@ an HTTP API that can be polled by a web client or dashboard.
pip install -r requirements.txt
```
3. Copy `local.settings.json.template` to `local.settings.json` and update the values (or export them as environment variables) with your Azure resources.
3. Copy `local.settings.json.template` to `local.settings.json` and update `AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`, and `AZURE_OPENAI_API_KEY` (or export them as environment variables) for your Azure resources, making sure `TASKHUB_NAME` remains `default` unless you have changed the durable task hub name.
4. Start the Functions host:
@@ -11,5 +11,10 @@
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
},
"extensions": {
"durableTask": {
"hubName": "%TASKHUB_NAME%"
}
}
}
@@ -4,7 +4,9 @@
"FUNCTIONS_WORKER_RUNTIME": "python",
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
"TASKHUB_NAME": "default",
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>"
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>",
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>"
}
}
@@ -1,2 +1,3 @@
agent-framework-azurefunctions
azure-identity
azure-identity
packaging
@@ -9,15 +9,16 @@ preserving the conversation state between runs.
- HTTP endpoints for starting the orchestration and polling for status/output
## Prerequisites
- Python 3.11+
- Azure Functions Core Tools v4
- Local Azure Storage / Azurite and the Durable Task sidecar running
- Python 3.10+
- [Azure Functions Core Tools 4.x](https://learn.microsoft.com/azure/azure-functions/functions-run-local?tabs=windows%2Cpython%2Cv2&pivots=programming-language-python#install-the-azure-functions-core-tools)
- [Azurite storage emulator](https://learn.microsoft.com/azure/storage/common/storage-use-azurite?tabs=visual-studio) running locally so the sample can use `AzureWebJobsStorage=UseDevelopmentStorage=true`
- Environment variables configured:
- `AZURE_OPENAI_ENDPOINT`
- `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`
- `AZURE_OPENAI_API_KEY` (omit if using Azure CLI authentication)
- Copy `local.settings.json.template` to `local.settings.json` and populate those keys (and any storage settings) before running the Functions host.
- Dependencies installed: `pip install -r requirements.txt`
- `AZURE_OPENAI_API_KEY` (required for key-based auth; ensure Azure CLI is logged in if you prefer token-based auth)
- Keep `TASKHUB_NAME` set to `default` unless you intend to change the durable task hub name.
- Copy `local.settings.json.template` to `local.settings.json` and populate those keys—including `AZURE_OPENAI_API_KEY`—along with any storage settings before running the Functions host.
- Install dependencies with `pip install -r requirements.txt`
## Running the Sample
1. Start the Functions host: `func start`.
@@ -1,23 +1,12 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"maxTelemetryItemsPerSecond": 20
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle.Preview",
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
},
"extensions": {
"durableTask": {
"storageProvider": {
"type": "azureManaged",
"connectionStringName": "DURABLE_TASK_SCHEDULER_CONNECTION_STRING"
}
"hubName": "%TASKHUB_NAME%"
}
}
}
@@ -4,7 +4,9 @@
"FUNCTIONS_WORKER_RUNTIME": "python",
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
"TASKHUB_NAME": "default",
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>"
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>",
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>"
}
}
@@ -1,2 +1,3 @@
agent-framework-azurefunctions
azure-identity
packaging
@@ -8,15 +8,16 @@ This sample starts a Durable Functions orchestration that runs two agents in par
- HTTP routes (`/api/multiagent/run` and `/api/multiagent/status/{instanceId}`) mirror the .NET sample for parity.
## Prerequisites
- Python 3.11+
- Azure Functions Core Tools v4
- Azurite / Azure Storage emulator and Durable Task sidecar running locally
- Python 3.10+
- [Azure Functions Core Tools 4.x](https://learn.microsoft.com/azure/azure-functions/functions-run-local?tabs=windows%2Cpython%2Cv2&pivots=programming-language-python#install-the-azure-functions-core-tools)
- [Azurite storage emulator](https://learn.microsoft.com/azure/storage/common/storage-use-azurite?tabs=visual-studio) running locally so the sample can use `AzureWebJobsStorage=UseDevelopmentStorage=true`
- Environment variables configured:
- `AZURE_OPENAI_ENDPOINT`
- `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`
- `AZURE_OPENAI_API_KEY` (omit when using Azure CLI auth)
- Copy `local.settings.json.template` to `local.settings.json` and fill in those Azure OpenAI values (and storage settings) before starting the Functions host.
- Install dependencies: `pip install -r requirements.txt`
- `AZURE_OPENAI_API_KEY` (required for key-based auth; ensure the Azure CLI is logged in if you rely on token-based auth)
- Keep `TASKHUB_NAME` set to `default` unless you intend to change the durable task hub name.
- Copy `local.settings.json.template` to `local.settings.json` and fill in those Azure OpenAI values—including `AZURE_OPENAI_API_KEY`—along with storage settings before starting the Functions host.
- Install dependencies with `pip install -r requirements.txt`
## Running the Sample
1. Start the Functions host: `func start`.
@@ -1,23 +1,12 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"maxTelemetryItemsPerSecond": 20
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle.Preview",
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
},
"extensions": {
"durableTask": {
"storageProvider": {
"type": "azureManaged",
"connectionStringName": "DURABLE_TASK_SCHEDULER_CONNECTION_STRING"
}
"hubName": "%TASKHUB_NAME%"
}
}
}
@@ -4,7 +4,9 @@
"FUNCTIONS_WORKER_RUNTIME": "python",
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
"TASKHUB_NAME": "default",
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>"
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>",
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>"
}
}
@@ -1,2 +1,3 @@
agent-framework-azurefunctions
azure-identity
packaging
@@ -4,11 +4,12 @@ This sample evaluates incoming emails with a spam detector agent and,
when appropriate, drafts a response using an email assistant agent.
## Prerequisites
- Python 3.11 environment with dependencies from `requirements.txt` installed.
- Azure Functions Core Tools (`func`) available on the PATH.
- Environment variables `AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`, and either
`AZURE_OPENAI_API_KEY` or an active Azure CLI login.
- Copy `local.settings.json.template` to `local.settings.json` and populate those Azure OpenAI settings (and storage values) before starting the host.
- Python 3.10+ environment with dependencies from `requirements.txt` installed.
- [Azure Functions Core Tools 4.x](https://learn.microsoft.com/azure/azure-functions/functions-run-local?tabs=windows%2Cpython%2Cv2&pivots=programming-language-python#install-the-azure-functions-core-tools) available on the PATH.
- [Azurite storage emulator](https://learn.microsoft.com/azure/storage/common/storage-use-azurite?tabs=visual-studio) running locally so the sample can use `AzureWebJobsStorage=UseDevelopmentStorage=true`.
- Environment variables `AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`, and `AZURE_OPENAI_API_KEY`.
- Keep `TASKHUB_NAME` set to `default` unless you intend to change the durable task hub name.
- Copy `local.settings.json.template` to `local.settings.json` and populate those Azure OpenAI settings—including `AZURE_OPENAI_API_KEY`—along with storage values before starting the host.
## Scenario Overview
- Two Azure OpenAI agents share a single deployment: one flags spam, the other drafts replies.
@@ -1,23 +1,12 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"maxTelemetryItemsPerSecond": 20
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle.Preview",
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
},
"extensions": {
"durableTask": {
"storageProvider": {
"type": "azureManaged",
"connectionStringName": "DURABLE_TASK_SCHEDULER_CONNECTION_STRING"
}
"hubName": "%TASKHUB_NAME%"
}
}
}
@@ -4,7 +4,9 @@
"FUNCTIONS_WORKER_RUNTIME": "python",
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
"TASKHUB_NAME": "default",
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>"
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>",
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>"
}
}
@@ -1,2 +1,3 @@
agent-framework-azurefunctions
azure-identity
packaging
@@ -5,11 +5,12 @@ A single writer agent iterates on content until a human reviewer approves the
output or a maximum number of attempts is reached.
## Prerequisites
- Python 3.11 environment with the packages from `requirements.txt` installed.
- Azure Functions Core Tools (`func`) available on the PATH.
- Environment variables `AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`, and either
`AZURE_OPENAI_API_KEY` or an active Azure CLI session.
- Copy `local.settings.json.template` to `local.settings.json` and configure those keys (plus storage settings) before starting the Functions host.
- Python 3.10+ environment with the packages from `requirements.txt` installed.
- [Azure Functions Core Tools 4.x](https://learn.microsoft.com/azure/azure-functions/functions-run-local?tabs=windows%2Cpython%2Cv2&pivots=programming-language-python#install-the-azure-functions-core-tools) available on the PATH.
- [Azurite storage emulator](https://learn.microsoft.com/azure/storage/common/storage-use-azurite?tabs=visual-studio) running locally so the sample can use `AzureWebJobsStorage=UseDevelopmentStorage=true`.
- Environment variables `AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`, and `AZURE_OPENAI_API_KEY`.
- Keep `TASKHUB_NAME` set to `default` unless you intend to change the durable task hub name.
- Copy `local.settings.json.template` to `local.settings.json` and configure those keys—including `AZURE_OPENAI_API_KEY`—plus storage settings before starting the Functions host.
## What It Shows
- Identical environment variable usage (`AZURE_OPENAI_ENDPOINT`,
@@ -63,7 +63,7 @@ app = AgentFunctionApp(agents=[_create_writer_agent()], enable_health_check=True
# 3. Activities encapsulate external work for review notifications and publishing.
@app.activity_trigger(input_name="content")
def notify_user_for_approval(content: dict[str, Any]) -> None:
def notify_user_for_approval(content: dict) -> None:
model = GeneratedContent.model_validate(content)
logger.info("NOTIFICATION: Please review the following content for approval:")
logger.info("Title: %s", model.title or "(untitled)")
@@ -72,7 +72,7 @@ def notify_user_for_approval(content: dict[str, Any]) -> None:
@app.activity_trigger(input_name="content")
def publish_content(content: dict[str, Any]) -> None:
def publish_content(content: dict) -> None:
model = GeneratedContent.model_validate(content)
logger.info("PUBLISHING: Content has been published successfully:")
logger.info("Title: %s", model.title or "(untitled)")
@@ -1,23 +1,12 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"maxTelemetryItemsPerSecond": 20
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle.Preview",
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
},
"extensions": {
"durableTask": {
"storageProvider": {
"type": "azureManaged",
"connectionStringName": "DURABLE_TASK_SCHEDULER_CONNECTION_STRING"
}
"hubName": "%TASKHUB_NAME%"
}
}
}
@@ -4,7 +4,9 @@
"FUNCTIONS_WORKER_RUNTIME": "python",
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
"TASKHUB_NAME": "default",
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>"
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>",
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>"
}
}
@@ -1,2 +1,3 @@
agent-framework-azurefunctions
azure-identity
packaging