Skip to content

Revue de code - Youssef Hamzaoui #3

@Youssef75ensae

Description

@Youssef75ensae

Revue de code — FastCrowdVision

Bonjour à toutes et à tous,

Voici ma revue de code sur votre projet. Bravo pour le travail accompli — détecter des personnes en temps réel sur vidéo avec une architecture entraînée from scratch, c'est un beau défi que vous avez relevé avec soin. Les remarques qui suivent portent sur quelques détails de bonnes pratiques vus en cours, le fond est vraiment solide.


Points forts

Structure du projet

La séparation entre model/, serving/, training/, tests/ et website/ est claire
et cohérente. Chaque module a une responsabilité bien définie, ce qui correspond à la
structure modulaire recommandée dans le cours (App 4–6).

Docker

Le multi-stage build est bien pensé. La séparation des dépendances entre
requirements.txt (entraînement + dev) et requirements-api.txt (API uniquement)
permet de garder l'image de production légère. Le .dockerignore est également présent,
ce qui est souvent omis.

CI/CD

Le workflow docker-deploy.yml utilise docker/metadata-action pour gérer le tagging
des images automatiquement — nom de branche pour les branches de développement, latest
réservé à main. Cette approche évite les tags codés en dur et s'aligne avec les
recommandations du cours (App 14–15).

GitOps avec ArgoCD

argocd/application.yaml est présent et configuré avec auto-sync, prune et self-heal.
Le README est transparent sur la limitation du SSPCloud concernant l'accès restreint au
namespace argocd, ce qui est appréciable.

Kubernetes

Les quatre manifests sont présents (deployment, service, ingress, pvc), ce qui
correspond au déploiement complet couvert en App 18.

Tests

La suite de tests couvre les forward passes SSD sur les quatre backbones ainsi que le
Hard Negative Mining. Le recours à des fonctions utilitaires évite la répétition et
l'ensemble est bien structuré.

inference.py et server.py

La séparation entre le chargement du modèle et la détection frame par frame est propre.
La boucle WebSocket dans server.py gère correctement les cas limites : nettoyage des
fichiers temporaires, gestion des erreurs dans le bloc finally, et asyncio.sleep(0)
pour ne pas bloquer l'event loop.

Versionnement du modèle

Stocker les poids du modèle sur HuggingFace plutôt que dans le dépôt est une bonne
pratique. La logique de chargement dans inference.py via hf_hub_download avec mise
en cache locale est propre.


Pistes d'amélioration

1. Absence d'un pipeline de tests automatisé

pytest est mentionné dans le README mais il n'existe pas de workflow GitHub Actions
qui exécute la suite de tests automatiquement à chaque push ou pull request. C'est l'une
des recommandations explicites du cours (App 14). Un changement introduisant une
régression pourrait donc passer inaperçu jusqu'à ce que quelqu'un lance les tests
manuellement. Ajouter un workflow tests.yml permettrait de combler cette lacune :

name: Run tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install dependencies
        run: pip install -r requirements/requirements-api.txt pytest
      - name: Run tests
        run: pytest tests/ -v

2. Absence de pre-commit hooks

ruff est configuré dans pyproject.toml mais il n'existe pas de .pre-commit-config.yaml,
ce qui signifie que le linting n'est pas appliqué avant chaque commit. Le cours aborde
ce point en App 2. Ajouter un hook pre-commit avec ruff permettrait de l'exécuter
systématiquement plutôt que de le laisser disponible sans être déclenché :

repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.4.0
    hooks:
      - id: ruff
      - id: ruff-format

3. Gestion des dépendances

Le cours recommande uv comme gestionnaire de dépendances (App 3), notamment pour les
garanties de reproductibilité offertes par uv.lock. La configuration actuelle repose
sur pip + venv, ce qui fonctionne mais n'offre pas le même niveau de reproductibilité.
On notera que uv.lock est mentionné — et commenté — dans le .gitignore, ce qui
suggère que uv avait été envisagé. La migration serait relativement simple puisque
pyproject.toml est déjà en place.

4. main.ipynb à la racine

Le notebook main.ipynb se trouve à la racine du dépôt. La structure cookiecutter
recommandée dans le cours (App 4) place les notebooks dans un dossier notebooks/
dédié, afin de garder la racine lisible et de séparer clairement le travail exploratoire
du code de production.


Bonne continuation à tous !

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions