-
First Check
Commit to Help
Example Codefrom collections import deque
from typing import Any, Dict, Set
from fastapi import APIRouter, WebSocket, WebSocketDisconnect, FastAPI
from starlette.middleware.cors import CORSMiddleware
class EngineServer:
"""WebSocket server for the engine"""
clients: Set[WebSocket] = set()
_responses: deque = deque(maxlen=1000)
port: int = 8080
host: str = "0.0.0.0"
@classmethod
async def init(
cls, host: str | None = None, port: int | None = None
) -> "EngineServer":
if host: cls.host = host
if port: cls.port = port
return cls
@classmethod
async def connect(cls, websocket: WebSocket):
await websocket.accept()
cls.clients.add(websocket)
@classmethod
def disconnect(cls, websocket: WebSocket):
cls.clients.remove(websocket)
@classmethod
async def send(cls, message: dict, websocket: WebSocket):
await websocket.send_json(message)
@classmethod
async def _receive(cls, websocket: WebSocket) -> dict[str, Any]:
response = await websocket.receive_json()
cls._responses.append(response)
return response
router = APIRouter(
prefix="",
tags=["engine"],
)
@router.websocket("/query/ws", name="query-websocket")
async def websocket_endpoint(websocket: WebSocket):
"""Query websocket route"""
engine_client = await EngineServer.init()
await engine_client.connect(websocket)
try:
while True:
data = await engine_client._receive(websocket)
print(data)
await engine_client.send(data, websocket)
except WebSocketDisconnect:
engine_client.disconnect(websocket)
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=settings.ALLOWED_HOSTS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(router)Description
Request URL: http://0.0.0.0:8000/engine/query/ws/
Request Method: GET
Status Code: 403 Forbidden
-----------------
Request Headers
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: zFafMFebNPPOXUEFv9KZZw==
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Host: 0.0.0.0:8000
-----------------
Response Headers
Server: nginx/1.23.4
Date: Sat, 13 May 2023 11:00:42 GMT
Content-Type: text/plain
Content-Length: 0
Connection: keep-aliveOperating SystemmacOS Operating System DetailsNo response FastAPI Version0.95.1 Python VersionPython 3.11.3 Additional ContextThis application is running inside docker as part of a compose stack. Additionally, I am using nginx as a reverse proxy. Following is my nginx upstream engine_server {
server engine:4200;
}
# now we declare our main server
server {
listen 80;
server_name localhost;
client_max_body_size 10M;
location /engine/query/ws/ {
proxy_pass http://engine_server/engine/query/ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_redirect off;
}
location /engine/ {
proxy_pass http://engine_server/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
|
I meet the same issue, FastAPI Websocket in docker。 meet 403 issue. |
Beta Was this translation helpful? Give feedback.
-
|
i have same issue, fastapi runs on vps locally behind nginx also i tried to run example that i found in official docs(online chat) and got this: |
Beta Was this translation helpful? Give feedback.
-
|
Hey, for me it was url trailing slash issue. websocket: URL INSIDE: |
Beta Was this translation helpful? Give feedback.



Hey, for me it was url trailing slash issue.
So config looks like this:
NGINX:
websocket: