Créez une application Web typée avec le framework Web de Python «Fast API» et TypeScript / Open API - Pile technique pour les applications Web d'apprentissage automatique

Intro Présentation de FastAPI + TypeScript + OpenAPI en tant que pile technologique pour créer rapidement des applications Web avec l'apprentissage automatique et le traitement d'images comme back-end implémenté en Python.

motivation

--Je souhaite configurer rapidement un serveur Web (serveur API) avec Python ――Utilisez comme si vous utilisiez Flask jusqu'à présent

Choix envisagés

Cadre Web

Garantie de type

Conclusion d'abord

FastAPI? FastAPI logo https://fastapi.tiangolo.com/

--Base Starlette

Demo

Des motivations ci-dessus

―― Configurez rapidement une API

Démo de ça

Cliquez ici pour un exemple de référentiel: https://github.com/tuttieee/fastapi-typescript-openapi-example

En gros, procédez selon le tutoriel Fast API, mais il a été légèrement modifié pour ↑.

--Inclure le frontend (TypeScript) dans l'exemple pour couvrir le processus de création d'une WebApp --Développer et déployer avec Docker

Lancer avec Docker

Selon https://fastapi.tiangolo.com/deployment/.

Après docker-compose build, docker-compose up, essayez curl localhost: 8000

$ curl localhost:8000
{"Hello":"World"}

Exemple: https://github.com/tuttieee/fastapi-typescript-openapi-example/commit/703af24fff8d39e261e1f1ce5ba859f28e806fb2

Paramètres de développement

Exemple: https://github.com/tuttieee/fastapi-typescript-openapi-example/commit/33f6e91bc48c9c6396a9ceaf1e720b88c78a6822

Essayez de créer une API connectée à SQL

En gros, procédez selon ↓. La partie qui utilise MySQL est ajoutée indépendamment.

https://fastapi.tiangolo.com/tutorial/sql-databases/

Installation de SQL Alchemy

Pour le moment, utilisez directement le Dockerfile pour RUN pip install sqlalchemy

Exemple: https://github.com/tuttieee/fastapi-typescript-openapi-example/commit/75b7d2d7ccb8bc5a142b86bd3800b5e190732628

Premier SQLite

--Créer ʻapp / app / __ init __. Py, ʻapp / app / database.py, ʻapp / app / models.py`

from app import models
from app.database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
user = models.User(email='[email protected]', hashed_password='')
db = SessionLocal()
db.add(user)
db.commit()
db.close()
db = SessionLocal()
db.query(models.User).all()

Exemple: https://github.com/tuttieee/fastapi-typescript-openapi-example/commit/8f0d85445c33bfddd05466060b11501c2f3748b3

MySQL

Installer le logiciel associé dans le conteneur backend

RUN apt-get update && apt-get install -y \
    default-mysql-client \ 
&& apt-get clean \ 
&& rm -rf /var/lib/apt/lists/*

RUN pip install sqlalchemy PyMySQL

échantillon:

Ajouter un conteneur MySQL

-Utiliser Image officielle. En gros, écrivez les paramètres dans docker-compose.yml selon README --Ajoutez des informations d'identification à .env et passez-le en tant que variable d'environnement avec docker-compose.yml

Exemple: https://github.com/tuttieee/fastapi-typescript-openapi-example/commit/22d760d963394f340622ea402fdcf72f02cd240f

Alembic

Astuces: Vous pouvez utiliser la classe starlette telle quelle

Entrez ensuite dans le shell et procédez comme suit:

Initialisation

Exemple: https://github.com/tuttieee/fastapi-typescript-openapi-example/commit/979f4b3982b3ce3e7631661af3171000d6ea0381

Réglage

Ref: https://alembic.sqlalchemy.org/en/latest/autogenerate.html

--Modifier ʻalembic.ini --Supprimersqlalchemy.url (car il provient de database.py) --Modifier migrations / env.py` -Ajouté ↓

from app.models import Base
from app.database import SQLALCHEMY_DATABASE_URL

config.set_main_option("sqlalchemy.url", SQLALCHEMY_DATABASE_URL)
target_metadata = Base.metadata
Génération de migration

--Définissez models.py pour MySQL (spécifiez la longueur dans String)

Exemple: https://github.com/tuttieee/fastapi-typescript-openapi-example/commit/4ceae799f6f6b83ffc71cfec5ce13a669e137757

Exécution de la migration
Essaie
from app import models
from app.database import SessionLocal
user = models.User(email='[email protected]', hashed_password='')
db = SessionLocal()
db.add(user)
db.commit()
db.close()

db = SessionLocal()
db.query(models.User).all()

Création d'API

Création de modèles Pydantic

See https://fastapi.tiangolo.com/tutorial/sql-databases/#create-initial-pydantic-models-schemas ʻApp / schemas.py` créé

Créer des utils CRUD

See https://fastapi.tiangolo.com/tutorial/sql-databases/#crud-utils ʻApp / crud.py` créé

Création de l'API principale

See https://fastapi.tiangolo.com/tutorial/sql-databases/#main-fastapi-app Mise à jour ʻApp / main.py`

Exemple: https://github.com/tuttieee/fastapi-typescript-openapi-example/commit/1e7d140c1d7929c15f7815648deb14f831807ddd

Contrôle de fonctionnement

Exemple de cURL:

Depuis Open API http://localhost:8000/docs

MISC

from fastapi.routing import APIRoute

...

def use_route_names_as_operation_ids(app: FastAPI) -> None:
  """
  Simplify operation IDs so that generated API clients have simpler function
  names.

  Should be called only after all routes have been added.
  """
  for route in app.routes:
      if isinstance(route, APIRoute):
          route.operation_id = route.name

