ademoverflow
fr
en

Déployer votre application FastAPI sur AWS Lambda via Serverless

Auteur: Adem Usta

Publié le 2021-04-10

Déployer votre application FastAPI sur AWS Lambda via Serverless

Introduction

FastAPI, le framework python créé par Sebastián Ramírez, est un super framework permettant de créer des API REST.

Son utilisation est simple et facile d’accès.

Si vous ne connaissez pas ce framework, je vous invite à aller faire un tour sur la documentation officielle, et de vous y mettre au plus vite !

Si vous êtes tombés sur cet article, c’est que vous cherchez un moyen simple de déployer votre app FastAPI sur une lambda, l’environnement serverless de AWS.

Bonne pioche ! On va vous expliquer comment procéder.

Tutoriel

Étape 1 - Créer son application FastAPI

En suivant le guide dans la documentation officielle, on crée une app en quelques lignes de code.

Créer un fichier main.py contenant la déclaration de l’app et une route hello:

from fastapi import FastAPI

app = FastAPI(title="MyAwesomeApp")

@app.get("/hello")
def hello_world():
    return {"message": "Hello World"}

Étape 2 - Tester le fonctionnement de l’app localement

Pour tester l’application localement, vous pouvez créer un environnement virtuel et installer le contenu du fichier requirements.txt suivant:

fastapi==0.63.0
uvicorn==0.13.4

Quelques commandes pour créer tout cela …

python3.8 -m venv .virtualenv   # Création d'un environnement virtuel
source .virtualenv/bin/activate # Activation de celui-ci
pip install -r requirements.txt # Installation des packages python

Lancez l’application localement:

uvicorn main:app

Vous devriez voir des logs comme ceux ci-dessous:

INFO:     Started server process [87999]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

Votre application est disponible sur http://127.0.0.1:8000.

Vous pouvez voir la documentation autogénérée via http://127.0.0.1:8000/docs

Un petit aperçu:

FastAPI documentation autogénérée

Votre application fonctionne localement ? Parfait, on est prêts pour la suite.

Étape 3 - Rendre compatible votre application avec l’écosystème d’AWS Lambda

Pour rendre votre application compatible avec AWS Lambda, nous allons utiliser un outil: Mangum.

Ajoutez le dans le fichier requirements.txt, il sera utile pour la suite:

fastapi==0.63.0
uvicorn==0.13.4
mangum==0.11.0

Nous allons modifier main.py pour “envelopper” notre objet app.

Votre fichier main.py devient alors:

from fastapi import FastAPI
from mangum import Mangum

app = FastAPI(title="MyAwesomeApp")

@app.get("/hello")
def hello_world():
    return {"message": "Hello World"}

handler = Mangum(app)

Remarque:

A ce stade, l’application est prête et sera fonctionnelle avec l’environnement Lambda, mais une des fonctionnalités de FastAPI ne fonctionnera pas: la page de documentation.

En effet: lorsque la lambda sera créée, le point de terminaison de celle-ci aura la forme https://XXXXXXX.execute-api.eu-west-1.amazonaws.com/stage, avec stage qui peut valoir la valeur que vous voulez (on le verra dans la suite).

Hors, pour générer la page de documentation, FastAPI a besoin, par défaut, d’être servi sur un nom de domaine, et non sur un sous-domaine.

Pour régler cela, on va modifier un minimum le code de l’application, avec ceci:

import os

from fastapi import FastAPI
from mangum import Mangum

stage = os.environ.get('STAGE', None)
openapi_prefix = f"/{stage}" if stage else "/"

app = FastAPI(title="MyAwesomeApp", openapi_prefix=openapi_prefix) # la magie se trouve ici.


@app.get("/hello")
def hello_world():
    return {"message": "Hello World"}


handler = Mangum(app)

En résumé:

On change le chemin sur lequel le fichier openapi.json est servi, ce qui servira à la page de documentation de fonctionner correctement.

Dans l’état, votre code python est prêt ! Il nous reste plus qu’à déployer cela, avec le framework serverless.

Étape 4 - Utiliser serverless pour le déploiement dans le cloud

A partir de cette étape, vous allez avoir besoin de la CLI serverless et de le configurer avec vos identifiants AWS.

La CLI s’installe avec npm:

npm install -g serverless

C’est un outil qui facilite le déploiement d’applications et services dans le cloud, en décrivant via un fichier YAML les services que l’on veut déployer.

Il est compatible avec AWS Lambda, et plus généralement avec l’outil Cloudformation d’AWS.

Pour plus d’informations, allez sur serverless.com

Après avoir installé serverless, il faut le configurer avec vos identifiants AWS, que vous trouverez dans votre console AWS.

La configuration se fait via cette commande:

serverless config credentials --provider aws --key <YOUR_KEY> --secret <YOUR_SECRET_KEY>

Vous allez donc créer un fichier serverless.yaml qui va contenir les informations des services à déployer:

service: my-awesome-app

package:
  individually: true

provider:
  name: aws
  runtime: python3.8
  region: eu-west-1
  stage: ${opt:stage, "dev"}

