Local Development
⚡ Local Development¶
Run the ARTVoice Accelerator locally with raw commands. No Makefile usage. Keep secrets out of git and rotate any previously exposed keys.
1. Scope¶
What this covers:
- Local backend (FastAPI + Uvicorn) and frontend (Vite/React)
- Dev tunnel for inbound Azure Communication Services callbacks
- Environment setup via venv OR Conda
- Minimal
.envfiles (root + frontend)
What this does NOT cover: - Full infra provisioning - CI/CD - Persistence hardening
2. Prerequisites¶
| Tool | Notes |
|---|---|
| Python 3.11 | Required runtime |
| Node.js ≥ 22 | Frontend |
| Azure CLI | az login first |
| Dev Tunnels | Getting Started Guide |
| (Optional) Conda | If using environment.yaml |
| Provisioned Azure resources | For real STT/TTS/LLM/ACS |
If you only want a browser demo (no phone), ACS variables are optional.
3. Clone Repository¶
git clone https://github.com/Azure-Samples/art-voice-agent-accelerator.git
cd art-voice-agent-accelerator
4. Python Environment (Choose One)¶
Option A: venv¶
python -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
Option B: Conda¶
conda env create -f environment.yaml
conda activate audioagent
pip install -r requirements.txt # sync with lock
5. Root .env (Create in repo root)¶
Sample Configuration
Use .env.sample as a starting template and customize with your Azure resource values.
Using Azure Developer CLI (azd)
If you provisioned infrastructure using azd provision, an environment file will be automatically generated for you in the format .env.<azd-env-name>.
To use the azd-generated configuration:
# Copy the azd-generated environment file
cp .env.<your-azd-env-name> .env
# Example: if your azd environment is named "dev"
cp .env.dev .env
The azd-generated file contains all the Azure resource endpoints and configuration needed for local development.
Manual Configuration Template (edit placeholders; DO NOT commit real values):
# ===== Azure OpenAI =====
AZURE_OPENAI_ENDPOINT=https://<your-aoai>.openai.azure.com
AZURE_OPENAI_KEY=<aoai-key>
AZURE_OPENAI_DEPLOYMENT=gpt-4-1-mini
AZURE_OPENAI_API_VERSION=2024-12-01-preview
AZURE_OPENAI_CHAT_DEPLOYMENT_ID=gpt-4-1-mini
AZURE_OPENAI_CHAT_DEPLOYMENT_VERSION=2024-11-20
# ===== Speech =====
AZURE_SPEECH_REGION=<speech-region>
AZURE_SPEECH_KEY=<speech-key>
# ===== ACS (optional unless using phone/PSTN) =====
ACS_CONNECTION_STRING=endpoint=https://<your-acs>.communication.azure.com/;accesskey=<acs-key>
ACS_SOURCE_PHONE_NUMBER=+1XXXXXXXXXX
ACS_ENDPOINT=https://<your-acs>.communication.azure.com
# ===== Optional Data Stores =====
REDIS_HOST=<redis-host>
REDIS_PORT=6380
REDIS_PASSWORD=<redis-password>
AZURE_COSMOS_CONNECTION_STRING=<cosmos-conn-string>
AZURE_COSMOS_DATABASE_NAME=audioagentdb
AZURE_COSMOS_COLLECTION_NAME=audioagentcollection
# ===== Runtime =====
ENVIRONMENT=dev
ACS_STREAMING_MODE=media
# ===== Filled after dev tunnel starts =====
BASE_URL=https://<tunnel-url>
Ensure .env is in .gitignore.
6. Start Dev Tunnel¶
Required if you want ACS callbacks (phone flow) or remote test:
Copy the printed HTTPS URL and set BASE_URL in root .env. Update it again if the tunnel restarts (URL changes).
The Dev Tunnel URL will look similar to:
Security Considerations for Operations Teams
Dev Tunnels create public endpoints that expose your local development environment to the internet. Review the following security guidelines:
- Azure Dev Tunnels Security - Comprehensive security guidance
- Access Control: Use
--allow-anonymousonly for development; consider authentication for sensitive environments - Network Policies: Ensure dev tunnels comply with organizational network security policies
- Monitoring: Dev tunnels should be monitored and logged like any public endpoint
- Temporary Usage: Tunnels are for development only; use proper Azure services for production
- Credential Protection: Never expose production credentials through dev tunnels
InfoSec Recommendation: Review tunnel usage with your security team before use in corporate environments.
7. Run Backend¶
8. Frontend Environment¶
Create or edit apps/rtagent/frontend/.env:
Sample Configuration
Use apps/rtagent/frontend/.env.sample as a starting template.
Use the dev tunnel URL by default so the frontend (and any external device or ACS-related flows) reaches your backend consistently—even if you open the UI on another machine or need secure HTTPS.
# Recommended (works across devices / matches ACS callbacks)
VITE_BACKEND_BASE_URL=https://<tunnel-url>
If the tunnel restarts (URL changes), update both BASE_URL in the root .env and this value.
9. Run Frontend¶
Open: http://localhost:5173
WebSocket URL is auto-derived by replacing http/https with ws/wss.
10. Alternative: VS Code Debugging¶
Built-in debugger configurations are available in .vscode/launch.json:
Backend Debugging¶
- Set breakpoints in Python code
- Press F5 or go to Run & Debug view
- Select "[RT Agent] Python Debugger: FastAPI"
- Debug session starts with hot reload enabled
Frontend Debugging¶
- Start the React dev server (
npm run dev) - Press F5 or go to Run & Debug view
- Select "[RT Agent] React App: Browser Debug"
- Browser opens with debugger attached
Benefits: - Set breakpoints in both Python and TypeScript/React code - Step through code execution - Inspect variables and call stacks - Hot reload for both frontend and backend
11. Alternative: Docker Compose¶
For containerized local development, use the provided docker-compose.yml:
# Ensure .env files are configured (see sections 5 & 8 above)
# Build and run both frontend and backend containers
docker-compose up --build
# Or run in detached mode
docker-compose up --build -d
# View logs
docker-compose logs -f
# Stop containers
docker-compose down
Container Ports:
- Frontend: http://localhost:8080 (containerized)
- Backend: http://localhost:8010 (same as manual setup)
When to use Docker Compose:
- Consistent environment across team members
- Testing containerized deployment locally
- Isolating dependencies from host system
- Matching production container behavior
Dev Tunnel with Docker
You still need to run devtunnel host -p 8010 --allow-anonymous for ACS callbacks, as the containers need external access for webhook endpoints.
12. Optional: Phone (PSTN) Flow¶
-
Purchase ACS phone number (Portal or CLI).
-
Ensure these vars are set in your root
.env(with real values):
ACS_CONNECTION_STRING=endpoint=...
ACS_SOURCE_PHONE_NUMBER=+1XXXXXXXXXX
ACS_ENDPOINT=https://<your-acs>.communication.azure.com
BASE_URL=https://<tunnel-hash>-8010.usw3.devtunnels.ms
- Create a single Event Grid subscription for the Incoming Call event pointing to your answer handler:
- Inbound endpoint:
https://<tunnel-hash>-8010.usw3.devtunnels.ms/api/v1/calls/answer - Event type:
Microsoft.Communication.IncomingCall - (Callbacks endpoint
/api/v1/calls/callbacksis optional unless you need detailed lifecycle events.)
If tunnel URL changes, update the subscription (delete & recreate or update endpoint).
Reference: Subscribing to events
- Dial the number; observe:
- Call connection established
- Media session events
- STT transcripts
- TTS audio frames
13. Quick Browser Test¶
- Backend + frontend running.
- Open app, allow microphone.
- Speak → expect:
- Interim/final transcripts
- Model response
- Audio playback
14. Troubleshooting¶
| Symptom | Likely Cause | Fix |
|---|---|---|
| 404 on callbacks | Stale BASE_URL |
Restart tunnel, update .env |
| No audio | Speech key/region invalid | Verify Azure Speech resource |
| WS closes fast | Wrong VITE_BACKEND_BASE_URL |
Use exact backend/tunnel URL |
| Slow first reply | Cold pool warm-up | Keep process running |
| Phone call no events | ACS callback not updated to tunnel | Reconfigure Event Grid subscription |
| Import errors | Missing dependencies | Re-run pip install -r requirements.txt |
15. Testing Your Setup¶
Quick Unit Tests¶
Validate your local setup with the comprehensive test suite:
# Run core component tests
python -m pytest tests/test_acs_media_lifecycle.py -v
# Test event handling and WebSocket integration
python -m pytest tests/test_acs_events_handlers.py -v
# Validate DTMF processing (if using phone features)
python -m pytest tests/test_dtmf_validation.py -v
Load Testing (Advanced)¶
Test WebSocket performance with realistic conversation scenarios:
# Generate realistic audio for testing
make generate_audio
# Run WebSocket load test locally
locust -f tests/load/locustfile.py --web-host 127.0.0.1 --web-port 8089
What the load tests validate: - ✅ Real-time audio streaming - 20ms PCM chunks via WebSocket - ✅ Multi-turn conversations - Insurance inquiries and quick questions - ✅ Response timing - TTFB (Time-to-First-Byte) measurement - ✅ Barge-in handling - Response interruption simulation - ✅ Connection stability - Automatic WebSocket reconnection
Additional Resources
For more comprehensive guidance on development and operations:
- Troubleshooting Guide - Detailed problem resolution for common issues
- Testing Guide - Comprehensive unit and integration testing (85%+ coverage)
- Load Testing - WebSocket performance testing and Azure Load Testing integration
- Repository Structure - Understand the codebase layout
- Utilities & Services - Core infrastructure components
Keep secrets out of commits. Rotate anything that has leaked.