Skip to content

Commit 220b445

Browse files
authored
Improve demo (#855)
* Improve demo * Improvements on token set, improve readme and release note, add some error logging * Update document * Improve error handling and update azd parameter file, update docs * clear readme * Improve model parameter check and adding debug log * hardcode model config instead * Update to use parameters_json, we expect the model to do model specific filter * simplify the config.json.tpl for a non-breaking update
1 parent 49f8bd9 commit 220b445

27 files changed

+881
-251
lines changed

samples/ai/chat-demo.zip

-110 KB
Binary file not shown.

samples/ai/chat-demo/.azureignore

Lines changed: 0 additions & 11 deletions
This file was deleted.

samples/ai/chat-demo/.webappignore

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
## .webappignore controls what source files are excluded from App Service packaging.
2+
## Similar semantics to .gitignore; evaluated by Azure Developer CLI when creating the zip.
3+
4+
# Local environment secrets
5+
.env
6+
*.env
7+
.env.*
8+
9+
# Node modules (rebuilt in prepackage hook / Oryx build)
10+
client/node_modules
11+
node_modules
12+
13+
# Git metadata
14+
**/.git
15+
16+
# Python virtual environments & caches
17+
**/.venv
18+
**/__pycache__
19+
*.py[cod]
20+
*.log
21+
22+
# Frontend intermediate artifacts (final build copied into python_server/static)
23+
client/.vite
24+
client/dist
25+
26+
# DO NOT exclude python_server/static (serves built client)
27+
28+
# Editor / platform cruft
29+
.vscode
30+
.idea
31+
Thumbs.db
32+
.DS_Store
33+
34+
# Coverage / test artifacts (optional)
35+
coverage/
36+
htmlcov/
37+
38+
# Experimental local scripts
39+
scripts/local*/

samples/ai/chat-demo/README.md

Lines changed: 130 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,40 @@ Prereqs:
1818
* Node 18+
1919

2020
1. Create a PAT with **Models – Read**: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
21-
2. Install backend + frontend deps:
22-
```bash
23-
pip install -r requirements.txt
24-
# optional (tests, typing): pip install -r requirements-dev.txt
25-
```
26-
3. (Set token if you want AI answers)
27-
```bash
28-
export GITHUB_TOKEN=<your_pat> # bash/zsh
29-
# PowerShell
30-
$env:GITHUB_TOKEN="<your_pat>"
31-
```
32-
4. Start everything (serves React build automatically):
33-
```bash
34-
python start_dev.py
35-
```
36-
5. Open http://localhost:5173
21+
2. (Recommended) Create and activate a virtual environment:
22+
* macOS/Linux (bash/zsh):
23+
```bash
24+
python3 -m venv .venv
25+
source .venv/bin/activate
26+
python -m pip install --upgrade pip
27+
```
28+
* Windows (PowerShell):
29+
```pwsh
30+
python -m venv .venv
31+
.venv\Scripts\Activate.ps1
32+
python -m pip install --upgrade pip
33+
```
34+
Deactivate anytime with:
35+
```bash
36+
deactivate
37+
```
38+
3. Install backend + frontend deps (inside the venv):
39+
```bash
40+
pip install -r requirements.txt
41+
# optional (tests, typing): pip install -r requirements-dev.txt
42+
```
43+
4. (Set token if you want AI answers)
44+
```bash
45+
export GITHUB_TOKEN=<your_pat> # bash/zsh
46+
# PowerShell
47+
$env:GITHUB_TOKEN="<your_pat>"
48+
```
49+
Alternatively, you can update GITHUB_TOKEN in [./python_server/.env](./python_server/.env)
50+
5. Start everything (serves React build automatically):
51+
```bash
52+
python start_dev.py
53+
```
54+
6. Open http://localhost:5173
3755

3856
Running services:
3957
* HTTP API :5000
@@ -71,29 +89,64 @@ Frontend (Vitest + RTL):
7189
npm --prefix client test
7290
```
7391
Selected coverage areas (backend): config merge, room store limits, transport factory, room lifecycle, streaming send path.
74-
Coverage snapshot:
75-
* Runtime config validation & merging
76-
* In‑memory room store behavior / limits
77-
* Chat service builder (self vs webpubsub path & credential preconditions)
78-
* Room lifecycle (add/remove)
79-
* Streaming send path basic invariants
8092
81-
#### Frontend (Vitest + RTL)
82-
Location: `client/src/__tests__`
93+
## Deploy to Azure
94+
Install the Azure Developer CLI if you haven't: https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd
8395

84-
Run:
96+
```bash
97+
azd env new chatenv
98+
azd env set githubModelsToken ghp_your_token_here # store token for this env
99+
azd up
85100
```
86-
npm --prefix client test
101+
102+
Security note: `azd env set` persists the value in the environment state on disk; avoid committing the `.azure` folder.
103+
104+
That single `azd up` command:
105+
1. Provisions Azure Web PubSub + Storage + App Service (with Managed Identity)
106+
2. Builds the React client
107+
3. Deploys the Python backend
108+
4. Applies app settings sourced from previously persisted environment values (e.g. `githubModelsToken` set via `azd env set`)
109+
5. Prints your site URL + negotiate endpoint
110+
111+
### Enable AI Features (One-time Setup)
112+
**Recommended Default:** Pass the token via secure Bicep parameter at provision time (Option A). This avoids surprise hooks and keeps behavior explicit. For production, prefer Key Vault (Option D).
113+
114+
**Option A (Secure Bicep Parameter – default)**
115+
```bash
116+
azd env set githubModelsToken ghp_your_token_here
117+
azd up
87118
```
88-
Included tests:
89-
* Room switching: cached messages isolated & textarea present after switch
90-
* Sender fallback: history messages without `from` show `AI Assistant`
119+
Rotate: `azd env set githubModelsToken <new>` then `azd provision`.
120+
Remove: `azd env unset githubModelsToken` then `azd provision`.
91121

92-
Add more ideas:
93-
* Mid‑stream room switch preserves previous room’s partial content when returning
94-
* Simulated error banner rendering
95-
* Theme / avatar contexts snapshot
122+
**Option B (Manual CLI – update anytime)**
123+
```bash
124+
az webapp config appsettings set \
125+
--resource-group <your-resource-group> \
126+
--name <your-web-app-name> \
127+
--settings GITHUB_TOKEN="ghp_your_github_token_here"
128+
129+
az webapp restart \
130+
--resource-group <your-resource-group> \
131+
--name <your-web-app-name>
132+
```
133+
134+
**Option C (Portal)** Azure Portal → App Service → Configuration → Application settings → New application setting: Name=`GITHUB_TOKEN`, Value=`your-token`
96135

136+
**Option D (Key Vault Reference – production / rotation)**
137+
1. Store the PAT as a secret in a Key Vault you control.
138+
2. Grant the web app’s managed identity `get` permissions.
139+
3. Add an app setting: `[email protected](SecretUri=https://<vault>.vault.azure.net/secrets/<secret-name>/<version>)`
140+
4. Restart the web app.
141+
142+
### Next Changes
143+
```bash
144+
azd deploy # code only (frontend or backend)
145+
```
146+
Infra template changes:
147+
```bash
148+
azd provision && azd deploy
149+
```
97150

98151
## Core Environment Variables
99152
| Variable | Purpose |
@@ -113,7 +166,9 @@ Notes:
113166
## Custom Resource Names (Optional)
114167
Want predictable names? Provide overrides (must be globally unique where required):
115168
```bash
116-
azd provision --set webPubSubNameOverride=mywps1234 --set webAppNameOverride=mychatweb1234
169+
azd env set webPubSubNameOverride mywps1234
170+
azd env set webAppNameOverride mychatweb1234
171+
azd provision
117172
```
118173

119174
## Iteration Cheatsheet
@@ -151,6 +206,47 @@ More: **[ADVANCED.md](./docs/ADVANCED.md#2-local-development-paths)**
151206
- Customize AI logic in `python_server/chat_model_client.py`
152207
- Review how scalable history works now (Table storage) in the persistence section of the advanced doc.
153208

209+
## Debugging & Logs
210+
**Control runtime log level**
211+
- Set `LOG_LEVEL` to adjust all server logs (`DEBUG`, `INFO`, `WARNING`, `ERROR`). Defaults to `INFO`.
212+
- Optional: customize the format with `LOG_FORMAT` (defaults to `"%(asctime)s %(levelname)s %(name)s: %(message)s"`).
213+
214+
Example (PowerShell):
215+
```pwsh
216+
$env:LOG_LEVEL="DEBUG"
217+
python start_dev.py
218+
```
219+
- `DEBUG` enables verbose traces from Flask, OpenAI SDK, and httpx transport.
220+
221+
**Azure App Service**
222+
- Portal → App Service → Configuration → Application settings → add `LOG_LEVEL`, then restart.
223+
- Stream logs: `az webapp log tail --resource-group <rg> --name <app-name>`.
224+
225+
## Troubleshooting
226+
**App Service setting `GITHUB_TOKEN` missing after `azd up`**
227+
1. Make sure you set the value *before* the first `azd provision`: `azd env set githubModelsToken <token>`.
228+
3. If you added the token *after* the first deployment, run `azd provision` (you don't need `azd deploy` for an app setting change). Use `azd provision --no-state` if it claims no changes.
229+
230+
**Changed token but app setting didn’t update**
231+
- Confirm the parameter file or environment value is non-empty.
232+
- Run `azd env get githubModelsToken` to verify what azd stored.
233+
- Re-run `azd provision`. (Only a code change needs `azd deploy`.)
234+
235+
**Early `ECONNREFUSED` errors in the browser during local dev**
236+
- The React dev server starts first and immediately proxies `/api/*` to Flask while it’s still binding.
237+
- These transient errors vanish once `Flask app running` appears in the terminal. Safe to ignore.
238+
239+
**Web PubSub negotiate failing (401/403 or missing access)**
240+
- Ensure the web app’s Managed Identity has necessary roles (e.g. Web PubSub Service Owner / Contributor) on the Web PubSub resource.
241+
- If using the `createRoleAssignments` parameter and you turned it off after first provision, assign roles manually.
242+
243+
**`Unauthorized` error when calling openai**
244+
- Check if the GitHub PAT has **model read** permission
245+
246+
**General diagnostic tips**
247+
- Show current environment values: `azd env get`.
248+
- List effective app settings (Azure): `az webapp config appsettings list --name <app-name> --resource-group <rg>`.
249+
154250
---
155251
Happy hacking! Open an issue or PR in [our GitHub repo](https://github.com/Azure/azure-webpubsub) with feedback.
156252

samples/ai/chat-demo/RELEASE_NOTES.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,23 @@
22

33
Plain-language updates focused on what demo users can try. Non-customer internal details intentionally omitted.
44

5-
## [Unreleased]
6-
Nothing user-facing has changed yet.
5+
## [0.1.1] - 2025-10-30 (Preview)
6+
7+
### Added
8+
- `config.json` configuration file added to support different models with distinct parameters.
9+
10+
### Changed
11+
- Provide `githubModelsToken` parameter for `azd`
12+
- AI error visibility: early initialization surfaces missing/invalid token directly to users via broadcast message.
13+
- Logging improved around streaming start / completion / error states.
14+
15+
### Upgrade Guidance (0.1.0 → 0.1.1)
16+
1. If you want AI immediately, set the token before running `azd up`:
17+
`azd env set githubModelsToken <token>` then `azd up`.
18+
2. If you deployed without a token, enable AI later with:
19+
`azd env set githubModelsToken <token>` then `azd provision`.
20+
3. Rotate token: `azd env set githubModelsToken <new_token>` then `azd provision`.
21+
3. To change the token later, repeat provision with the new value.
722

823
## [0.1.0] - 2025-10-11 (Preview)
924
Initial preview release.

samples/ai/chat-demo/azure.yaml

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,16 @@ metadata:
44
infra:
55
provider: bicep
66
path: infra
7-
# To override the default web app name (<baseName>-web), set parameter:
8-
# parameters:
9-
# webAppNameOverride: your-custom-name
10-
# To override (or guarantee uniqueness for) the Web PubSub service name:
11-
# azd provision --set webPubSubNameOverride=myuniquewpsname123
127
services:
138
chatserver:
14-
# Use repo root as the project so `python_server` remains a package
15-
# and Oryx can load `wsgi:app` from the root wsgi.py
169
project: .
1710
language: python
1811
host: appservice
19-
# Frontend build hook (build React and copy static files) - ensure this exists in project root or scripts
2012
hooks:
2113
prepackage:
2214
windows:
2315
shell: pwsh
24-
run: |
25-
Push-Location .\client
26-
if (Test-Path node_modules) {
27-
Write-Host "Reusing existing node_modules"
28-
} else {
29-
Write-Host "Installing dependencies in client/"
30-
npm install
31-
}
32-
npm run build
33-
Pop-Location
34-
if (Test-Path .\python_server\static) { Remove-Item -Recurse -Force .\python_server\static }
35-
Copy-Item -Recurse .\client\dist .\python_server\static
16+
run: ./scripts/prepackage.ps1
3617
posix:
3718
shell: sh
38-
run: |
39-
(cd ./client && ([ -d node_modules ] || npm install) && npm run build)
40-
rm -rf ./python_server/static
41-
mkdir -p ./python_server
42-
cp -R ./client/dist ./python_server/static
19+
run: ./scripts/prepackage.sh

0 commit comments

Comments
 (0)