plugins:
  - serverless-python-requirements

custom:
  pythonRequirements:
    dockerizePip: true
    layer:
      name: my-awesome-app-layer
      description: My awesome app layer
      compatibleRuntimes:
        - python3.8

functions:
  app:
    package:
      include:
        - "main.py"
      exclude:
        - "requirements.txt"
        - "package.json"
        - "package-lock.json"
        - ".serverless/**"
        - ".virtualenv/**"
        - "node_modules/**"

    handler: main.handler
    environment:
      STAGE: ${self:provider.stage}
    layers:
      - { Ref: PythonRequirementsLambdaLayer }
    events:
      - http:
          method: any
          path: /{proxy+}

Et, au même niveau, vous allez créer un fichier package.json contenant:

{
    "name": "my-awesome-app",
    "version": "1.0.0",
    "author": "<YOUR_NAME>",
    "dependencies": {
        "serverless-python-requirements": "^5.0.1"
    }
}

Ce fichier va servir à installer les différents plugins Javascript, qui sont utilisés et nommés dans le fichier YAML plus-haut.

Installons les plugins:

npm install

Et, déployons notre application dans le cloud !

sls deploy --stage staging # "stage" désignera le stage de votre application dans le cloud.

serverless fait sa magie, et au bout de quelques minutes (moins de 5 en général), vous aurez des logs ressemblant à ceux-ci:

Service Information
service: my-awesome-app
stage: staging
region: eu-west-1
stack: my-awesome-app-staging
resources: 12
api keys:
  None
endpoints:
  ANY - <LE POINT DE TERMINAISON EST ICI>
functions:
  app: my-awesome-app-staging-app
...

En regardant ces logs, vous trouverez le point de terminaison de votre application !

Ici c’est https://XXXXXXXXX.execute-api.eu-west-1.amazonaws.com/staging/ (XXXXXX est en général une suite de chiffres et de lettres).

Si vous allez sur https://XXXXXXXXX.execute-api.eu-west-1.amazonaws.com/staging/docs, vous allez vous retrouver face à la documentation de votre app FastAPI !

Pour mettre à jour votre application, vous avez juste à effectuer vos modifications dans le code python, et ensuite le déploiement se fait en executant:

sls deploy --stage staging

Pour supprimer l’application et ses dépendences du cloud:

sls remove --stage staging

Vous avez maintenant tout de votre côté pour créer des applications FastAPI et les héberger via l’ecosystème AWS Lambda !

Faites en bon usage !

[Bonus] Étape 5 - Utiliser son nom de domaine personnalisé

Si vous voulez que votre app soit disponible sur votre domaine, il ne vous reste pas grand chose à faire.

Cette étape vous expliquera pas à pas ce qu’il manque.

Quelques pré-requis sont nécessaires:

  • un nom de domaine enregistré sur AWS Route53
  • un certificat lié au nom de domaine pour avoir le HTTPS, généré sur AWS Certificate Manager (si vous n’en avez pas, faites en sorte de le créer dans la région par défaut d’AWS us-east-1 qui est considéré comme global pour les certificats).

On va utiliser un plugin qui va nous faciliter la vie: serverless-domain-manager.

Installons le:

npm install serverless-domain-manager

Et ajoutons le dans la liste des plugins dans notre fichier serverless.yaml:

plugins:
  - serverless-python-requirements
  - serverless-domain-manager

On doit configurer le plugin, vous allez donc ajouter dans la partie custom de serverless.yaml:

custom:
  customDomain:
    domainName: VOTRE_DOMAINE_ICI
    stage: ${self:provider.stage}
    certificateArn: VOTRE_CERTIFICAT_ARN_ICI
    endpointType: "edge"
    securityPolicy: tls_1_2
    apiType: rest
    autoDomain: true
    autoDomainWaitFor: 120

(N’oubliez pas de renseigner les champs comme indiqué).

Une fois cela fait, on déploie:

sls deploy --stage staging

Après quelques minutes on peut accéder à notre API via votre nom de domaine !

… Vraiment ?

Tentez d’accéder à la documentation générée sur /docs … vous voyez le piège ?

FastAPI Erreur documentation

Cela vient de ce que l’on a ajouté dans le code python pour pouvoir accéder à la documentation depuis le point de terminaison de notre lambda !

Il ne nous reste plus qu’à l’enlever:

app = FastAPI(title="MyAwesomeApp", openapi_prefix=openapi_prefix) # Changez cela

app = FastAPI(title="MyAwesomeApp") # Avec cela

Redéployez.

Tada GIF

Vous avez maintenant votre application FastAPI, hébergé sur AWS Lambda, accessible depuis votre nom de domaine personnel.

Libre à vous maintenant de créer des applications cools !

Conclusion

A travers cet article écrit sous la forme d’un petit tutoriel, vous êtes maintenant capable de créer une application FastAPI, de la tester localement et de la déployer sur AWS via serverless !

Si vous avez des questions ou des remarques, n’hésitez pas à me contacter.

A la prochaine,

Adem.