Ce qu'un développeur Python FastAPI doit savoir sur l'async et Pydantic

FastAPI se prend en main en une journée, et les CV finissent par tous se ressembler. L'entretien porte sur ce qui casse en production, comme un appel bloquant dans une route async ou une session SQLAlchemy partagée entre deux requêtes.

Recevoir la fiche complète

Mis à jour le Par l'équipe Delectus5 min de lecture

La fiche Développeur Python FastAPI : technologies, chaîne du poste, une question et la grille d'évaluation

Le développeur Python FastAPI construit des API HTTP typées. Il déclare les schémas d'entrée et de sortie avec Pydantic, branche une base PostgreSQL avec SQLAlchemy 2 et Alembic, et sert l'application avec Uvicorn, souvent dans Kubernetes. Les offres l'associent à Angular ou React pour le front, à Celery ou Kafka pour les traitements différés, et de plus en plus à des services qui appellent des LLM, où les timeouts et le streaming comptent.

Le risque vient de la facilité du framework. Le tutoriel officiel suffit pour livrer une API qui répond, et beaucoup de profils s'arrêtent là. L'écart se voit sur le modèle d'exécution. Une route en async def qui appelle requests ou un pilote synchrone bloque tout le worker, alors qu'une route en def part dans un pool de threads. Un candidat qui a tenu une API sous charge sait l'expliquer, et sait pourquoi une AsyncSession ne se partage pas entre deux tâches.

Demandez un incident vécu : une latence qui grimpe, un pool de connexions épuisé, une migration Alembic qui a verrouillé une table. FastAPI publie souvent des versions avec des changements cassants, et la 0.128 a retiré le support de pydantic.v1. Vérifiez comment la personne suit ces montées de version. Le PDF contient 30 questions et un cas de 20 minutes sur une API de réservation.

La stack d'une API FastAPI en production

FastAPI et Starlette

FastAPI repose sur Starlette, qui gère le routage, les middlewares et les WebSockets. FastAPI ajoute la validation par les types, l'injection de dépendances et la documentation OpenAPI générée. Le projet reste en version 0.x et publie régulièrement des changements cassants. Demandez quelle version le candidat a utilisée et s'il a déjà mené une montée de version.

Pydantic v2

La bibliothèque de validation. Chaque corps de requête et chaque réponse passe par un modèle Pydantic. La version 2, dont le moteur est écrit en Rust, a renommé une partie de l'API (model_validate, model_dump, field_validator, ConfigDict). Un candidat qui écrit encore .dict() et @validator a surtout pratiqué la version 1.

asyncio et Uvicorn

Uvicorn est le serveur ASGI qui exécute l'application. Il fait tourner une boucle d'événements asyncio par processus, et on lance plusieurs workers ou réplicas pour utiliser plusieurs cœurs. Un appel bloquant dans une fonction async def gèle cette boucle, et toutes les requêtes en cours avec elle.

SQLAlchemy 2 et Alembic

L'ORM le plus fréquent avec FastAPI, en mode synchrone ou asynchrone (AsyncSession avec asyncpg). Alembic gère les migrations de schéma. Les questions utiles portent sur la durée de vie d'une session, le chargement des relations sans requêtes N+1 et les migrations sur une grosse table. SQLModel, qui combine SQLAlchemy et Pydantic, apparaît aussi dans les offres.

Injection de dépendances (Depends)

Le mécanisme qui fournit à chaque route sa session de base, l'utilisateur authentifié ou un client HTTP. Une dépendance avec yield ouvre une ressource et la referme après la réponse. Dans les tests, app.dependency_overrides remplace ces dépendances par des versions factices.

OAuth2, JWT et sécurité

FastAPI fournit des briques OAuth2 et la lecture des jetons, sans gérer les utilisateurs à votre place. Le poste demande de valider un JWT (signature, expiration, audience), de contrôler les droits route par route et de régler CORS. Les jetons viennent souvent d'un fournisseur d'identité comme Keycloak ou Entra ID.

pytest, httpx et pytest-asyncio

Les tests passent par TestClient, ou par httpx.AsyncClient avec pytest-asyncio quand les tests sont eux-mêmes asynchrones. Une suite fiable démarre un vrai PostgreSQL en conteneur, isole chaque test dans une transaction et remplace les services externes.

Celery et tâches de fond

