committed by
Sebastián Ramírez
12 changed files with 305 additions and 17 deletions
@ -0,0 +1,78 @@ |
|||
from fastapi import Cookie, Depends, FastAPI, Header |
|||
from starlette.responses import HTMLResponse |
|||
from starlette.status import WS_1008_POLICY_VIOLATION |
|||
from starlette.websockets import WebSocket |
|||
|
|||
app = FastAPI() |
|||
|
|||
html = """ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<title>Chat</title> |
|||
</head> |
|||
<body> |
|||
<h1>WebSocket Chat</h1> |
|||
<form action="" onsubmit="sendMessage(event)"> |
|||
<label>Item ID: <input type="text" id="itemId" autocomplete="off" value="foo"/></label> |
|||
<button onclick="connect(event)">Connect</button> |
|||
<br> |
|||
<label>Message: <input type="text" id="messageText" autocomplete="off"/></label> |
|||
<button>Send</button> |
|||
</form> |
|||
<ul id='messages'> |
|||
</ul> |
|||
<script> |
|||
var ws = null; |
|||
function connect(event) { |
|||
var input = document.getElementById("itemId") |
|||
ws = new WebSocket("ws://localhost:8000/items/" + input.value + "/ws"); |
|||
ws.onmessage = function(event) { |
|||
var messages = document.getElementById('messages') |
|||
var message = document.createElement('li') |
|||
var content = document.createTextNode(event.data) |
|||
message.appendChild(content) |
|||
messages.appendChild(message) |
|||
}; |
|||
} |
|||
function sendMessage(event) { |
|||
var input = document.getElementById("messageText") |
|||
ws.send(input.value) |
|||
input.value = '' |
|||
event.preventDefault() |
|||
} |
|||
</script> |
|||
</body> |
|||
</html> |
|||
""" |
|||
|
|||
|
|||
@app.get("/") |
|||
async def get(): |
|||
return HTMLResponse(html) |
|||
|
|||
|
|||
async def get_cookie_or_client( |
|||
websocket: WebSocket, session: str = Cookie(None), x_client: str = Header(None) |
|||
): |
|||
if session is None and x_client is None: |
|||
await websocket.close(code=WS_1008_POLICY_VIOLATION) |
|||
return session or x_client |
|||
|
|||
|
|||
@app.websocket("/items/{item_id}/ws") |
|||
async def websocket_endpoint( |
|||
websocket: WebSocket, |
|||
item_id: int, |
|||
q: str = None, |
|||
cookie_or_client: str = Depends(get_cookie_or_client), |
|||
): |
|||
await websocket.accept() |
|||
while True: |
|||
data = await websocket.receive_text() |
|||
await websocket.send_text( |
|||
f"Session Cookie or X-Client Header value is: {cookie_or_client}" |
|||
) |
|||
if q is not None: |
|||
await websocket.send_text(f"Query parameter q is: {q}") |
|||
await websocket.send_text(f"Message text was: {data}, for item ID: {item_id}") |
@ -0,0 +1,25 @@ |
|||
import pytest |
|||
from starlette.testclient import TestClient |
|||
from starlette.websockets import WebSocketDisconnect |
|||
from websockets.tutorial001 import app |
|||
|
|||
client = TestClient(app) |
|||
|
|||
|
|||
def test_main(): |
|||
response = client.get("/") |
|||
assert response.status_code == 200 |
|||
assert b"<!DOCTYPE html>" in response.content |
|||
|
|||
|
|||
def test_websocket(): |
|||
with pytest.raises(WebSocketDisconnect): |
|||
with client.websocket_connect("/ws") as websocket: |
|||
message = "Message one" |
|||
websocket.send_text(message) |
|||
data = websocket.receive_text() |
|||
assert data == f"Message text was: {message}" |
|||
message = "Message two" |
|||
websocket.send_text(message) |
|||
data = websocket.receive_text() |
|||
assert data == f"Message text was: {message}" |
@ -0,0 +1,83 @@ |
|||
import pytest |
|||
from starlette.testclient import TestClient |
|||
from starlette.websockets import WebSocketDisconnect |
|||
from websockets.tutorial002 import app |
|||
|
|||
client = TestClient(app) |
|||
|
|||
|
|||
def test_main(): |
|||
response = client.get("/") |
|||
assert response.status_code == 200 |
|||
assert b"<!DOCTYPE html>" in response.content |
|||
|
|||
|
|||
def test_websocket_with_cookie(): |
|||
with pytest.raises(WebSocketDisconnect): |
|||
with client.websocket_connect( |
|||
"/items/1/ws", cookies={"session": "fakesession"} |
|||
) as websocket: |
|||
message = "Message one" |
|||
websocket.send_text(message) |
|||
data = websocket.receive_text() |
|||
assert data == "Session Cookie or X-Client Header value is: fakesession" |
|||
data = websocket.receive_text() |
|||
assert data == f"Message text was: {message}, for item ID: 1" |
|||
message = "Message two" |
|||
websocket.send_text(message) |
|||
data = websocket.receive_text() |
|||
assert data == "Session Cookie or X-Client Header value is: fakesession" |
|||
data = websocket.receive_text() |
|||
assert data == f"Message text was: {message}, for item ID: 1" |
|||
|
|||
|
|||
def test_websocket_with_header(): |
|||
with pytest.raises(WebSocketDisconnect): |
|||
with client.websocket_connect( |
|||
"/items/2/ws", headers={"X-Client": "xmen"} |
|||
) as websocket: |
|||
message = "Message one" |
|||
websocket.send_text(message) |
|||
data = websocket.receive_text() |
|||
assert data == "Session Cookie or X-Client Header value is: xmen" |
|||
data = websocket.receive_text() |
|||
assert data == f"Message text was: {message}, for item ID: 2" |
|||
message = "Message two" |
|||
websocket.send_text(message) |
|||
data = websocket.receive_text() |
|||
assert data == "Session Cookie or X-Client Header value is: xmen" |
|||
data = websocket.receive_text() |
|||
assert data == f"Message text was: {message}, for item ID: 2" |
|||
|
|||
|
|||
def test_websocket_with_header_and_query(): |
|||
with pytest.raises(WebSocketDisconnect): |
|||
with client.websocket_connect( |
|||
"/items/2/ws?q=baz", headers={"X-Client": "xmen"} |
|||
) as websocket: |
|||
message = "Message one" |
|||
websocket.send_text(message) |
|||
data = websocket.receive_text() |
|||
assert data == "Session Cookie or X-Client Header value is: xmen" |
|||
data = websocket.receive_text() |
|||
assert data == "Query parameter q is: baz" |
|||
data = websocket.receive_text() |
|||
assert data == f"Message text was: {message}, for item ID: 2" |
|||
message = "Message two" |
|||
websocket.send_text(message) |
|||
data = websocket.receive_text() |
|||
assert data == "Session Cookie or X-Client Header value is: xmen" |
|||
data = websocket.receive_text() |
|||
assert data == "Query parameter q is: baz" |
|||
data = websocket.receive_text() |
|||
assert data == f"Message text was: {message}, for item ID: 2" |
|||
|
|||
|
|||
def test_websocket_no_credentials(): |
|||
with pytest.raises(WebSocketDisconnect): |
|||
client.websocket_connect("/items/2/ws") |
|||
|
|||
|
|||
def test_websocket_invalid_data(): |
|||
with pytest.raises(WebSocketDisconnect): |
|||
client.websocket_connect("/items/foo/ws", headers={"X-Client": "xmen"}) |
Loading…
Reference in new issue