Ich habe versucht, eine RESTful-API zu erstellen, indem ich die explosive Fast-API des Python-Frameworks mit MySQL verbunden habe.

Was ist FastAPI?

68747470733a2f2f666173746170692e7469616e676f6c6f2e636f6d2f696d672f6c6f676f2d6d617267696e2f6c6f676f2d7465616c2e706e67.png

FastAPI ist ein modernes und explosives Framework zum Erstellen von APIs für Python3.6 und höher.

Das Hauptmerkmal ist

(*) Nach den Untersuchungen des FastAPI-Produktionsteams.

Versuchen Sie vorerst, den Server zu starten

Wenn ich sage "Code spricht mehr als Worte", möchte ich ihn sofort verwenden.

Erstellen Sie zunächst einen geeigneten Ordner

mkdir fastapi-practice

Installieren Sie die erforderlichen Pakete.

pip install fastapi sqlalchemy uvicorn mysqlclient

Wenn Sie die globale Installation nicht mögen, installieren Sie sie bitte mit Gedichten usw. (danach werde ich ohnehin Gedichte verwenden).

Erstellen Sie die folgenden Dateien, die zum Ausführen von FastAPI erforderlich sind

touch main.py

Schreiben Sie dann den Code wie folgt.

main.py


from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def index():
    return {'Hello': 'World'}

Dies allein startet den Server.

uvicorn main:app

Der Server sollte nur durch Eingabe gestartet werden. http://localhost:8000/ Wenn Sie versuchen, in einem Browser anzuzeigen, sollte "{" Hallo ":" Welt "}" angezeigt werden.

Explosive Geschwindigkeit, schnelle API. Darüber hinaus erstellt Swagger automatisch API-Spezifikationen! !! (Überraschung!) http://localhost:8000/docs Versuchen Sie anzuzeigen. Die Spezifikationen sollten mit einer stilvollen Benutzeroberfläche erstellt werden.

Sie können sogar einen Tab öffnen und auf die Schaltfläche "Ausprobieren" klicken, um eine Anfrage zu senden und die Antwort anzuzeigen! (Beeindruckt !!)

スクリーンショット 2020-09-24 14.05.22.png

Apropos http://localhost:8000/redoc Wird automatisch erstellt und Sie können problemlos detailliertere Dokumente erstellen! (Zu erstaunlich !!!)

Verwenden Sie es tatsächlich (Docker-Umgebungskonstruktion)

Lassen Sie uns eine RESTful-API mit Fast API + MySQL erstellen, wobei ein realer Fall angenommen wird.

FastAPI kann einfach mit Docker erstellt werden. Versuchen wir also, MySQL und FastAPI im Container auszuführen und miteinander zu kommunizieren.

Erstellen Sie zunächst docker-compose.yml, docker-sync.yml und Dockerfile im Ordner.

touch docker-compose.yml docker-sync.yml Dockerfile

Eine ausführliche Erläuterung zur Verwendung von Docker wird hier weggelassen, aber Informationen zum Erstellen eines Containers in Dockerfile, ein Befehl zum Ausführen des in docker-compose.yml erstellten Containers und eine lokale Entwicklungsumgebung in docker-sync.yml Ich werde Code schreiben, um die Dateien im Docker-Container in Echtzeit zu synchronisieren.

Was die Verwendung von Docker-Sync betrifft, denke ich, dass die folgenden Artikel, die von anderen Personen geschrieben wurden, hilfreich sein werden. Bitte lesen Sie sie. Sie können es ohne Docker-Sync tun, aber ich benutze es, um die Sync-Geschwindigkeit explosiv zu machen!

https://qiita.com/Satoshi_Numasawa/items/278a143aa41735e1b0da

Schreiben wir nun den Code aus der Docker-Datei.

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

Verwenden Sie Poesie für die Paketverwaltung. Es gibt auch pipenv und pyflow für die Paketverwaltung. Gefällt dir das ...?

https://qiita.com/sk217/items/43c994640f4843a18dbe Dieser Artikel fasst jeden Paketmanager auf leicht verständliche Weise zusammen. Wenn Sie interessiert sind, schauen Sie bitte.

Dann 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"]

Und 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

Der Trick mit docker-compose.yml besteht darin, die persistenten Daten und die Ad-hoc-Daten ordnungsgemäß zu verwenden. Nicht persistente Daten werden jedes Mal zurückgesetzt, wenn Docker komponiert wird.

In diesem Fall werden die Daten in MySQL und das von Poetry installierte Paket dauerhaft gemacht, damit die Daten in MySQL nicht leer werden oder das Paket nicht bei jedem Start des Containers heruntergeladen werden muss. Da ich den Code, den ich mit Docker-Sync schreibe, synchronisieren möchte, schreibe ich außerdem "fastapi-Practice-Sync: / app: nocopy", um zu verhindern, dass er ohne Erlaubnis synchronisiert wird.

MySQL wird auch erstellt, indem das neueste Image vom Docker abgerufen wird.

