This guide covers setting up the application for local development, including fully local (no Azure subscription) and cloud-connected options.
- Python 3.13+
- uv
- Azure CLI (for cloud Foundry authentication)
- Docker
- Microsoft Foundry Local (optional — for fully local development without Azure)
# Install dependencies
uv sync --all-groups --prerelease=allow
# Start the emulators (Cosmos DB, Azurite, Service Bus)
docker compose up -d
# Configure environment
cp .env.example .env
# Edit .env — set MSSQL_SA_PASSWORD and optionally configure cloud credentials
# Service Bus entity names are centrally managed project configuration
# (pipeline-commands / pipeline-events with worker-consumer / web-consumer).
# Run the web dashboard (with hot reload)
uv run python -m curate_web.app
# Run the worker (in a separate terminal)
uv run python -m curate_worker.appThe web service runs the editorial dashboard (FastAPI + HTMX) and the worker runs the agent pipeline (change feed processor + orchestrator). Both connect to the same Cosmos DB and communicate via Azure Service Bus for real-time SSE updates.
When APP_ENV=development, dashboard authentication is bypassed automatically for local use, so Microsoft Entra credentials are optional during local iteration.
The project uses three local emulators via Docker Compose:
| Emulator | Image | Ports | Purpose |
|---|---|---|---|
| Cosmos DB | mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:vnext-preview |
8081, 1234 | NoSQL data store + change feed |
| Azurite | mcr.microsoft.com/azure-storage/azurite |
10000–10002 | Blob storage for static site |
| Service Bus | mcr.microsoft.com/azure-messaging/servicebus-emulator |
5672 | Event bridge between web and worker |
The Service Bus emulator requires an Azure SQL Edge container as its backend. Both are configured in docker-compose.yml and use MSSQL_SA_PASSWORD from .env. The emulator is pre-configured with pipeline-commands and pipeline-events topics plus the worker-consumer and web-consumer subscriptions via servicebus-config.json. These names are fixed project configuration, not user-overridable .env values.
- The web service publishes
publish-requestcommands to thepipeline-commandstopic. - The worker service consumes commands from
worker-consumer. - The worker service publishes pipeline progress events to the
pipeline-eventstopic. - The web service consumes pipeline events from
web-consumeronpipeline-eventsand forwards them to SSE clients.
To run entirely locally without an Azure subscription, install Foundry Local and set FOUNDRY_PROVIDER=local in your .env:
# macOS
brew install microsoft/foundrylocal/foundrylocal
# Windows
winget install Microsoft.FoundryLocalThen in your .env:
FOUNDRY_PROVIDER=local
FOUNDRY_LOCAL_MODEL=phi-4-mini
The application will automatically start the Foundry Local service, download the model on first run, and use on-device inference. No az login or Azure credentials required for the LLM pipeline. Foundry Memory is automatically disabled when using Foundry Local.
For cloud-based inference, authenticate with Azure and set the Foundry project endpoint:
az loginThen in your .env:
FOUNDRY_PROVIDER=cloud
FOUNDRY_PROJECT_ENDPOINT=https://{resource-name}.services.ai.azure.com/api/projects/{project-name}
FOUNDRY_MODEL=your-model-deployment
For intermittent UI lock-up diagnostics in local development, run with verbose timing logs:
LOG_LEVEL=DEBUG APP_SLOW_REQUEST_MS=400 APP_SLOW_REPOSITORY_MS=150 \
uv run python -m curate_web.appuv run pytest tests/ -vuv run ruff check packages/ tests/
uv run ruff format packages/ tests/
uv run ty check packages/GitHub Actions with five workflows. Check and Test run in parallel on push / PR to main; Build, Release, and Deploy chain sequentially via workflow_run triggers. All Azure-facing workflows authenticate using OIDC federated credentials.
| Workflow | File | Trigger | Responsibility |
|---|---|---|---|
| Check | check.yml |
Push / PR to main |
Lint, format check, type check |
| Test | test.yml |
Push / PR to main |
Unit tests |
| Build | build.yml |
Check + Test success on main |
Docker build, push to ACR, Bicep validation |
| Release | release.yml |
Build success on main |
Bicep infrastructure deployment |
| Deploy | deploy.yml |
Release success on main |
Container App update |
az deployment group create \
--resource-group <rg-name> \
--template-file infra/main.bicep \
--parameters infra/params/prod.bicepparam