FastAPI est un framework moderne et explosif pour créer des API pour python3.6 et supérieur.
La caractéristique principale est
** Vitesse **: très haute performance. Il bénéficie d'une vitesse de traitement comparable à NodeJS et Go (grâce à Starlette et Pydantic). L'un des plus rapides des nombreux frameworks Python.
** Simplification du code **: Augmentez la vitesse d'écriture du code d'environ 2-3 fois. (*)
** Moins de bogues **: Il est possible de réduire les bogues de code artificiels d'environ 40%. (*)
** Écriture intuitive **: Prise en charge complète de l'éditeur et complémentarité. Il est possible de réduire le temps nécessaire au débogage.
** Facile **: conçu pour être facile à écrire et à comprendre. Vous n'avez pas à vous soucier de prendre beaucoup de temps pour lire le document.
** Court **: évitez la duplication de code. Il a des fonctions qui fournissent diverses fonctions simplement en changeant les arguments à passer.
** Solid **: vous pouvez utiliser un code identique à l'environnement de développement, même dans l'environnement de production.
** Fournir Swagger **: L'API créée est automatiquement documentée en fonction du Swagger fourni par défaut, et chaque processus peut être exécuté.
(*) D'après les recherches de l'équipe de production FastAPI.
En disant "le code parle plus que les mots", j'aimerais l'utiliser immédiatement.
Tout d'abord, créez un dossier approprié
mkdir fastapi-practice
Installez les packages requis.
pip install fastapi sqlalchemy uvicorn mysqlclient
Si vous n'aimez pas l'installation globale, veuillez l'installer en utilisant la poésie, etc. (j'utiliserai quand même de la poésie après cela).
Créez les fichiers suivants nécessaires pour exécuter FastAPI
touch main.py
Ensuite, écrivez le code comme suit.
main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def index():
return {'Hello': 'World'}
Cela seul démarrera le serveur.
uvicorn main:app
Le serveur devrait avoir démarré simplement en tapant.
http://localhost:8000/
Si vous essayez d'afficher dans un navigateur, vous devriez voir {" Hello ":" World "}
.
Vitesse explosive, API rapide. De plus, Swagger crée automatiquement des spécifications API! !! (surprise!) http://localhost:8000/docs Essayez d'afficher. Les spécifications doivent être faites avec une interface utilisateur élégante.
Vous pouvez même ouvrir un onglet et appuyer sur le bouton «Essayer» pour envoyer une demande et voir la réponse! (Impressionné !!)
Au fait http://localhost:8000/redoc Est automatiquement créé et vous pouvez facilement créer des documents plus détaillés! (Trop incroyable !!!)
Créons une API RESTful avec Fast API + MySQL en supposant un cas réel.
FastAPI peut être facilement construit avec docker, alors essayons d'exécuter mysql et FastAPI dans le conteneur et de communiquer entre eux.
Commencez par créer docker-compose.yml, docker-sync.yml et Dockerfile dans le dossier.
touch docker-compose.yml docker-sync.yml Dockerfile
Une explication détaillée de l'utilisation de docker est omise ici, mais des informations pour créer un conteneur dans Dockerfile, une commande à exécuter sur le conteneur créé dans docker-compose.yml et un environnement de développement local dans docker-sync.yml Je vais écrire du code pour synchroniser les fichiers dans le conteneur Docker en temps réel.
En ce qui concerne l'utilisation de docker-sync, je pense que les articles suivants écrits par d'autres personnes seront utiles, alors veuillez le lire. Vous pouvez le faire sans utiliser docker-sync, mais je l'utilise pour rendre la vitesse de synchronisation explosive!
https://qiita.com/Satoshi_Numasawa/items/278a143aa41735e1b0da
Maintenant, écrivons le code du Dockerfile.
Dockerfile
FROM python:3.8-alpine
RUN apk --update-cache add python3-dev mariadb-dev gcc make build-base libffi-dev libressl-dev
WORKDIR /app
RUN pip install poetry
Utilisez la poésie pour la gestion des paquets. Il existe également pipenv et pyflow pour la gestion des paquets, alors aimez-vous ça ...?
https://qiita.com/sk217/items/43c994640f4843a18dbe Cet article résume chaque gestionnaire de packages d'une manière facile à comprendre. Si vous êtes intéressé, jetez un œil.
Puis docker-sync.yml
docker-sync.yml
version: "2"
options:
verbose: true
syncs:
fastapi-practice-sync:
src: "."
notify_terminal: true
sync_strategy: "native_osx"
sync_userid: "1000"
sync_excludes: [".git", ".gitignore", ".venv"]
Et docker-compose.yml
docker-compose.yml
version: "3"
services:
db:
image: mysql:latest
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_DATABASE: fastapi_practice_development
MYSQL_USER: root
MYSQL_PASSWORD: "password"
MYSQL_ROOT_PASSWORD: "password"
ports:
- "3306:4306"
volumes:
- mysql_data:/var/lib/mysql
fastapi:
build:
context: .
dockerfile: "./Dockerfile"
command: sh -c "poetry install && poetry run uvicorn main:app --reload --host 0.0.0.0 --port 8000"
ports:
- "8000:8000"
depends_on:
- db
volumes:
- fastapi-sync:/app:nocopy
- poetry_data:/root/.cache/pypoetry/
volumes:
mysql_data:
poetry_data:
fastapi-sync:
external: true
L'astuce avec docker-compose.yml est d'utiliser correctement les données persistantes et les données ad hoc. Les données non persistantes seront réinitialisées à chaque fois que docker-compose down.
Dans ce cas, les données de mysql et le package installé par poetry sont rendus persistants afin que les données de mysql ne deviennent pas vides ou que le package n'ait pas besoin d'être téléchargé à chaque démarrage du conteneur.
De plus, comme je veux synchroniser le code que j'écris en utilisant docker-sync, j'écris fastapi-practice-sync: / app: nocopy
pour l'empêcher d'être synchronisé sans autorisation.
MySQL sera également construit en extrayant la dernière image de docker.
C'est la fin de la configuration du docker.
Tout d'abord, configurez la poésie pour installer les packages requis pour Fast API.
poetry init
Au terminal. Ensuite, la configuration démarrera de manière interactive, alors appuyez sur oui ou non à plusieurs reprises. (Comme il n'y a pas de problème avec les paramètres de base par défaut, je pense qu'il n'y a pas de problème même si vous appuyez sur Entrée à plusieurs reprises ...)
Ensuite, je pense qu'un fichier appelé «pyproject.toml» a été créé.
Les informations de dépendance des packages seront ajoutées ici, alors utilisons la poésie pour installer les packages requis pour lancer l'API Fast.
poetry add fastapi sqlalchemy uvicorn mysqlclient
Saisissez-le et attendez la fin de l'installation du package.
Lorsque vous avez terminé, ouvrez pyproject.toml
et vous verrez des informations sur les packages installés.
pyproject.toml
[tool.poetry]
name = "fastapi-practice"
version = "0.1.0"
description = ""
authors = ["Your Name <[email protected]>"]
[tool.poetry.dependencies]
python = "^3.8"
fastapi = "^0.61.1"
sqlalchemy = "^1.3.19"
uvicorn = "^0.11.8"
[tool.poetry.dev-dependencies]
[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
Ensuite, tout ce que vous avez à faire est de taper docker-compose build
, de construire l'image et de saisir docker-sync-stack start
!
docker-sync-stack start
est une commande pour exécuter docker-sync start
et docker-compose up
en même temps. C'est pratique car cela vous donne également un joli journal.Lors de l'installation d'un nouveau package, installez d'abord le package localement avec poetry add
et redémarrez le conteneur docker, et il devrait également être synchronisé à l'intérieur du conteneur!
Ensuite, nous allons créer un lien avec DB (MySQL).
En parlant d'étudier CRUD cette fois, créer une liste Todo! Je vais donc définir la table Todo et effectuer la migration.
Todos Table
column | datatype |
---|---|
id | integer |
title | string |
content | string |
done | boolean |
Nous allons migrer la table avec une telle configuration.
Tout d'abord, créez un fichier qui définit la base de données
touch db.py
J'écrirai le contenu suivant.
db.py
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker, scoped_session
user_name = "root"
password = "password"
host = "db"
database_name = "fastapi_practice_development"
DATABASE = f'mysql://{user_name}:{password}@{host}/{database_name}'
engine = create_engine(
DATABASE,
encoding="utf-8",
echo=True
)
Base = declarative_base()
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
class Todo(Base):
__tablename__ = 'todos'
id = Column(Integer, primary_key=True, autoincrement=True)
title = Column(String(30), nullable=False)
content = Column(String(300), nullable=False)
done = Column(Boolean, default=False)
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
def main():
Base.metadata.drop_all(bind=engine)
Base.metadata.create_all(bind=engine)
if __name__ == "__main__":
main()
FastAPI semble être le courant dominant pour associer une base de données à un objet Python en utilisant l'un des ORM (Object-Relation Mapping) les plus couramment utilisés en Python, appelé sqlalchemy.
Après avoir écrit ceci, il ira dans le conteneur docker et migrera.
docker-sync-stack start
Lancez le conteneur avec, mettez-le en mode synchrone,
docker container ls
Regardez la liste des conteneurs qui est en place. Puis
docker exec -it {Nom du conteneur} sh
Frappez pour entrer dans le conteneur. Ensuite, migrez avec la commande suivante.
poetry run python db.py
Ensuite, la migration s'exécutera en toute sécurité et la table sera créée avec succès!
Ensuite, j'écrirai le traitement CRUD avec Fast API.
Avec l'évolutivité à l'esprit, nous utiliserons la fonction include_router intégrée à l'API Fast pour diviser le fichier.
mkdir routers
Et frappé
touch routers/todo.py
Créez un fichier appelé. J'écrirai ici le processus CRUD.
routers/todo.py
from fastapi import Depends, APIRouter
from sqlalchemy.orm import Session
from starlette.requests import Request
from pydantic import BaseModel
from db import Todo, engine, get_db
router = APIRouter()
class TodoCreate(BaseModel):
title: str
content: str
done: bool
class TodoUpdate(BaseModel):
title: str
content: str
done: bool
@router.get("/")
def read_todos(db: Session = Depends(get_db)):
todos = db.query(Todo).all()
return todos
@router.get("/{todo_id}")
def read_todo_by_todo_id(todo_id: int, db: Session = Depends(get_db)):
todo = db.query(Todo).filter(Todo.id == todo_id).first()
return todo
@router.post("/")
def create_todo(todo: TodoCreate, db: Session = Depends(get_db)):
db_todo = Todo(title=todo.title,
content=todo.content, done=todo.done)
db.add(db_todo)
db.commit()
@router.put("/{todo_id}")
def update_todo(todo_id: int, todo: TodoUpdate, db: Session = Depends(get_db)):
db_todo = db.query(Todo).filter(Todo.id == todo_id).first()
db_todo.title = todo.title
db_todo.content = todo.content
db_todo.done = todo.done
db.commit()
@router.delete("/{todo_id}")
def delete_todo(todo_id: int, db: Session = Depends(get_db)):
db_todo = db.query(Todo).filter(Todo.id == todo_id).first()
db.delete(db_todo)
db.commit()
De cette façon, j'ai grossièrement écrit l'opération CRUD. Écrivez simplement le nom de la requête après @router et l'URL de la cible de l'opération.
Puis éditez main.py
pour qu'il puisse être lu.
main.py
from fastapi import FastAPI
from routers import todos
app = FastAPI()
app.include_router(
todos.router,
prefix="/todos",
tags=["todos"],
responses={404: {"description": "Not found"}},
)
prefix crée le chemin de l'url. les balises sont regroupées pour que les documents soient faciles à voir.
Puis http://localhost:8000/docs Lorsque vous vous connectez, cela devrait ressembler à ceci!
Ouvrez l'onglet et appuyez sur le bouton clic pour essayer le processus CRUD!
Si cela est laissé tel quel, une erreur CORS se produira lors de l'appel depuis le front-end, veuillez donc ajouter le traitement CORS suivant lors de l'appel depuis une autre application.
main.py
#Postscript
from starlette.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Comment était FastAPI? Il est très intéressant de pouvoir créer une API avec une si petite quantité de code. Il semble être très compatible lors de la création de microservices avec Python.
Comme il s'agissait du premier message de Qiita, veuillez demander si vous avez des questions! A partir de maintenant, je veux sortir le plus possible sur Qiita ... (je ferai de mon mieux)