Software Architectuur: FastAPI Backend¶
Inleiding & Scope¶
Projectbeschrijving¶
Het Signapse platform vertaalt gebarentaal naar tekst via een combinatie van computer vision, deep learning en een mobiele/webclient. De backend levert een uniforme FastAPI-laag die mediastreams van de client verwerkt, keypoints extraheert, AI-modellen aanroept en resultaten terugstuurt in realtime.
Scope van dit document¶
Dit document beschrijft de backendlaag die de frontends aanstuurt. Het behandelt de FastAPI-applicatie met zijn routers en lifecycle management in server/src/main.py, de integratie met het smart_gestures AI-package, de request/response-validatie via Pydantic schema's, alle REST en WebSocket endpoints inclusief hun doel en contracten, en de datastromen tussen client, keypoint-service en inferentie-modellen.
Voor details over de AI-modellen zelf, zie AI-Architecture.
Overzicht Architectuur¶
High-level backend-architectuur¶
De backend bestaat uit een gelaagde FastAPI-applicatie met vier duidelijke lagen. De transportlaag verzorgt REST en WebSocket endpoints, CORS-configuratie en versiebeheer. De routerlaag organiseert de functionaliteit in logische modules zoals root, keypoints, alphabet, gestures en ws, elk met eigen prefixes en tags. De service/AI-laag voert aanroepen uit naar smart_gestures voor ASL/VGT feed-forward modellen en LSTM-gebaseerde woordherkenning, samen met MediaPipe detectors voor keypoint-extractie. Tot slot dwingt de validatielaag via Pydantic schema's vorm en constraints af, zoals het aantal landmarks en sequentielengtes.
Alle zware objecten zoals MediaPipe detectors en PyTorch-modellen worden éénmalig geinitialiseerd bij import, zodat elk request enkel inference-berekeningen uitvoert.
Contextdiagram¶
---
config:
layout: elk
---
flowchart RL
subgraph Client["Client (Expo/React Native/Web)"]
CAM["CameraView & hooks<br>client/app/camera.tsx"]
APIClient["API helpers<br>client/lib/api.ts"]
end
subgraph Backend["FastAPI backend<br>server/src/main.py"]
ROOT["Root & Health<br>routes/root.py"]
KP["Keypoints router<br>/keypoints/*"]
ALPHA["Alphabet router<br>/alphabet/{asl|vgt}/*"]
GEST["Gestures router<br>/gestures/lstm/*"]
WS["WebSocket /ws"]
end
subgraph AI["AI & Feature laag"]
MP["MediaPipe Hands/Holistic<br>cv2 + mediapipe"]
ASL["smart_gestures.alphabet.ASLModel"]
VGT["smart_gestures.alphabet.VGTModel"]
LSTM["smart_gestures.gestures.LSTMModel"]
end
CAM -- Frames --> APIClient
APIClient -- Images --> KP
KP -- 21/258 keypoints --> APIClient
APIClient -- Landmarks JSON --> ALPHA
APIClient -- Sequences (40x258) --> GEST
ALPHA -- REST response --> APIClient
GEST -- REST response --> APIClient
WS -- Realtime feedback --> APIClient
KP --> MP
ALPHA --> ASL & VGT
GEST --> LSTM
APIClient --> n1["Untitled Node"]
Kerncomponenten¶
FastAPI-applicatie & runtime¶
- Entry point:
server/src/main.py - Stelt logging/waarschuwingen in en dwingt CPU-mode af voor MediaPipe/TensorFlow.
- Initialiseert
FastAPImet titel, beschrijving en__version__(gelezen uitpyproject.tomlviaconst.py). - Registreert CORS (
allow_origins=["*"]) zodat web en mobiele clients kunnen verbinden tijdens development. - Includeert routers (
root,ws,alphabet,gestures,keypoints). - Deployment:
server/Dockerfilebouwt een Python 3.12 container, installeertsmart-gesturesals lokaal package en start viafastapi run src/main.py --host 0.0.0.0 --port 8000. - Runtime dependencies (uit
server/pyproject.toml): fastapi[standard],uvicorn,pydanticsmart-gestures==0.3.3(bundelt getrainde modellen)- Tools voor linting/typing (black, isort, mypy, flake8) voor kwaliteitsborging
Routerlagen¶
| Router | Prefix | Belangrijkste verantwoordelijkheden | Files |
|---|---|---|---|
root |
/ |
Health-check, versie-informatie, redirects | routes/root.py |
keypoints |
/keypoints |
MediaPipe integratie voor hands & pose, beeldvalidatie | routes/keypoints/__init__.py |
alphabet |
/alphabet |
ASL/VGT klassen & predictions | routes/alphabet/asl_model, vgt_model |
gestures |
/gestures |
LSTM woordherkenning (klassen + predict) | routes/gestures/lstm_model |
ws |
/ws |
Stateful WebSocket kanaal voor realtime feedback | routes/ws/connection.py, websocket/connection_manager.py |
Validatie & schema's¶
- Alle requests/responses gebruiken Pydantic schema's (
server/src/schemas). PredictBodydwingt exact 21HandLandmarkentries af (NUM_POINTS).LSTMPredictBodyvalideert 40 frames metfield_validatoren zet data om naar eennumpy-array (to_numpy_sequence()).HandKeypointsResponse,PoseLandmarkenLSTMFramestandaardiseren MediaPipe output zodat frontend en backend dezelfde structuur delen.StatusResponse,ClassesResponseenLSTMClassesResponsedocumenteren metadata voor automatische OpenAPI docs.
AI-integratie (smart_gestures)¶
- De
smart_gesturespackage wordt via een lokale path dependency geladen ([tool.uv.sources]). - Modellen (
ASLModel,VGTModel,LSTMModel) laden.pthbestanden bij import en bieden een.predict(...)API die(naam, confidence)teruggeeft. - De routers converteren Pydantic objecten naar Python lijsten/dicts vóór inferentie.
- Normalisatie (translatie, scaling) en tensor-conversies zitten in het package zodat de backend puur orchestration doet.
WebSocket infrastructuur¶
routes/ws/connection.pyexposeert/wsen gebruiktConnectionManager.ConnectionManagerhoudtactive_connections: dict[str, WebSocket]bij, accepteert clients, broadcast berichten en verwijdert clients bij disconnect.- Dit kanaal is voorlopig bedoeld voor notificaties/experimentele realtime feedback maar de infrastructuur is klaar voor streaming predictions.
Foutafhandeling & observability¶
Inputfouten worden vertaald naar gepaste HTTPException responses: een 400 statuscode bij lege bestanden of verkeerde landmark-aantallen, 404 als er geen hand of pose gevonden wordt, en 500 bij onverwachte predictieproblemen in het LSTM-model. Alle responses zijn JSON-geformatteerd en volledig beschreven in de OpenAPI-specificatie die beschikbaar is via /docs en /redoc. Om de logs overzichtelijk te houden voor backend events, is de logging van absl, tensorflow en mediapipe onderdrukt in main.py.
Endpointcatalogus¶
Root & status¶
| Endpoint | Methode | Doel | Request | Response |
|---|---|---|---|---|
/ |
GET | Redirect naar /health als startpunt voor monitoring. |
- | 307 Redirect |
/health |
GET | Geeft API-versie terug (monitorable via load balancers). | - | { "version": "0.3.2" } (StatusResponse) |
Keypoints (MediaPipe)¶
| Endpoint | Methode | Doel | Request | Response |
|---|---|---|---|---|
/keypoints/ |
POST | Backwards compat. endpoint dat direct redirect naar /keypoints/hands. |
multipart/form-data met image |
307 Redirect |
/keypoints/hands |
POST | Extraheert 21 hand-landmarks via MediaPipe Hands. | multipart/form-data, single frame (JPEG/PNG). Validatie op lege bestanden. |
HandKeypointsResponse (21 × {x,y,z}) |
/keypoints/pose |
POST | Bouwt één LSTMFrame (pose + beide handen) voor sequential models. |
multipart/form-data met frame. |
LSTMFrame (33 pose + 2×21 hand landmarks). |
Technische highlights:
prepare_image()decodeert bytes →numpy→ RGB.- Persistente MediaPipe detectors vermijden init-overhead per request.
Alphabet (ASL/VGT)¶
| Endpoint | Methode | Doel | Request | Response |
|---|---|---|---|---|
/alphabet/asl/classes |
GET | Geeft lijst van 35 ASL-klassen uit het model JSON. | - | ClassesResponse (["a","b",...]) |
/alphabet/asl/predict |
POST | Voorspelt ASL-letter/cijfer op basis van 21 landmarks. | PredictBody (landmarks: list[HandLandmark]) |
PredictResponse (prediction, confidence) |
/alphabet/vgt/classes |
GET | Geeft lijst van VGT-klassen. | - | ClassesResponse |
/alphabet/vgt/predict |
POST | Voorspelt VGT-letter (wrist-to-middle normalisatie in model). | PredictBody |
PredictResponse |
Binnenkomende landmarks worden geconverteerd naar dicts met .model_dump() en vervolgens aan het betreffende model doorgegeven. Exceptions worden vertaald naar 400 Bad Request.
Gestures (LSTM woordherkenning)¶
| Endpoint | Methode | Doel | Request | Response |
|---|---|---|---|---|
/gestures/lstm/classes |
GET | Geeft mapping van gebaren → class-id (voor UI dropdowns). | - | LSTMClassesResponse ({ "hallo": 3, ... }) |
/gestures/lstm/predict |
POST | Voorspelt woorden uit sequenties van 40 frames. | LSTMPredictBody (frames: list[LSTMFrame]) |
LSTMPredictResponse (prediction, confidence) |
LSTMPredictBody.to_numpy_sequence() zet de frames om naar numpy (40, 258) voordat model.predict() wordt aangeroepen. Inputvalidatie onderscheidt tussen ValueError (400) en andere fouten (500).
WebSocket¶
| Endpoint | Type | Doel | Payload | Gedrag |
|---|---|---|---|---|
/ws |
WebSocket | Bi-directionele kanaal voor realtime feedback of multi-user sessies. | Vrij tekstprotocol (nu broadcast). | Iedere binnenkomende message wordt naar alle clients gestuurd; connect/disconnect events worden automatisch gebroadcast. |
Gebruik ConnectionManager om toekomstige features zoals push-notificaties voor predictions te implementeren.
Datastromen & Sequenties¶
Alfabet-herkenning (ASL/VGT)¶
- Frame capture in
client/app/camera.tsx. - Upload frame →
POST /keypoints/hands; backend decodeert bytes, draait MediaPipe Hands en retourneert 21 landmarks. - Client valideert response en bouwt
PredictBody. - Client → /alphabet/{asl|vgt}/predict met landmarks.
- Router converteert landmarks naar lijst dicts, roept
ASLModelofVGTModelaan: - Normalisatie & tensorconversie gebeurt in
smart_gestures. - Softmax → confidence, mapping naar klasse.
- Response (
prediction,confidence) wordt in UI getoond en eventueel gebruikt om woorden op te bouwen.
Woord-herkenning (LSTM)¶
- Sequencing: client verzamelt 40 opeenvolgende frames en extraheert per frame pose + hand-landmarks (kan bouwstenen hergebruiken van
/keypoints/pose). - Request naar
/gestures/lstm/predictmetframes. - Validatie:
LSTMPredictBodycheckt lengte en structuren en zet om naar(40,258)numpy-array. - Inferentie:
LSTMModel.predict()draait normalisatie, voert forward pass, berekent confidence. - Response bevat
prediction+confidence. Frontend toont woord + probabiliteit of annuleert als drempel niet gehaald wordt.
WebSocket feedback¶
- Client opent
ws://<host>/wsen ontvangt bevestiging. - Elke message (bv. "prediction: hallo") wordt gebroadcast naar alle aangesloten clients.
- Disconnects worden opgeschoond door
ConnectionManager. - Dankzij deze infrastructuur kan de backend later streaming predictions pushen zonder extra endpoints.
Client-integratie & Deployability¶
De client-code is georganiseerd rond een API-helper in client/lib/api.ts die fetch wrappers, JSON parsing en error handling verzorgt. De camera workflow in client/app/camera.tsx en bijbehorende hooks bouwen de volledige pipeline op zoals beschreven in de vorige secties. De UI-logica combineert alphabet predictions tot volledige woorden of triggert LSTM-requests voor woordherkenning.
Voor CORS en security zijn tijdens development alle origins toegestaan, hoewel de productieconfiguratie allow_origins kan beperken tot vertrouwde domeinen en apps. File uploads verlopen via HTTPS om fotogegevens te beschermen. Het versiebeheer en observability wordt ondersteund door het /health endpoint dat __version__ exposeert, zodat monitoring kan verifiëren of de juiste release draait. De fastapi[standard] dependency levert automatisch een Swagger UI op /docs en ReDoc op /redoc, wat bruikbaar is voor QA-teams en integrators.
De containerisatie vereist specifieke systeemlibraries zoals libgl1 en libglib2.0-0 voor dependencies als cv2 en MediaPipe, die vastgelegd zijn in de Dockerfile. Omgevingsvariabelen zoals MPLCONFIGDIR en TMPDIR worden ingesteld zodat MediaPipe en matplotlib kunnen schrijven in sandbox directories.
Document-informatie:
- Versie: 1.1
- Datum: December 2025
- Auteurs: Lynn Delaere
- Contact: Zie GitHub repository