Skip to content

Commit fdcea89

Browse files
authored
[websockets/fastapi-ai-chat] switch to use latest services (#1512)
### Description Updates to use the latest `services` schema, as well as README fixes. Depends on vercel/vercel#16757 ### Demo URL <!-- Provide a URL to a live deployment where we can test your PR. If a demo isn't possible feel free to omit this section. --> ### Type of Change - [ ] New Example - [x] Example updates (Bug fixes, new features, etc.) - [ ] Other (changes to the codebase, but not to examples) ### New Example Checklist - [ ] 🛫 `npm run new-example` was used to create the example - [ ] 📚 The template wasn't used but I carefuly read the [Adding a new example](https://github.com/vercel/examples#adding-a-new-example) steps and implemented them in the example - [ ] 📱 Is it responsive? Are mobile and tablets considered?
1 parent 4b9f81d commit fdcea89

4 files changed

Lines changed: 31 additions & 18 deletions

File tree

websockets/fastapi-ai-chat/README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
# FastAPI AI Chat with WebSocket
22

3-
A real-time AI chat application using **Next.js** (frontend), **FastAPI** (backend), **WebSocket** for streaming, and the [Python AI SDK](https://github.com/vercel-labs/ai-python) for LLM integration. Deployed on Vercel using [experimental services](https://vercel.com/docs/functions/experimental-services).
3+
A real-time AI chat application using **Next.js** (frontend), **FastAPI** (backend), **WebSocket** for streaming, and the [Python AI SDK](https://github.com/vercel-labs/ai-python) for LLM integration. Deployed on Vercel using [Services](https://vercel.com/docs/services).
44

55
## How It Works
66

77
- The **frontend** is a Next.js single-page app with a chat UI that connects to the backend via WebSocket.
88
- The **backend** is a FastAPI server that accepts WebSocket connections, streams LLM responses using the Python AI SDK, and sends text deltas back to the client in real time.
9-
- On Vercel, the frontend and backend run as separate services routed by path prefix (`/` and `/svc/api`).
10-
- Python ASGI apps handle WebSocket upgrades natively on Vercel — no `experimental_upgradeWebSocket` workaround needed.
9+
- On Vercel, the frontend and backend run as separate services routed by path prefix (`/` and `/api`).
1110

1211
## How to Use
1312

websockets/fastapi-ai-chat/backend/main.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import os
22

3-
import fastapi
4-
5-
import ai
3+
import ai, fastapi
64

75
app = fastapi.FastAPI()
86

@@ -15,13 +13,15 @@
1513
"system": ai.system_message,
1614
}
1715

16+
api = fastapi.APIRouter(prefix="/api")
17+
1818

19-
@app.get("/")
19+
@api.get("/")
2020
async def health():
2121
return {"status": "ok"}
2222

2323

24-
@app.websocket("/ws")
24+
@api.websocket("/ws")
2525
async def websocket_endpoint(websocket: fastapi.WebSocket):
2626
await websocket.accept()
2727
try:
@@ -47,3 +47,5 @@ async def websocket_endpoint(websocket: fastapi.WebSocket):
4747
)
4848
except fastapi.WebSocketDisconnect:
4949
pass
50+
51+
app.include_router(api)

websockets/fastapi-ai-chat/frontend/app/page.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
import { useState, useEffect, useRef } from "react";
44

5-
const BACKEND = process.env.NEXT_PUBLIC_BACKEND_URL || "/svc/api";
6-
75
export default function Chat() {
86
const [messages, setMessages] = useState([]);
97
const [input, setInput] = useState("");
@@ -25,7 +23,7 @@ export default function Chat() {
2523
if (cancelled) return;
2624

2725
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
28-
const wsUrl = `${protocol}//${window.location.host}${BACKEND}/ws`;
26+
const wsUrl = `${protocol}//${window.location.host}/api/ws`;
2927

3028
setStatus("connecting");
3129
const ws = new WebSocket(wsUrl);
Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
11
{
2-
"experimentalServices": {
2+
"rewrites": [
3+
{
4+
"source": "/api/:path*",
5+
"destination": {
6+
"type": "service",
7+
"service": "backend"
8+
}
9+
},
10+
{
11+
"source": "/(.*)",
12+
"destination": {
13+
"type": "service",
14+
"service": "frontend"
15+
}
16+
}
17+
],
18+
"services": {
319
"frontend": {
4-
"framework": "nextjs",
5-
"entrypoint": "frontend",
6-
"routePrefix": "/"
20+
"root": "frontend",
21+
"framework": "nextjs"
722
},
823
"backend": {
9-
"framework": "fastapi",
10-
"entrypoint": "backend/main.py",
11-
"routePrefix": "/svc/api"
24+
"root": "backend",
25+
"framework": "fastapi"
1226
}
1327
}
1428
}

0 commit comments

Comments
 (0)