use_route_names_as_operation_ids(app)

Frontend Create React App

$ yarn create react-app frontend --template typescript
$ cd frontend
$ yarn start

Exemple: https://github.com/tuttieee/fastapi-typescript-openapi-example/commit/21b1f0f926132fdbf9c1dbef967ef4286fa27279

(Pour le moment) Accès API

# TODO: This is for development. Remove it for production.
origins = [
    "<http://localhost:3000",>
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
import React, { useState, useEffect } from 'react';
import './App.css';
import { DefaultApi, Configuration, User } from './api-client';

const config = new Configuration({ basePath: 'http://localhost:8000' }); // TODO: This is for dev
export const apiClient = new DefaultApi(config);

const App: React.FC = () => {
  const [users, setUsers] = useState<User[]>([]);

  useEffect(() => {
    apiClient.readUsers().then((response) => {
      setUsers(response.data);
    })
  })

  return (
    <div className="App">
      <ul>
        {users.map(user =>
          <li key={user.id}>{user.email}</li>
        )}
      </ul>
    </div>
  );
}

export default App;

Exemple: https://github.com/tuttieee/fastapi-typescript-openapi-example/commit/79fc0bb26c6ffa7e6e43473f0ef497dd1c2f53ff

Problèmes avec la base de code actuelle

--Doit être tapé manuellement

Génération automatique de client par OpenAPI

Intro OpenAPI: ancien Swagger FastAPI générera une définition JSON pour OpenAPI: <http: // localhost: 8000 / openapi.json> Open API Generator qui mange ce JSON et génère des clients dans différentes langues

Exécutez Open API Generator avec Docker

See https://openapi-generator.tech/docs/installation.html#docker

--Créer docker-compose.openapi-generator.yml

version: "3.7"

services:
  openapi-generator:
    image: openapitools/openapi-generator-cli
    volumes:
      - ./frontend:/frontend
    working_dir: /frontend
    command:
      - generate
      - -g
      - typescript-axios
      - -i
      - <http://backend/openapi.json>
      - -o
      - /frontend/src/api-client
      - --additional-properties=supportsES6=true,modelPropertyNaming=original
      # modelPropertyNaming=original is necessary though camelCase is preferred
      # See <https://github.com/OpenAPITools/openapi-generator/issues/2976>

--Ajouter une commande à Makefile

oapi/gen:
  docker-compose -f docker-compose.yml -f docker-compose.openapi-generator.yml up openapi-generator \
  && docker-compose -f docker-compose.yml -f docker-compose.openapi-generator.yml rm -f openapi-generator

Réécrire Frontend pour utiliser le code généré automatiquement

frontend/src/App.tsx

import React, { useState, useEffect } from 'react';
import './App.css';
import { DefaultApi, Configuration, User } from './api-client';

const config = new Configuration({ basePath: '<http://localhost:8000'> }); // TODO: This is for dev
export const apiClient = new DefaultApi(config);

const App: React.FC = () => {
  const [users, setUsers] = useState<User[]>([]);

  useEffect(() => {
    apiClient.readUsers().then((response) => {
      setUsers(response.data);
    })
  })

  return (
    <div className="App">
      <ul>
        {users.map(user =>
          <li>{user.email}</li>
        )}
      </ul>
    </div>
  );
}

export default App;

Exemple: https://github.com/tuttieee/fastapi-typescript-openapi-example/commit/1d38242a63c9a5477fa1cde506f36f68a19060a7

Autre

Ce que je n'ai pas traité dans cette démo

Dans le projet proprement dit, Unittest, CI, Linter, etc. sont adoptés le cas échéant.

Autres avantages de FastAPI, pourquoi nous avons adopté FastAPI par rapport à d'autres technologies

Recommended Posts

Créez une application Web typée avec le framework Web de Python «Fast API» et TypeScript / Open API - Pile technique pour les applications Web d'apprentissage automatique
Apprentissage automatique facile avec scikit-learn et flask ✕ Application Web
Créez une application d'apprentissage automatique avec ABEJA Platform + LINE Bot
Créez une API d'intégration sociale pour les applications smartphone avec Django
Comment créer une API de machine learning sans serveur avec AWS Lambda
Création d'une nouvelle application corona à Kyoto avec le framework Web de Python Dash
Créer une application graphique avec Tkinter de Python
Diagnostic Machine Learning x Web App: reconnaissez CAPTCHA avec l'API Cloud Vision
Créez une application Web simple avec Flask
Créez une base de données propre pour les tests avec FastAPI et effectuez le test Unittest de l'API avec pytest
Jusqu'à ce que vous créiez un environnement d'apprentissage automatique avec Python sur Windows 7 et que vous l'exécutiez
Créer une application Todo avec Django REST Framework + Angular
Créez une application graphique native avec Py2app et Tkinter
Essayez de créer une application Todo avec le framework Django REST
Créez un environnement d'apprentissage automatique à partir de zéro avec Winsows 10
Créez un environnement d'apprentissage automatique scikit-learn avec VirtualBox et Ubuntu
Créez une caméra de surveillance WEB avec Raspberry Pi et OpenCV
Tornado - Créons une API Web qui renvoie facilement JSON avec JSON
Créez une API Web capable de fournir des images avec Django
(Pour les débutants) Essayez de créer une API Web simple avec Django
Création d'un environnement Windows 7 pour une introduction à l'apprentissage automatique avec Python
Créez une illusion rayée avec correction gamma pour Python3 et openCV3
Pratique de développement d'applications Web: Créez une page de création d'équipe avec Django! (Page de création de décalage)
Créer une API REST pour faire fonctionner dynamodb avec le Framework Django REST
Créer et renvoyer un fichier CSV CP932 pour Excel avec Chalice