Dies ist das Ende der Docker-Einrichtung.

Verwenden Sie es tatsächlich (schnelle API-Einstellung)

Richten Sie zunächst Poesie ein, um die für Fast API erforderlichen Pakete zu installieren.

poetry init

Am Terminal. Dann startet das Setup interaktiv. Drücken Sie also wiederholt Ja oder Nein. (Da es keine Probleme mit den Grundeinstellungen gibt, gibt es meines Erachtens auch dann kein Problem, wenn Sie wiederholt die Eingabetaste drücken ...)

Dann denke ich, dass eine Datei namens "pyproject.toml" erstellt wurde.

Informationen zur Paketabhängigkeit werden hier hinzugefügt. Verwenden Sie also Poesie, um die Pakete zu installieren, die zum Starten der Fast-API erforderlich sind.

poetry add fastapi sqlalchemy uvicorn mysqlclient

Geben Sie dies ein und warten Sie, bis die Paketinstallation abgeschlossen ist. Wenn Sie fertig sind, öffnen Sie "pyproject.toml" und Sie sehen Informationen zu den installierten Paketen.

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"

Dann müssen Sie nur noch "Docker-Compose Build" eingeben, das Image erstellen und "Docker-Sync-Stack Start" eingeben!

Wenn Sie ein neues Paket installieren, installieren Sie das Paket zuerst lokal mit "Poetry Add" und starten Sie den Docker-Container neu. Es sollte auch im Container synchronisiert werden!

Wandern

Als nächstes werden wir mit DB (MySQL) verknüpfen.

Apropos diesmal CRUD studieren, eine Todo-Liste erstellen! Also werde ich die Todo-Tabelle definieren und die Migration durchführen.

Todos Table

column datatype
id integer
title string
content string
done boolean

Wir werden die Tabelle mit einer solchen Konfiguration migrieren.

Erstellen Sie zunächst eine Datei, die die Datenbank definiert

touch db.py

Ich werde den folgenden Inhalt schreiben.

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 scheint der Mainstream zu sein, um eine Datenbank mit einem Python-Objekt zu verknüpfen, indem eines der in Python am häufigsten verwendeten ORM (Object-Relation Mapping) namens sqlalchemy verwendet wird.

Nachdem Sie dies geschrieben haben, gehen Sie in den Docker-Container und beginnen Sie mit der Migration.

docker-sync-stack start

Starten Sie den Container mit, versetzen Sie ihn in den synchronen Modus,

docker container ls

Schauen Sie sich die Containerliste an, die sich in befindet. Dann

docker exec -it {Containername} sh

Drücken Sie, um den Container zu betreten. Migrieren Sie dann mit dem folgenden Befehl.

poetry run python db.py

Dann läuft die Migration sicher und die Tabelle wird erfolgreich erstellt!

Als nächstes werde ich die CRUD-Verarbeitung mit Fast API schreiben.

Schreiben wir die CRUD-Verarbeitung mit FastAPI

Im Hinblick auf die Erweiterbarkeit verwenden wir die in die Fast-API integrierte Funktion include_router, um die Datei zu teilen.

mkdir routers

Und getroffen

touch routers/todo.py

Erstellen Sie eine Datei mit dem Namen. Ich werde den CRUD-Prozess hier schreiben.

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()

Auf diese Weise habe ich grob die CRUD-Operation geschrieben. Schreiben Sie einfach den Anforderungsnamen nach @router und die URL des Operationsziels.

Bearbeiten Sie dann main.py, damit es gelesen werden kann.

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"}},
)

Präfix erstellt den Pfad für die URL. Tags sind so gruppiert, dass die Dokumente leicht zu sehen sind.

Dann http://localhost:8000/docs Wenn Sie eine Verbindung herstellen, sollte dies so aussehen!

スクリーンショット 2020-09-24 14.53.20.png

Öffnen Sie die Registerkarte und drücken Sie die Klick-Taste, um den CRUD-Prozess zu versuchen!

Wenn dies unverändert bleibt, tritt beim Aufrufen vom Front-End aus ein CORS-Fehler auf. Fügen Sie daher beim Aufrufen aus einer anderen Anwendung die folgende CORS-Verarbeitung hinzu.

main.py


#Nachtrag
from starlette.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

Zusammenfassung

Wie war FastAPI? Es ist sehr attraktiv, eine API mit so wenig Code erstellen zu können. Es scheint sehr kompatibel zu sein, wenn Microservices mit Python erstellt werden.

Da dies Qiitas erster Beitrag war, fragen Sie bitte, wenn Sie Fragen haben! Von nun an möchte ich so viel wie möglich an Qiita ausgeben ... (Ich werde mein Bestes geben)

Recommended Posts

Ich habe versucht, eine RESTful-API zu erstellen, indem ich die explosive Fast-API des Python-Frameworks mit MySQL verbunden habe.
Ich habe versucht, API list.csv mit Python aus swagger.yaml zu erstellen
Ich habe versucht, eine Quip-API zu erstellen
Django super Einführung von Python-Anfängern! Teil 6 Ich habe versucht, die Login-Funktion zu implementieren
Ich habe versucht, einen einfachen Kredit-Score mit logistischer Regression zu erstellen.
Rubyist hat versucht, eine einfache API mit Python + Flasche + MySQL zu erstellen
Ich habe eine Python-Bibliothek erstellt, um die API von LINE WORKS aufzurufen
Ich habe versucht, mit Python eine Liste von Primzahlen zu erstellen
Erstellen Sie eine REST-API, um dynamodb mit dem Django REST Framework zu betreiben
Ich habe versucht, einen Linebot zu erstellen (Implementierung)
Ich habe versucht, einen Linebot zu erstellen (Vorbereitung)
Ich habe versucht, die COTOHA-API zu berühren
Ich habe eine Web-API erstellt
Ich habe das Python Tornado Testing Framework ausprobiert
Ich habe versucht, die Sprecheridentifikation mithilfe der Sprechererkennungs-API von Azure Cognitive Services mit Python zu überprüfen. # 1
Ich habe versucht, die Sprecheridentifikation mithilfe der Sprechererkennungs-API von Azure Cognitive Services in Python zu überprüfen. # 2
Ich habe versucht, ein Programm zu erstellen, das Hexadezimalzahlen mit Python in Dezimalzahlen konvertiert
Ich habe versucht, den Authentifizierungscode der Qiita-API mit Python abzurufen.
Ich habe versucht, die Beschleunigung von Python durch Cython zu verifizieren und zu analysieren
[Outlook] Ich habe versucht, mit Python automatisch eine tägliche Berichtsmail zu erstellen
Ich habe versucht, die Filminformationen der TMDb-API mit Python abzurufen
Ich habe ein Beispiel für den Zugriff auf Salesforce mit Python und Bottle erstellt
Ich habe versucht, das Ergebnis des A / B-Tests mit dem Chi-Quadrat-Test zu überprüfen
Ich habe versucht, die Neujahrskarte selbst mit Python zu analysieren
Django super Einführung von Python-Anfängern! Teil 3 Ich habe versucht, die Vererbungsfunktion für Vorlagendateien zu verwenden
Django super Einführung von Python-Anfängern! Teil 2 Ich habe versucht, die praktischen Funktionen der Vorlage zu nutzen
Ich möchte mit Python ein Fenster erstellen
Ich habe versucht, das Datetime-Modul von Python zu verwenden
Ich habe versucht, eine Klasse zu erstellen, mit der Json in Python problemlos serialisiert werden kann
Erstellen wir es, indem wir den Protokollpuffer mit Serverless Framework auf die API anwenden.
Als ich versuchte, mit Python eine virtuelle Umgebung zu erstellen, funktionierte dies nicht
Ich habe versucht, mit Selenium + Python einfach ein vollautomatisches Anwesenheitssystem zu erstellen
[Python] Ich habe versucht, den Typnamen als Zeichenfolge aus der Typfunktion abzurufen
Ich habe versucht, ein Modell mit dem Beispiel von Amazon SageMaker Autopilot zu erstellen
Ich möchte eine API erstellen, die ein Modell mit einer rekursiven Beziehung im Django REST Framework zurückgibt
Ich habe versucht, die in Python installierten Pakete grafisch darzustellen
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 1 ~
Ich habe versucht, eine CSV-Datei mit Python zu berühren
Ich habe versucht, Soma Cube mit Python zu lösen
Ich habe versucht, einen Pseudo-Pachislot in Python zu implementieren
[Python] Ich habe versucht, die Top 10 der Lidschatten grafisch darzustellen
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 2 ~
Ich habe versucht, das Problem mit Python Vol.1 zu lösen
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 3 ~
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 4 ~
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 5 ~
Ich habe versucht, die API mit dem Python-Client von echonest zu erreichen
Ich habe versucht, die String-Operationen von Python zusammenzufassen
Ich habe versucht, das Update von "Werde ein Romanautor" mit "IFTTT" und "Werde ein Romanautor API" zu benachrichtigen.
[Python] Ich habe versucht, automatisch einen täglichen Bericht über YWT mit Outlook-Mail zu erstellen
Verwenden Sie die Twitter-API, um die von Twitter benötigte Zeit zu verkürzen (erstellen Sie eine Hervorhebungszeitleiste).
Ich habe versucht, einen Pandas-Datenrahmen zu erstellen, indem ich mit Python Informationen zum Lebensmittelrückruf abgekratzt habe
Ich habe versucht, die Entropie des Bildes mit Python zu finden
Ich habe versucht zu simulieren, wie sich die Infektion mit Python ausbreitet
Ich habe versucht, einen eindimensionalen Zellautomaten in Python zu implementieren
Die erste API, die mit dem Python Djnago REST-Framework erstellt wurde