[PYTHON] L'histoire que FastAPI peut prendre la suprématie

Bonjour, bonne soirée, bonjour. Il s'agit de Shimabukuro de K.S. Rogers.

J'ai écrit un article comme Auparavant, la prochaine suprématie du framework Web de Python est celle-ci, mais après cela, j'ai passé un moment loin de Python en tant qu'ingénieur. Au fait, un framework appelé FastAPI est apparu!

Pour être honnête, je suis en retard parce que je ne sais pas quel numéro préparer, mais laissez-moi vous le présenter.

Caractéristiques de FastAPI

Selon la page d'accueil officielle,

  1. Haute vitesse aussi rapide que NodeJS et Go
  2. Écriture de code rapide - double et triple!
  3. Bugs réduits-réduits d'environ 40%!
  4. Intuitif-facile à déboguer
  5. Facile à utiliser. Facile à lire le document!
  6. Duplication sans court-circuit. Plusieurs fonctions peuvent être appelées par déclaration de paramètre
  7. Robuste - C'est vraiment facile car il est généré automatiquement
  8. Standard-Compatible avec la norme OpenAPI (compatible avec Swagger)

Il dit, mais c'est compatible parce que c'est le standard ʻOpenAPI en bas (compatible avec Swagger) `C'est trop génial. FastAPI, en fait, Swagger (document) peut être généré automatiquement!

Génération automatique de documents

Après avoir installé fastapi et ʻuvicorn` avec pip, je vais le toucher immédiatement. En passant, le pip standard n'a pas d'isolation d'environnement, il est donc recommandé d'utiliser pipenv.

from fastapi import FastAPI

app = FastAPI()


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

Après avoir créé ce qui précède avec main.py, démarrez-le avec ʻuvicorn main: app --reload. Si vous cochez http: //127.0.0.1: 8000 / docs` ...

Fast API - Swagger UI 2020-02-05 00-29-56.jpg

Oui! Agréable! !! Si vous essayez de définir le paramètre de chemin ...

Path parameters

@app.get("/{name}")
async def root():
    return {"message": "Hello " + name}
Fast API - Swagger UI 2020-02-05 13-09-21.jpg

Il sera reflété automatiquement. C'est le plus fort que les documents sont créés automatiquement. C'est une fonction trop pratique pour nous, qui accordons une importance particulière aux documents.

Query Parameters

@app.get("/")
async def read_item(name: str = ""):
    return {"message": "Hello " + name}
Fast API - Swagger UI 2020-02-05 23-04-27.jpg

Requests Utilisez le modèle.

from fastapi import FastAPI
from pydantic import BaseModel

class Item(BaseModel):
    name: str
    description: str = None

app = FastAPI()


@app.post("/items/")
async def create_item(item: Item):
    return item
Fast API - Swagger UI 2020-02-05 23-12-03.jpg

De plus, la validation peut être spécifiée pour les propriétés de la classe Model, la gestion est donc très bonne. C'est une structure similaire au modèle Django.

class Item(BaseModel):
    name: str = Field(None, min_length=2, max_length=5)
    description: str = Field(None, max_length=100)

CRUD (Crate, Read, Update, Delete) Écrivons grossièrement le CRUD de base. Puisqu'il s'agit d'un extrait partiel, veuillez vous référer au lien d'écriture pour plus de détails.

https://github.com/shuto-S/sample-fast-api

DB Connection & Migration Utilisez databases et sqlalchemy pour vous connecter et migrer vers la base de données. Cette fois, nous utiliserons SQLite, qui est facile à manipuler, pour la base de données.

Écrivez rapidement autour de la connexion,

import databases
import sqlalchemy

DATABASE_URL = "sqlite:///./db.sqlite3"

database = databases.Database(DATABASE_URL)
engine = sqlalchemy.create_engine(DATABASE_URL, echo=False)
metadata = sqlalchemy.MetaData()

Schemas Décrivez la définition de la table et exécutez le même fichier.

