]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
:sparkles: Add docs for WebSockets (#62)
authorSebastián Ramírez <tiangolo@gmail.com>
Sat, 2 Mar 2019 17:45:15 +0000 (21:45 +0400)
committerGitHub <noreply@github.com>
Sat, 2 Mar 2019 17:45:15 +0000 (21:45 +0400)
docs/img/tutorial/websockets/image01.png [new file with mode: 0644]
docs/img/tutorial/websockets/image02.png [new file with mode: 0644]
docs/img/tutorial/websockets/image03.png [new file with mode: 0644]
docs/img/tutorial/websockets/image04.png [new file with mode: 0644]
docs/src/websockets/tutorial001.py [new file with mode: 0644]
docs/tutorial/websockets.md [new file with mode: 0644]
mkdocs.yml

diff --git a/docs/img/tutorial/websockets/image01.png b/docs/img/tutorial/websockets/image01.png
new file mode 100644 (file)
index 0000000..c6de53b
Binary files /dev/null and b/docs/img/tutorial/websockets/image01.png differ
diff --git a/docs/img/tutorial/websockets/image02.png b/docs/img/tutorial/websockets/image02.png
new file mode 100644 (file)
index 0000000..84e2d6a
Binary files /dev/null and b/docs/img/tutorial/websockets/image02.png differ
diff --git a/docs/img/tutorial/websockets/image03.png b/docs/img/tutorial/websockets/image03.png
new file mode 100644 (file)
index 0000000..31b2110
Binary files /dev/null and b/docs/img/tutorial/websockets/image03.png differ
diff --git a/docs/img/tutorial/websockets/image04.png b/docs/img/tutorial/websockets/image04.png
new file mode 100644 (file)
index 0000000..7fed0b0
Binary files /dev/null and b/docs/img/tutorial/websockets/image04.png differ
diff --git a/docs/src/websockets/tutorial001.py b/docs/src/websockets/tutorial001.py
new file mode 100644 (file)
index 0000000..2713550
--- /dev/null
@@ -0,0 +1,53 @@
+from fastapi import FastAPI
+from starlette.responses import HTMLResponse
+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)">
+            <input type="text" id="messageText" autocomplete="off"/>
+            <button>Send</button>
+        </form>
+        <ul id='messages'>
+        </ul>
+        <script>
+            var ws = new WebSocket("ws://localhost:8000/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)
+
+
+@app.websocket_route("/ws")
+async def websocket_endpoint(websocket: WebSocket):
+    await websocket.accept()
+    while True:
+        data = await websocket.receive_text()
+        await websocket.send_text(f"Message text was: {data}")
+    await websocket.close()
diff --git a/docs/tutorial/websockets.md b/docs/tutorial/websockets.md
new file mode 100644 (file)
index 0000000..703f57a
--- /dev/null
@@ -0,0 +1,93 @@
+
+You can use <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" target="_blank">WebSockets</a> with **FastAPI**.
+
+## WebSockets client
+
+### In production
+
+In your production system, you probably have a frontend created with a modern framework like React, Vue.js or Angular.
+
+And to communicate using WebSockets with your backend you would probably use your frontend's utilities.
+
+Or you might have a native mobile application that communicates with your WebSocket backend directly, in native code.
+
+Or you might have any other way to communicate with the WebSocket endpoint.
+
+---
+
+But for this example, we'll use a very simple HTML document with some JavaScript, all inside a long string.
+
+This, of course, is not optimal and you wouldn't use it for production.
+
+In production you would have one of the options above.
+
+But it's the simplest way to focus on the server-side of WebSockets and have a working example:
+
+```Python hl_lines="2 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 42 43 44"
+{!./src/websockets/tutorial001.py!}
+```
+
+## Create a `websocket_route`
+
+In your **FastAPI** application, create a `websocket_route`:
+
+```Python hl_lines="3 47 48"
+{!./src/websockets/tutorial001.py!}
+```
+
+!!! tip
+    In this example we are importing `WebSocket` from `starlette.websockets` to use it in the type declaration in the WebSocket route function.
+
+    That is not required, but it's recommended as it will provide you completion and checks inside the function.
+
+
+!!! info
+    This `websocket_route` we are using comes directly from <a href="https://www.starlette.io/applications/" target="_blank">Starlette</a>. 
+    
+    That's why the naming convention is not the same as with other API path operations (`get`, `post`, etc).
+
+
+## Await for messages and send messages
+
+In your WebSocket route you can `await` for messages and send messages.
+
+```Python hl_lines="49 50 51 52 53"
+{!./src/websockets/tutorial001.py!}
+```
+
+You can receive and send binary, text, and JSON data.
+
+To learn more about the options, check Starlette's documentation for:
+
+* <a href="https://www.starlette.io/applications/" target="_blank">Applications (`websocket_route`)</a>.
+* <a href="https://www.starlette.io/websockets/" target="_blank">The `WebSocket` class</a>.
+* <a href="https://www.starlette.io/endpoints/#websocketendpoint" target="_blank">Class-based WebSocket handling</a>.
+
+
+## Test it
+
+If your file is named `main.py`, run your application with:
+
+```bash
+uvicorn main:app --debug
+```
+
+Open your browser at <a href="http://127.0.0.1:8000" target="_blank">http://127.0.0.1:8000</a>.
+
+You will see a simple page like:
+
+<img src="/img/tutorial/websockets/image01.png">
+
+You can type messages in the input box, and send them:
+
+<img src="/img/tutorial/websockets/image02.png">
+
+And your **FastAPI** application with WebSockets will respond back:
+
+<img src="/img/tutorial/websockets/image03.png">
+
+You can send (and receive) many messages:
+
+<img src="/img/tutorial/websockets/image04.png">
+
+And all of them will use the same WebSocket connection.
index 432a23051b37e8e0d8551c9209fc7a9b9edb500f..2760194af82f5e88c096d8489b8ec695b006a9ac 100644 (file)
@@ -62,6 +62,7 @@ nav:
         - Sub Applications - Behind a Proxy: 'tutorial/sub-applications-proxy.md'
         - Application Configuration: 'tutorial/application-configuration.md'
         - GraphQL: 'tutorial/graphql.md'
+        - WebSockets: 'tutorial/websockets.md'
         - Debugging: 'tutorial/debugging.md'
     - Concurrency and async / await: 'async.md'
     - Deployment: 'deployment.md'