BackgroundTasks lance un traitement court après la réponse, dans le même processus. Un traitement long, ou qui doit survivre à un redémarrage, demande une file : Celery avec Redis ou RabbitMQ, ARQ, Dramatiq ou Kafka. Le candidat doit savoir placer la frontière entre les deux.

Docker, Kubernetes et observabilité

L'API tourne en conteneur, avec des sondes de santé, plusieurs réplicas et un arrêt propre à chaque déploiement. Les traces OpenTelemetry et les métriques Prometheus montrent quelle route ralentit et à quelle étape.

Le poste porte plusieurs intitulés : développeur Python back-end, ingénieur Python, développeur FastAPI. Les offres demandent souvent FastAPI à côté de Flask ou de Django, et certaines missions consistent à migrer une API Flask vers FastAPI. Une partie des annonces récentes concerne des services d'IA générative, où FastAPI expose un modèle ou orchestre des appels à des LLM. Le socle Python ne change pas : typage, tests, SQL, packaging avec uv ou Poetry. FastAPI n'a pas de certification officielle, l'expérience se vérifie donc en entretien.

Les compétences FastAPI à contrôler

  • Modèle d'exécution async et sync de FastAPI
  • Validation et sérialisation avec Pydantic v2
  • Accès aux données avec SQLAlchemy 2 et Alembic
  • Authentification et contrôle d'accès d'une API
  • Tests d'API et injection de dépendances
  • Déploiement, performance et observabilité

Cinq questions sur l'async, les sessions et la validation

Chaque question vient avec ce qu'une bonne réponse contient et le signal qui doit vous alerter. Pas besoin d'être technique pour les poser : écoutez si le candidat raconte du vécu.

  1. Question 1 · confirmé

    Une route async def appelle une API externe avec requests. Sous charge, toutes les routes ralentissent, même /health. Que se passe-t-il ?

    Une bonne réponserequests est synchrone, donc l'appel bloque la boucle d'événements du worker. Aucune autre requête n'avance pendant ce temps, /health comprise. Plusieurs corrections selon le contexte : un client async (httpx.AsyncClient créé au démarrage et partagé), une route déclarée en def pour qu'elle parte dans le pool de threads, ou l'appel enveloppé dans run_in_threadpool ou asyncio.to_thread. Il ajoute un timeout explicite sur l'appel externe.

    Signal d'alerte« Il faut plus de workers Uvicorn » sans voir l'appel bloquant, ou « async rend le code plus rapide » en général.

  2. Question 2 · confirmé

    Comment fournissez-vous une session SQLAlchemy asynchrone à vos routes, et pourquoi pas une session globale ?

    Une bonne réponseUn async_sessionmaker créé au démarrage avec expire_on_commit=False, et une dépendance avec yield qui ouvre une AsyncSession par requête, la referme après la réponse et annule la transaction en cas d'erreur. La documentation SQLAlchemy précise qu'une AsyncSession ne doit pas servir à plusieurs tâches concurrentes. Une session globale mélange les transactions de requêtes différentes et produit des erreurs aléatoires sous charge. Le moteur et son pool, eux, sont partagés.

    Signal d'alerteUne session créée à l'import du module et réutilisée partout, ou un commit oublié qui laisse la transaction ouverte.

  3. Question 3 · confirmé

    Un client envoie un champ is_admin dans le corps d'une mise à jour de profil, et la valeur est enregistrée en base. Comment est-ce arrivé, et comment l'empêchez-vous ?

    Une bonne réponsePar défaut, Pydantic ignore les champs inconnus, donc is_admin était déclaré dans le modèle d'entrée : un même schéma sert à la lecture et à l'écriture, ou le code recopie le JSON brut sur l'entité. Correction : des schémas séparés pour la création, la mise à jour et la lecture, sans champ sensible en entrée, model_config = ConfigDict(extra='forbid') pour rejeter l'inconnu, et une mise à jour partielle avec model_dump(exclude_unset=True) appliquée champ par champ. Le response_model filtre ce qui sort, pas ce qui entre.

    Signal d'alerteRetirer le champ à la main dans la route, ou compter sur le front pour ne pas l'envoyer.

  4. Question 4 · confirmé

    Comment protégez-vous une route qui ne doit être accessible qu'au propriétaire de la ressource ?

    Une bonne réponseUne dépendance qui valide le jeton (signature, expiration, audience, émetteur, avec une bibliothèque comme PyJWT) et renvoie l'utilisateur, puis un contrôle d'appartenance de la ressource, de préférence en filtrant la requête SQL par l'identifiant de l'utilisateur. Il répond 404 plutôt que 403 quand l'existence de la ressource ne doit pas fuiter. Il cite l'accès à l'objet d'un autre par changement d'identifiant dans l'URL, première faille du top 10 API de l'OWASP.

    Signal d'alerte« Le jeton est valide, donc l'utilisateur a le droit », sans vérifier à qui appartient l'objet.

  5. Question 5 · senior

    En production, l'API renvoie des erreurs « QueuePool limit reached » aux heures de pointe. Comment raisonnez-vous ?

    Une bonne réponseLe pool SQLAlchemy est épuisé. Soit des sessions restent ouvertes trop longtemps (appel HTTP externe pendant une transaction, session jamais rendue), soit le pool est trop petit pour le trafic. Il vérifie que chaque requête rend sa session, sort les appels lents des transactions, puis dimensionne pool_size et max_overflow en comptant les workers et les réplicas, qui ont chacun leur pool, face au max_connections de PostgreSQL. PgBouncer quand le total dépasse ce que la base accepte.

    Signal d'alertePasser pool_size à 500 sans calculer le nombre total de connexions côté PostgreSQL.

