FastAPI is built on top of Starlette for the web parts and Pydantic for the data parts. It uses Python type hints to validate, serialize, and deserialize data. It also supports asynchronous programming, which is essential for handling multiple real - time connections.
WebSockets are a communication protocol that provides full - duplex communication channels over a single TCP connection. Unlike traditional HTTP requests, which are stateless and require a new connection for each request, WebSockets allow for continuous communication between the client and the server. This makes them perfect for real - time applications like chat.
Asynchronous programming in Python allows multiple tasks to be executed concurrently without blocking the main thread. In the context of a real - time chat application, asynchronous programming enables the server to handle multiple WebSocket connections simultaneously, ensuring that messages are sent and received in real - time.
First, create a virtual environment and install FastAPI and Uvicorn (a server for running FastAPI applications).
python -m venv chat_env
source chat_env/bin/activate
pip install fastapi uvicorn
Create a new Python file, for example, main.py
.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Welcome to the real - time chat application!"}
You can run the application using Uvicorn:
uvicorn main:app --reload
from fastapi import FastAPI, WebSocket
app = FastAPI()
connected_clients = []
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
connected_clients.append(websocket)
try:
while True:
data = await websocket.receive_text()
# Here we will add code to broadcast the message later
except Exception as e:
print(f"Error: {e}")
finally:
connected_clients.remove(websocket)
In this code, we first accept the WebSocket connection. Then we add the client to the list of connected clients. We use a while
loop to continuously receive messages from the client. If an error occurs, we print the error message, and finally, we remove the client from the list of connected clients.
from fastapi import FastAPI, WebSocket
app = FastAPI()
connected_clients = []
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
connected_clients.append(websocket)
try:
while True:
data = await websocket.receive_text()
for client in connected_clients:
if client != websocket:
await client.send_text(data)
except Exception as e:
print(f"Error: {e}")
finally:
connected_clients.remove(websocket)
In this updated code, when a message is received from a client, we iterate over all the connected clients and send the message to each client except the sender.
As shown in the previous code examples, proper error handling is crucial. When dealing with WebSocket connections, errors can occur due to network issues, client disconnections, etc. Catching and logging these errors helps in debugging and maintaining the application.
Before broadcasting messages, it’s a good practice to validate the incoming messages. You can use Pydantic models to define the structure of the messages and validate them on the server - side.
from pydantic import BaseModel
class ChatMessage(BaseModel):
sender: str
message: str
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
connected_clients.append(websocket)
try:
while True:
data = await websocket.receive_text()
try:
message = ChatMessage.parse_raw(data)
for client in connected_clients:
if client != websocket:
await client.send_text(data)
except ValueError:
print("Invalid message format")
except Exception as e:
print(f"Error: {e}")
finally:
connected_clients.remove(websocket)
Building a real - time chat application with FastAPI is a powerful and efficient way to provide real - time communication features. By leveraging FastAPI’s asynchronous capabilities and WebSockets, you can create a high - performance chat application that can handle multiple concurrent connections. Following common and best practices such as error handling, message validation, security, and scalability will ensure that your application is robust and reliable.