Déployer une API Python sur Google App Engine Standard, avec FastAPI.
- Publié le
- Auteurs et autrices
- Nom
- Séraphin Vandegar
- https://noc.social/@seraphin
Cet article a été initialement publié en 2021 sur le site de mon entreprise Aynils. Je l'ai déplacé car ça fait plus de sens de m'exprimer en mon nom propre ici. J'évite mainenant d'utiliser les services de Google mais cet article reste pertinent pour celleux qui n'ont pas le choix, dans le cadre d'un projet.
Table des matières
Google App Engine Standard (GAE) était mon service préféré (avant ma réflexion sur le monopole malsain des GAFAM) pour le déploiement de mes services Python et Node.js. En plus de la générosité de son offre gratuite, j'aime GAE pour ces avantages:
- Scaling automatique ;
- Portail d'administration clair ;
- Déploiement simple, en une seule commande ;
- Écosystème Google Cloud Portal permettant d'accéder simplement à toute une série de services complémentaires: Pub/Sub, Cron tasks, DB managée, AI APIs, etc.
À côté de ces avantages, le point négatif des services de Google est souvent la précision de la documentation. Quand j'utilise un nouveau service, je dois souvent passer beaucoup de temps à chercher des réponses à mes questions et quand j'en trouve, elles ne sont pas toujours à jour.
J'ai donc décidé de contribuer à améliorer la situation en publiant ce guide pour déployer une API Python sur Google App Engine Standard.
Prérequis
- Un accès owner à un compte Google Cloud Portal (GCP);
- Python 3.8 installé sur ta machine;
- Un dépôt GitHub pour ton projet.
Conventions
Les instructions sont testées depuis Linux (Ubuntu 20.04.1 LTS) et devraient fonctionner également sous Mac OS. Si tu utilises Windows, désolé mais il faudra un peu adapter.
Quand une ligne de code commence par $
, cela signifie qu'elle doit être entrée dans ton terminal. Le $
ne doit jamais être entré avec la commande qui suit.
L'API
Tout d’abord, commençons par développer une API simple, pour les besoins de cet exercice. Si tu as déjà une application prête à être déployée, tu peux directement aller à l'étape suivante: Configuration
Création de la base du projet
Pour partir d'un environnement Python propre, crée d'abord un nouveau dossier et accédes-y.
$ mkdir ma-super-api && cd ma-super-api
Crée un environnement virtuel.
$ python3.8 -m venv venv
Maintenant, tu as besoin d'un fichier requirements.txt
pour spécifier les packages à importer.
$ touch requirements.txt
Et le fichier qui contiendra le code de notre API.
$ touch main.py
Le code
Pour ce guide, j'ai choisi de créer une API simple, en utilisant le package FastAPI. Qui permet de développer rapidement des API Python asynchrones.
L'environement
Depuis /ma-super-api/
:
Accède à l'environnement virtuel:
$ source venv/bin/activate
Si l'action à fonctionné, tu verras (venv)
indiqué devant ton nom d'utilisateur, dans le terminal. Toutes les actions effectuées à partir de maintenant le seront depuis le contexte de cet environnement virtuel.
Documente les packages à installer dans le fichier requirements.txt
fastapi
uvicorn
gunicorn
uvloop
httptools
websockets
Puis installe les packages documentés
$ pip install -r requirements.txt
Le code
Ouvre le fichier main.py dans ton éditeur favori et colles-y le code suivant:
import os
import uvicorn
from fastapi import FastAPI
app = FastAPI()
@app.get("/salut")
async def getCity():
return {
"message": "Hey, salut!"
}
if __name__ == "__main__" and os.environ.get("ENVIRONMENT") != "PRODUCTION":
uvicorn.run(app, host="0.0.0.0", port=8000)
Tu peux maintenant tester le résultat localement
$ python main.py
Le message suivant devrait être affiché dans ton terminal:
INFO: Started server process [20686]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
Et si tu ouvres ton navigateur et navigues à l'adresse http://0.0.0.0:8000/salut
, tu y verras le résultat suivant:
{"message":"Hey, salut!"}
Si ça marche, tu peux arrêter le serveur en appuyant sur CTRL + C
puis sortir de l’environnement virtuel $ deactivate
Configuration
Git
Il te faut un dépôt git local, synchronisé avec le dépôt GitHub de ce projet.
$ git init
$ git remote add origin <URL_DE_TON_DEPOT_GITHUB>
Et un gitignore pour ne pas synchroniser ton environnement virtuel avec le dépôt.
$ echo "venv" > .gitignore
Google App Engine
Création de l'app
Ouvre le portal de Google App Engine et clique sur Créer une application
. Choisis les options suivantes:
- Localisation: choisis le serveur le plus près des services qui utiliseront l'API
- Langage:
Python
- Environnement:
Standard
A l'étape Déployer avec le SDK Google Cloud
, clique sur Je le ferai plus tard
Activation de Cloud build API
Ouvre le portail Cloud Build et clique sur Activer
Configuration de l'API
La configuration de l'instance Google App Engine sur laquelle ton API sera déployée se trouve dans le fichier app.yaml
, déployé avec ton application. Crée ce fichier:
$ touch app.yaml
Ensuite, ajoutes-y le contenu suivant:
runtime: python38
entrypoint: gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker
instance_class: F2
env_variables:
ENVIRONMENT: "PRODUCTION
handlers:
- url: /.*
secure: always
redirect_http_response_code: 301
script: auto
La documentation concernant ce fichier est disponible ici
Compte de service
Pour créer l'instance Google App Engine et y déployer l'API, tu as besoin d'un compte de service. Pour le créer, ça se passe dans la section IAM de ton compte Google Cloud Portal, onglet "Comptes de service".
Clique sur Créer un compte de service
dans la barre supérieure et remplisse les différents champs de l'étape 1 Détails du compte de service
avec les données suivantes:
- Nom du compte de service:
github-action
- ID du compte de service: laisser la valeur par défaut
- Description du compte de service:
Compte utilisé par GitHub actions pour gérer les instances
A l'étape 2 Autoriser ce compte de service à accéder au projet
, ajoute les rôles suivants:
- Déployeur App Engine
- Administrateur de services App Engine
- Éditeur Cloud Build
- Utilisateur du compte de service
- Créateur des objets de l'espace de stockage
- Lecteur des objets de l'espace de stockage
N'entre rien à l'étape 3 Autoriser les utilisateurs à accéder à ce compte de service
et clique sur OK
pour valider.
Ensuite, ouvre le menu en cliquant sur les trois points dans la colonne tout à droite de la ligne correspondant au compte de service nouvellement créé et choisis l'option créer une clé
.
Choisir json
et enregistrer le fichier localement. ⚠️Cette clé permet d'accéder à ton compte et doit donc être stockée en sécurité.
Pour utiliser la clé pour le déploiement, tu as besoin de sa représentation en base 64. Pour ce faire, ouvre ton terminal dans le dossier ou se trouve la clé que tu viens de télécharger et utilise la commande suivante:
$ base64 <NOM_DU_FICHIER_DE_CLE>
Copier le résultat et le conserver pour l'étape suivante.
GitHub
Secret
Dans ton compte GitHub, aller navigue vers le dépôt de ce projet puis ouvre la page Settings
puis l'onglet Secrets
.
Crée un nouveau secret en cliquant sur New repository secret
avec les données suivantes:
- Name:
GAE_DEPLOY_KEY
- Value: copie ici la représentation base64 de ta clé que tu viens de créer à l'étape précédente
Action
La configuration se trouve dans un fichier .yaml
à créer dans le projet.
$ mkdir -p .github/workflows/
$ touch .github/workflows/gae.yaml
Ouvre le fichier et y ajoutes-y la configuration suivante:
name: Deploy to Google App Engine
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@master
- name: Deploy to production
if: github.ref == 'refs/heads/main'
uses: google-github-actions/deploy-appengine@main
with:
credentials: ${{ secrets.GAE_DEPLOY_KEY }}
deliverables: app.yaml
Déploiement
Ça y est, c'est le moment de déployer ton API! 🥳
Premièrement, commit tes changements localement
$ git add .
$ git commit -m "initial commit"
Et puis, pousse les changements vers le dépôt distant GitHub.
$ git branch -M main
❗Cette étape sert à renommer la branche master
crée par défaut localement vers main
qui est le nouveau nom de la branche principale sur GitHub
$ git push -u origin main
Maintenant, tout est prêt. Il ne te reste plus qu'à tester. Pour cela, il faut un changement pour pouvoir pousser à nouveau vers GitHub et déclencher l'action qui à été créée à l'étape précédente.
$ touch README.MD
$ git add .
$ git commit -m "add README"
$ git push
Test
Pour vérifier le statut du déploiement, ça se passe sur GitHub, sur la page du dépôt du projet, dans l'onglet Actions
.
Si c'est vert, c'est bon. Si c'est rouge, c'est pas bon. (merci Captain Obvious!).
Pour accéder à l'API, il te reste à trouver son url. Elle se trouve sur le portail Google App Engine, en haut à droite. Elle ressemble à <NOM_DE_TON_PROJET>.uc.r.appspot.com
Ouvre ton navigateur et navigues vers <URL_DE_TON_APP_ENGINE>/salut
et tu devrais voir le résultat:
{ 'message': 'Hey, salut!' }
Et voilà! ✨