Recevez la fiche d'entretien complète en PDF

La fiche pour mener l'entretien de bout en bout, prête à imprimer ou à partager avec le manager.

  • 30 questions sur 6 axes, avec la bonne réponse, le signal d'alerte et la relance
  • Le niveau visé pour chaque question
  • Une mise en situation de 20 minutes et ce qu'on attend du candidat
  • La grille d'évaluation de 1 à 4, axe par axe

FastAPI : ce que demandent les recruteurs

Faut-il exiger FastAPI sur le CV, ou Flask et Django suffisent-ils ?

Pas forcément. Un développeur Python solide sur Flask ou Django apprend FastAPI vite, car les notions restent les mêmes : routes, validation, ORM, tests. L'écart porte surtout sur l'asynchrone. Une personne qui n'a jamais écrit de code asyncio en production aura besoin de temps pour éviter les appels bloquants et gérer des sessions async. Vérifiez ce point en entretien plutôt que le nom du framework sur le CV.

Quel test technique proposer à un développeur FastAPI ?

Une petite API existante avec deux ou trois défauts plantés : un appel requests dans une route async, une session globale, un schéma de réponse qui expose le mot de passe haché. Demandez à la personne de lire le code, de dire ce qu'elle corrige en premier, puis d'écrire un test. Quarante-cinq minutes suffisent. Faites-le en direct, documentation ouverte, comme dans le travail quotidien.

En quoi ce poste diffère-t-il d'un développeur full-stack Python ?

Le développeur FastAPI travaille sur l'API, la base de données, la sécurité et le déploiement du back-end. Le full-stack Python ajoute un front en Angular, React ou Vue, et tient les deux côtés du contrat d'API. Les offres mélangent souvent les deux intitulés. Regardez la part réelle du front dans le poste. Si elle est régulière, ajoutez un axe front-end à l'entretien.

Que peut-on attendre d'un junior sur FastAPI ?

Les bases : routes, modèles Pydantic, codes HTTP, une requête SQL avec jointure, quelques tests pytest. Le modèle async peut rester approximatif, à condition que la personne sache qu'un appel bloquant pose problème dans une fonction async def. Donnez-lui une route courte à lire et demandez ce qu'elle fait ligne par ligne. Notez si elle parle d'elle-même des cas d'erreur, comme un identifiant inexistant ou un corps invalide.

Pour structurer vos autres entretiens, consultez aussi nos pages sur les questions d'entretien de recrutement, la méthode de l'entretien structuré et la grille d'évaluation d'entretien.

Les fiches voisines

Toutes les fiches →

Voyez Delectus sur vos propres offres.

Commencez gratuitement. Passez à l'échelle quand vous êtes prêt.

Demander une démo

Votre ATS, connecté à Delectus

  • Workable
  • Teamtailor
  • iCIMS
  • Lever
  • SmartRecruiters
  • Jobvite
  • Greenhouse
  • Pinpoint