import sqlalchemy
from db import metadata, engine


items = sqlalchemy.Table(
    "items",
    metadata,
    sqlalchemy.Column("id", sqlalchemy.Integer, primary_key=True),
    sqlalchemy.Column("name", sqlalchemy.String),
    sqlalchemy.Column("description", sqlalchemy.String),
)

metadata.create_all(engine)

Main main.py également réparé

from fastapi import FastAPI
from db import database
from starlette.requests import Request
from routers import items

app = FastAPI()

@app.on_event("startup")
async def startup():
    #Début de la connexion à la base de données
    await database.connect()

@app.on_event("shutdown")
async def shutdown():
    #Déconnexion de la connexion DB
    await database.disconnect()

#Enregistrer les routeurs
app.include_router(items.router)

#Incorporer une connexion de base de données avec un middleware (afin qu'elle puisse être obtenue avec un routeur)
@app.middleware("http")
async def db_session_middleware(request: Request, call_next):
    request.state.connection = database
    response = await call_next(request)
    return response

Routers router est également divisé en fichiers afin de pouvoir être décrit pour chaque point final.

from fastapi import APIRouter, Depends, HTTPException
from typing import List
from databases import Database
from starlette.status import HTTP_204_NO_CONTENT

from utils import get_db_connection
from schemas import items
from models.item import ItemModel


router = APIRouter()

@router.get("/items", tags=["items"], response_model=List[ItemModel])
async def list_item(database: Database = Depends(get_db_connection)):
    query = items.select()
    return await database.fetch_all(query)

@router.post("/items", tags=["items"], response_model=ItemModel)
async def create_item(data: ItemModel, database: Database = Depends(get_db_connection)):
    query = items.insert()
    await database.execute(query, data.dict())
    return {**data.dict()}

@router.patch("/items/{item_id}", tags=["items"], response_model=ItemModel)
async def update_item(item_id: int, data: ItemModel, database: Database = Depends(get_db_connection)):
    query = items.update().where(items.columns.id==item_id)
    ret = await database.execute(query, data.dict())
    if not ret:
        raise HTTPException(status_code=404, detail="Not Found")
    return {**data.dict()}

@router.delete("/items/{item_id}", tags=["items"], status_code=HTTP_204_NO_CONTENT)
async def delete_item(item_id: int, database: Database = Depends(get_db_connection)):
    query = items.delete().where(items.columns.id==item_id)
    ret = await database.execute(query)
    if not ret:
        raise HTTPException(status_code=404, detail="Not Found")

Résumé

Comment c'est? La génération automatique de documents n'est-elle pas une fonctionnalité assez intéressante? Je pense que Responder est également un très bon cadre, mais j'ai trouvé FastAPI moins original et plus facile à écrire.

Postscript

En passant, nous publions également des blogs d'entreprise en plus de notre entreprise et de notre technologie, donc si vous êtes intéressé, faites-le. https://www.wantedly.com/companies/ks-rogers

Recommended Posts

L'histoire que FastAPI peut prendre la suprématie
L'histoire que scipy a soudainement arrêté de se charger
L'histoire que XGBoost a finalement été installé
L'histoire qui s'inscrit dans l'installation de pip
Une histoire qui réduit l'effort de fonctionnement / maintenance
Une histoire qui a eu du mal avec l'ensemble commun HTTP_PROXY = ~
L'histoire de l'affichage des personnages dans l'entrée japonaise de Kivy
L'histoire selon laquelle la valeur de retour de tape.gradient () était None
Modules pouvant passer par le shell en Python
L'histoire de la confusion entre la production japonaise et Django
Une histoire qui a analysé la livraison de Nico Nama.
L'histoire selon laquelle yapf n'a pas fonctionné avec vscode
L'histoire selon laquelle ma pull request a été intégrée à Scipy
Histoire que Python a cessé de travailler avec VS Code (Windows 10)
L'histoire de la définition de la clé privée à 600 avec chmod