Heim >Backend-Entwicklung >Python-Tutorial >Erstellen robuster Komponenten mit FastAPI und Pydantic

Erstellen robuster Komponenten mit FastAPI und Pydantic

DDD
DDDOriginal
2024-10-07 16:12:29920Durchsuche

Building Robust Components with FastAPI and Pydantic

Nutzung wohldefinierter Objekte für eine effiziente Datenvalidierung

Objekte dienen als Ein- und Ausstiegspunkte für Komponenten und fungieren als grundlegende Gateways für den Datenfluss. Um robuste, wartbare Komponenten zu erstellen, ist es wichtig, klare, gut strukturierte Felder innerhalb dieser Objekte zu definieren. Dies gewährleistet Datenintegrität und zuverlässige Interaktionen zwischen verschiedenen Systemteilen. Persönlich bevorzuge ich die Verwendung von Python zusammen mit dem FastAPI-Framework für die Entwicklung moderner, leistungsstarker APIs. Für die Datenvalidierung ist Pydantic meine bevorzugte Bibliothek, die sich nahtlos in FastAPI integrieren lässt, um Feldeinschränkungen elegant durchzusetzen und die Konsistenz im gesamten System aufrechtzuerhalten.


from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, EmailStr, Field, ValidationError, conint

# FastAPI instance
app = FastAPI()

# Pydantic model for request body validation
class User(BaseModel):
    name: str = Field(..., min_length=3, max_length=50, description="Name must be between 3 and 50 characters")
    age: conint(gt=0, le=120) = Field(..., description="Age must be between 1 and 120")  # Constrained integer type
    email: EmailStr = Field(..., description="Must be a valid email address")

# API route to handle user data submission
@app.post("/create-user/")
async def create_user(user: User):
    try:
        # If validation passes, this will run
        return {"message": f"User {user.name} created successfully!"}
    except ValidationError as e:
        # Catch and return validation errors
        raise HTTPException(status_code=400, detail=e.errors())

# Sample invalid data
invalid_data = {"name": "A", "age": -5, "email": "invalid_email"}

# Simulate calling the route with invalid data
@app.get("/test-invalid-data/")
async def test_invalid_data():
    try:
        user = User(**invalid_data)  # Validation will fail here
    except ValidationError as e:
        return {"error": e.errors()}

# Run the server using: uvicorn <filename>:app --reload


In diesem Beispiel zeigen wir, wie FastAPI und Pydantic zusammenarbeiten, um die Datenvalidierung effizient durchzuführen. Mithilfe des BaseModel von Pydantic definieren wir Validierungsregeln für eingehende Anforderungsdaten. Beispielsweise verwenden wir EmailStr, um E-Mail-Formate automatisch zu validieren und so den Prozess zu vereinfachen, ohne dass ein benutzerdefinierter Regex erforderlich ist. In ähnlicher Weise verwenden wir conint (einen eingeschränkten Ganzzahltyp), um sicherzustellen, dass das Alter in einen bestimmten Bereich von 1 bis 120 fällt. Dieser Ansatz verbessert die Lesbarkeit und Sicherheit.

Im Beispielcode wird ein Benutzermodell mit Feldern wie Name, Alter und E-Mail definiert, die jeweils ihre Validierungskriterien haben. Wenn ein Benutzer Daten über die Route /create-user/ übermittelt, validiert FastAPI die Eingabe automatisch anhand dieser Regeln. Wenn gültig, wurde der Benutzer erfolgreich erstellt. Wenn nicht, löst FastAPI eine 400 Bad Request mit detaillierten Fehlermeldungen aus. Dadurch wird das Risiko der Verarbeitung falscher oder schädlicher Daten erheblich reduziert, was FastAPI zu einer leistungsstarken Wahl für die sichere API-Entwicklung macht.

Benutzerdefinierte Feld-/Modellvalidierung mit Pydantic

Pydantic v2 führt die Validierung auf Modellebene ein, sodass Sie mithilfe des @model_validator-Dekorators mehrere Felder im Verhältnis zueinander validieren können. Diese Validierung wird nach der Feldvalidierung ausgeführt und ist besonders nützlich, um sicherzustellen, dass bestimmte Bedingungen zwischen Feldern erfüllt sind. Beispielsweise möchten Sie möglicherweise bestätigen, dass ein Startdatum vor einem Enddatum in einem Ereignismodell liegt:


from pydantic import BaseModel, model_validator
from datetime import date

class Event(BaseModel):
    name: str
    start_date: date
    end_date: date

    @model_validator(mode='after')
    def check_dates(cls, values):
        start, end = values.get('start_date'), values.get('end_date')
        if start and end and start >= end:
            raise ValueError('start_date must be before end_date')
        return values


In diesem Beispiel prüft der @model_validator, ob start_date vor end_date liegt. Wenn diese Bedingung nicht erfüllt ist, löst Pydantic einen Validierungsfehler aus. Diese Validierung auf Modellebene ist hilfreich, um sicherzustellen, dass die Beziehungen zwischen mehreren Feldern genau durchgesetzt werden.

Benutzerdefinierte Serialisierung in Pydantic

Pydantic ermöglicht die benutzerdefinierte Serialisierung von Modellfeldern durch Überschreiben der Methoden dict() oder json(). Dies ist nützlich, wenn Sie das Ausgabeformat ändern oder bestimmte Felder während der Serialisierung ausschließen möchten. Sie können auch den @property-Decorator verwenden, um berechnete Felder hinzuzufügen, die in der Serialisierung enthalten sind, aber nicht Teil der Rohdaten des Modells sind.

Hier ist ein Beispiel für eine benutzerdefinierte Serialisierung, die ändert, wie ein vollständiger Name zurückgegeben wird, während das Passwortfeld von der serialisierten Ausgabe ausgeschlossen wird:


from pydantic import BaseModel

class User(BaseModel):
    first_name: str
    last_name: str
    password: str

    # Custom serialization to return the full name
    @property
    def full_name(self):
        return f"{self.first_name} {self.last_name}"

    # Overriding dict() to exclude the password
    def dict(self, **kwargs):
        result = super().dict(**kwargs)
        result['full_name'] = self.full_name  # Add computed field
        result.pop('password', None)  # Remove password from serialization
        return result

# Example usage
user = User(first_name="John", last_name="Doe", password="secret123")
print(user.dict())


In diesem Beispiel ist full_name eine berechnete Eigenschaft, und wir überschreiben die dict()-Methode, um sicherzustellen, dass das Passwort von der Ausgabe ausgeschlossen wird. Eine solche benutzerdefinierte Serialisierung bietet eine detaillierte Kontrolle darüber, wie Modelldaten in APIs oder Antworten verfügbar gemacht werden.

FastAPI und Pydantic-Integration

Pydantic lässt sich nahtlos in FastAPI integrieren und bietet eine automatische Datenvalidierung für Anforderungsnutzlasten, Abfrageparameter und Pfadparameter. Wenn Sie ein Pydantic-Modell in einem FastAPI-Endpunkt definieren, übernimmt FastAPI automatisch das Parsen und Validieren der eingehenden Daten anhand der Modellregeln. Wenn die Daten ungültig sind, gibt FastAPI eine detaillierte 422 Unprocessable Entity-Antwort mit eindeutigen Fehlermeldungen zurück.

Hier ist ein einfaches Beispiel:


from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
    username: str
    age: int

@app.post("/users/")
async def create_user(user: User):
    return {"message": f"User {user.username} created successfully!"}


Wenn in diesem Beispiel eine POST-Anfrage an /users/ gesendet wird, verwendet FastAPI Pydantic, um die eingehenden JSON-Daten zu validieren. Wenn die Daten nicht dem Benutzermodell entsprechen (z. B. fehlender Benutzername oder ungültiges Alter), gibt FastAPI automatisch eine Fehlerantwort zurück, was die Eingabevalidierung und Fehlerbehandlung vereinfacht.

Zusammenfassung

Zusammenfassend lässt sich sagen, dass die Nutzung von Pydantic mit FastAPI Ihre Fähigkeit verbessert, robuste, wartbare Anwendungen zu erstellen, indem die Datenintegrität durch klare Validierungen sichergestellt wird. Diese leistungsstarke Kombination vereinfacht den Entwicklungsprozess und verbessert gleichzeitig die Sicherheit und Zuverlässigkeit, was sie zur bevorzugten Wahl für die Erstellung moderner APIs macht.

Referenzen

Pydantic-Funktionen in FastAPI
Pydantic V2-Plan


Das obige ist der detaillierte Inhalt vonErstellen robuster Komponenten mit FastAPI und Pydantic. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn