Pydantic – chatgpz.de – KI-Tools & Praxiswissen http://chatgpz.de Unabhängige Tests, Anleitungen und Hintergründe zu KI-Tools. Tue, 14 Jul 2026 13:27:11 +0000 de-DE hourly 1 https://wordpress.org/?v=6.4.2 234900186 Pydantic + OpenAI: Der sauberste Weg, strukturierte Ausgaben von LLMs zu erhalten http://chatgpz.de/machine-learning/pydantic-openai-der-sauberste-weg-strukturierte-ausgaben-von-llms-zu-erhalten/ http://chatgpz.de/machine-learning/pydantic-openai-der-sauberste-weg-strukturierte-ausgaben-von-llms-zu-erhalten/#respond Tue, 14 Jul 2026 13:27:10 +0000 https://chatgpz.de/machine-learning/pydantic-openai-der-sauberste-weg-strukturierte-ausgaben-von-llms-zu-erhalten/ [ad_1]

In meinem Neuester Beitrag zu strukturierten Ausgabendie drei Hauptansätze, um maschinenlesbare Antworten von einem LLM zu erhalten. Dies sind der JSON-Modus, Funktionsaufrufe und die strukturierten Ausgaben von OpenAI. Wenn Sie diesen Beitrag noch nicht gelesen haben, lohnt es sich, ihn vor diesem Beitrag kurz zu lesen, da wir direkt darauf aufbauen.

Deshalb gehen wir heute noch einen Schritt weiter und sprechen über etwas, das die Artwork und Weise verändert, wie sich strukturierte Ausgaben in der Praxis anfühlen. Das heißt Pydantisch. Genauer gesagt, während Strukturierte Ausgaben von OpenAI Obwohl die Funktion garantiert, dass das Modell gültiges, schemakonformes JSON zurückgibt, müssen wir auf der Python-Seite noch etwas mit diesem JSON tun. Insbesondere müssen wir es analysieren, die Datentypen validieren, auf die Felder zugreifen, mit unerwarteten Werten umgehen und so weiter. Und hier kommt Pydantic ins Spiel.

Meiner Meinung nach ist die Kombination von Pydantic und OpenAIs Structured Outputs das derzeit sauberste Setup für die Erstellung zuverlässiger LLM-basierter Anwendungen in Python. Am Ende dieses Beitrags werden Sie genau sehen, warum.

Was ist mit Pydantic?

Pydantisch ist eine Python-Bibliothek zur Datenvalidierung mithilfe von Typanmerkungen. Dies bedeutet, dass Sie die Kind und Typen Ihrer Daten als Python-Klasse definieren und dann überprüfen können, ob alle von Ihnen übergebenen Daten tatsächlich dieser Beschreibung entsprechen. Wenn dies nicht der Fall ist, meldet Pydantic einen eindeutigen, beschreibenden Fehler, anstatt zuzulassen, dass sich fehlerhafte Daten stillschweigend durch Ihr System verbreiten.

Hier ist das einfachste mögliche Pydantic-Modell:

from pydantic import BaseModel

class PersonInfo(BaseModel):
    title: str
    age: int
    metropolis: str

Auf diese Weise haben wir jetzt ein Schema, das dies durchsetzt title Und metropolis werden immer eine Zeichenfolge sein, wohingegenage ist immer eine ganze Zahl. Wenn jemand versucht, eine zu erstellen PersonInfo mit age="thirty-two" Pydantic wird es sofort erkennen und uns genau sagen, was schief gelaufen ist.

Aber ist das nicht genau das, was wir bereits mit Funktionsaufrufen und strukturierten Ausgaben gemacht haben? Ja, aber mit einem sehr wichtigen Unterschied.

Einerseits kann das Modell im JSON-Modus oder beim Funktionsaufruf eine Antwort zurückgeben, die dem Schema entspricht, das wir uns vorgestellt haben, oder auch nicht. Selbst wenn das Schema richtig ist, gibt es immer noch eine einfache JSON-Zeichenfolge zurück, sodass wir Felder manuell analysieren, Typen umwandeln und Werte auf der Python-Seite validieren müssen.

Auf der anderen Seite verbessert Structured Outputs dies, indem es dank der eingeschränkten Dekodierung auf Modellebene garantiert, dass der zurückgegebene JSON immer unserem definierten Schema entspricht. Dennoch ist es immer noch nur eine JSON-Zeichenfolge, die wir in Python selbst verwalten müssen.

Mit Pydantic definieren wir unser Schema als Python-Klasse, und die Integration mit der OpenAI-API bedeutet, dass wir zurückkommen ein richtiges Python-Objekt, kein Wörterbuchwobei alle Felder automatisch eingegeben und validiert werden. Das JSON-Schema, das die API benötigt, wird hinter den Kulissen aus unserem Pydantic-Modell generiert. Wir müssen es nie selbst schreiben. Mit anderen Worten, Pydantic ist die Schemadefinitionsschicht, die zwischen unserem Python-Code und der OpenAI-API liegtDadurch wird das gesamte strukturierte Ausgabeerlebnis sauberer, sicherer und wartbarer.

🍨 DataCream ist ein Publication zu KI, Daten und Technologie. Wenn Sie sich für diese Themen interessieren, Abonnieren Sie hier!

Aber sehen wir uns in der Praxis an, was wir durch die Verwendung von Pydantic im Vergleich zur bloßen Verwendung strukturierter Ausgaben gewinnen.

So sah die strukturierte Ausgabe vor der Pydantic-Integration aus:

from openai import OpenAI
import json

consumer = OpenAI(api_key="your_api_key")

# outline schema as a uncooked dictionary
instruments = (
    {
        "kind": "perform",
        "perform": {
            "title": "extract_person_info",
            "strict": True,
            "parameters": {
                "kind": "object",
                "properties": {
                    "title": {"kind": "string"},
                    "age": {"kind": "integer"},
                    "metropolis": {"kind": "string"}
                },
                "required": ("title", "age", "metropolis"),
                "additionalProperties": False
            }
        }
    }
)

response = consumer.chat.completions.create(
    mannequin="gpt-4o-mini",
    instruments=instruments,
    tool_choice={"kind": "perform", "perform": {"title": "extract_person_info"}},
    messages=(
        {"position": "consumer", "content material": "Extract data from: 'Maria is 32 years outdated and lives in Athens.'"}
    )
)

# parse manually — we get again a plain dictionary
end result = json.hundreds(response.decisions(0).message.tool_calls(0).perform.arguments)
print(end result("title"))   # "Maria" — however what if the secret is lacking? KeyError.
print(end result("age"))    # is perhaps "32" as a substitute of 32 — kind not assured

Und hier ist das Gleiche mit Pydantic:

from openai import OpenAI
from pydantic import BaseModel

consumer = OpenAI(api_key="your_api_key")

class PersonInfo(BaseModel):
    title: str
    age: int
    metropolis: str

response = consumer.beta.chat.completions.parse(
    mannequin="gpt-4o-mini",
    messages=(
        {"position": "consumer", "content material": "Extract data from: 'Maria is 32 years outdated and lives in Athens.'"}
    ),
    response_format=PersonInfo
)

# we get again a correct Python object, absolutely typed and validated
end result = response.decisions(0).message.parsed
print(end result.title)   # "Maria" — at all times a string
print(end result.age)    # 32 — at all times an integer, by no means a string
print(end result.metropolis)   # "Athens" — at all times a string

Offensichtlich ist die Pydantic-Model kürzer, lesbarer und sicherer. Beachten Sie, wie wir unser Pydantic-Modell an übergeben response_formatund das OpenAI SDK, das die Generierung des JSON-Schemas übernimmt, führt lediglich den API-Aufruf durch strict: Trueund analysiert die Antwort wieder in eine richtige Antwort PersonInfo Objekt. Auf diese Weise erhalten wir Zugriff auf Felder mit Typsicherheit, Validierung und Punktnotation.

Beachten Sie darüber hinaus auch die .parse() Methode, statt der üblichen .create(). Das liegt daran .parse() ist eine Methode im OpenAI SDK, die speziell für die Arbeit mit Pydantic-Modellen entwickelt wurde und die gesamte strukturierte Ausgabepipeline durchgängig verarbeitet.

Aufbau mit Pydantic

1. verschachtelte Modelle und Hear

Einer der Bereiche, in denen Pydantic wirklich glänzt, sind verschachtelte Datenstrukturen. Das Schreiben eines rohen JSON-Schemas für verschachtelte Objekte ist mühsam, aber bei Verwendung von Pydantic werden nur Python-Klassen definiert:

from pydantic import BaseModel
from typing import Checklist

class Handle(BaseModel):
    road: str
    metropolis: str
    nation: str

class ContactInfo(BaseModel):
    title: str
    electronic mail: str
    handle: Handle
    phone_numbers: Checklist(str)

response = consumer.beta.chat.completions.parse(
    mannequin="gpt-4o-mini",
    messages=(
        {
            "position": "consumer",
            "content material": """Extract contact data from:
            'Maria Mouschoutzi, (electronic mail protected), 
            Ermou 15, Athens, Greece. 
            Telephone: +30 210 1234567, +30 697 8901234'"""
        }
    ),
    response_format=ContactInfo
)

contact = response.decisions(0).message.parsed
print(contact.title)                 # "Maria Mouschoutzi"
print(contact.handle.metropolis)        # "Athens"
print(contact.phone_numbers(0))    # "+30 210 1234567"

Der Handle Das Modell ist darin verschachtelt ContactInfo Natürlich übernimmt Pydantic die vollständige Validierung der verschachtelten Struktur. Wir können dann auf Felder mit sauberer Punktnotation zugreifen, wie zum Beispiel: contact.handle.metropolis statt end result("handle")("metropolis")was erhöhen kann KeyError wenn ein Zwischenschlüssel fehlt. Eine der Aufgaben, bei denen Pydantic wirklich praktisch ist, ist die Notwendigkeit verschachtelter Datenstrukturen.

2. Validierung mit Pydantic-Feld

Eine weitere Aufgabe, bei der Pydantic sehr nützlich ist, ist die Validierung der zurückgegebenen Daten. Diese Validierung umfasst die Prüfung von Datentypen, geht aber auch darüber hinaus, da Pydantic auch die Durchsetzung klarer Anweisungen zum tatsächlichen Inhalt der zurückgegebenen Werte ermöglicht. Genauer gesagt können wir mit explizite Validierungseinschränkungen hinzufügen Subjectund gibt dem Modell Anweisungen darüber, welche Werte akzeptabel sind und welche nicht.

Nehmen wir zum Beispiel an, wir haben ein Setup, das Daten zu Produktbewertungen zurückgibt:

from pydantic import BaseModel, Subject
from typing import Elective

class ProductReview(BaseModel):
    product_name: str = Subject(description="The title of the product being reviewed")
    score: int = Subject(ge=1, le=5, description="Score from 1 to five stars")
    sentiment: str = Subject(description="Considered one of: optimistic, impartial, detrimental")
    abstract: str = Subject(max_length=200, description="A quick abstract of the assessment")
    verified_purchase: Elective(bool) = Subject(default=None, description="Whether or not it is a verified buy")

response = consumer.beta.chat.completions.parse(
    mannequin="gpt-4o-mini",
    messages=(
        {
            "position": "consumer",
            "content material": """Extract a structured assessment from:
            'Completely love this espresso machine! 
            Makes good espresso each time. 
            5 stars, would suggest to anybody.'"""
        }
    ),
    response_format=ProductReview
)

assessment = response.decisions(0).message.parsed
print(assessment.product_name)   # "espresso machine"
print(assessment.score)         # 5
print(assessment.sentiment)      # "optimistic"
print(assessment.abstract)        # "Makes good espresso each time."

Insbesondere die ge=1, le=5 auf der score Das Feld teilt dem Modell mit, dass gültige Bewertungen zwischen 1 und 5 liegen max_length=200 auf der abstract stellt sicher, dass wir nie eine Antwort erhalten, die länger als 200 Zeichen ist.

Darüber hinaus ist die description Felder fungieren als Anweisungen für das Modell und helfen ihm dabei, genau zu verstehen, was jedes Feld enthalten soll. Dies ist im Wesentlichen das Äquivalent von description Felder, die wir manuell in Funktionsaufrufschemata geschrieben haben, um dem Modell zu zeigen, was in die einzelnen Felder eingefügt werden soll.

3. Ablehnungen

Hervorzuheben ist auch die Verwendung .parse()verarbeitet das OpenAI SDK auch Modellablehnungen elegant. Genauer gesagt, für den Fall, dass das Mannequin sich weigert, einer Anfrage nachzukommen (z. B. weil der Inhalt gegen die Richtlinien des Fashions verstößt), wird die parsed Feld wird sein None und die refusal Das Feld enthält den Grund. Dies ermöglicht es uns, auch im Falle einer Ablehnung ein strukturiertes Ergebnis zu erhalten und den Anwendungsbenutzer zumindest über den Grund für die Ablehnung seiner Anfrage zu informieren. Dies ist von besonderer Bedeutung für KI-gestützte Apps, die in der Produktion laufen, wo wir nicht wirklich vorhersagen können, welche seltsamen Wünsche der Benutzer möglicherweise haben wird.

So würde sich additionally eine Modellverweigerung bei Pydantic auswirken:

response = consumer.beta.chat.completions.parse(
    mannequin="gpt-4o-mini",
    messages=({"position": "consumer", "content material": "Extract data from the job posting above."}),
    response_format=JobPosting
)

message = response.decisions(0).message

if message.refusal:
    print(f"Mannequin refused: {message.refusal}")
else:
    job = message.parsed
    print(f"Extracted: {job.job_title} at {job.company_name}")

Ein Beispiel aus der Praxis: Extraktion von Dokumentinformationen

Lassen Sie uns alles anhand eines realistischeren Beispiels zusammenfassen. Stellen Sie sich vor, wir bauen eine Pipeline auf, die Stellenausschreibungen verarbeitet und daraus strukturierte Informationen extrahiert. Dies ist genau die Artwork von Aufgabe, bei der strukturierte Ausgaben glänzen: unstrukturierte Eingaben, klar definierte Ausgabeschemata und ein nachgelagertes System, das das Ergebnis in eine Datenbank einfügen muss.

from pydantic import BaseModel, Subject
from typing import Checklist, Elective
from openai import OpenAI

consumer = OpenAI(api_key="your_api_key")

class SalaryRange(BaseModel):
    min_salary: Elective(int) = Subject(default=None, description="Minimal wage in USD per yr")
    max_salary: Elective(int) = Subject(default=None, description="Most wage in USD per yr")
    forex: str = Subject(default="USD", description="Foreign money code")

class JobPosting(BaseModel):
    job_title: str = Subject(description="The job title or position title")
    company_name: str = Subject(description="The title of the hiring firm")
    location: str = Subject(description="Job location, e.g. 'Athens, Greece' or 'Distant'")
    employment_type: str = Subject(description="Considered one of: full-time, part-time, contract, freelance")
    required_skills: Checklist(str) = Subject(description="Checklist of required technical expertise")
    years_of_experience: Elective(int) = Subject(default=None, description="Minimal years of expertise required")
    wage: Elective(SalaryRange) = Subject(default=None, description="Wage vary if talked about")
    remote_friendly: bool = Subject(description="Whether or not distant work is allowed")

job_post_text = """
Senior Python Engineer at pialgorithms (Athens, Greece / Distant)

We're searching for an skilled Python developer to hitch our AI group.
You'll work on our doc administration platform, constructing clever 
search and extraction options utilizing LLMs and RAG pipelines.

Necessities:
- 5+ years of Python expertise
- Sturdy information of FastAPI, LangChain, and vector databases
- Expertise with OpenAI API and Pydantic
- Familiarity with Docker and cloud deployment (AWS/GCP)

Wage: €60,000 - €85,000 per yr
Full-time place. Distant-friendly.
"""

response = consumer.beta.chat.completions.parse(
    mannequin="gpt-4o-mini",
    messages=(
        {
            "position": "system",
            "content material": "You're an knowledgeable at extracting structured data from job postings."
        },
        {
            "position": "consumer",
            "content material": f"Extract all related data from this job posting:nn{job_post_text}"
        }
    ),
    response_format=JobPosting
)

job = response.decisions(0).message.parsed

print(f"Title: {job.job_title}")
print(f"Firm: {job.company_name}")
print(f"Location: {job.location}")
print(f"Distant: {job.remote_friendly}")
print(f"Expertise: {', '.be a part of(job.required_skills)}")
print(f"Expertise: {job.years_of_experience} years")
if job.wage:
    print(f"Wage: {job.wage.min_salary} - {job.wage.max_salary} {job.wage.forex}")

Und die Ausgabe sieht in etwa so aus:

Title: Senior Python Engineer
Firm: pialgorithms
Location: Athens, Greece / Distant
Distant: True
Expertise: Python, FastAPI, LangChain, vector databases, OpenAI API, Pydantic, Docker, AWS, GCP
Expertise: 5 years
Wage: 60000 - 85000 EUR

Dies ist ein produktionsbereiter Extraktionscode. Das Verschachtelte SalaryRange Das Modell verarbeitet die optionalen Gehaltsinformationen sauber. Elective Felder sind standardmäßig auf None wenn Informationen fehlen, und jedes Feld in der Antwort wird automatisch eingegeben und validiert. Das Ergebnis kann ohne zusätzliche Verarbeitung direkt in eine Datenbank eingefügt oder an den nächsten Schritt in einer Pipeline übergeben werden.

In meinen Gedanken

Was mich an der Kombination aus Pydantic und OpenAI am meisten erfreut, ist, wie intestine sie mit der Denkweise eines Python-Entwicklers übereinstimmt. Es definiert Datenstrukturen als Klassen, verwendet Typhinweise und erkennt Typfehler frühzeitig und deutlich. All dies sind traditionell die unvorhersehbarsten Teile jeder KI-Anwendung, vor allem weil wir all dies manuell auf der Python-Seite der KI-App erledigen mussten. Pydantic fungiert als bessere und robustere Verbindung zwischen dem KI-Modell und dem Relaxation unseres Python-Codes.

✨ Danke fürs Lesen! ✨


Wenn du es bis hierher geschafft hast, Vielleicht finden Sie Pialgorithmen nützlich: eine von uns entwickelte Plattform, die Groups dabei hilft, organisatorisches Wissen sicher an einem Ort zu verwalten.


Hat Ihnen dieser Beitrag gefallen? Begleiten Sie mich auf 💌 Unterstapel und 💼 LinkedIn


Alle Bilder vom Autor, sofern nicht anders angegeben.

[ad_2]

]]>
http://chatgpz.de/machine-learning/pydantic-openai-der-sauberste-weg-strukturierte-ausgaben-von-llms-zu-erhalten/feed/ 0 19960
So entwerfen Sie Mock-Knowledge-Pipelines in Produktionsqualität mithilfe von Polyfactory mit Datenklassen, Pydantic, Attrs und verschachtelten Modellen http://chatgpz.de/artificial-intelligence/so-entwerfen-sie-mock-knowledge-pipelines-in-produktionsqualitaet-mithilfe-von-polyfactory-mit-datenklassen-pydantic-attrs-und-verschachtelten-modellen/ http://chatgpz.de/artificial-intelligence/so-entwerfen-sie-mock-knowledge-pipelines-in-produktionsqualitaet-mithilfe-von-polyfactory-mit-datenklassen-pydantic-attrs-und-verschachtelten-modellen/#respond Sun, 08 Feb 2026 11:36:56 +0000 http://chatgpz.de/artificial-intelligence/so-entwerfen-sie-mock-data-pipelines-in-produktionsqualitaet-mithilfe-von-polyfactory-mit-datenklassen-pydantic-attrs-und-verschachtelten-modellen/ [ad_1]

In diesem Tutorial führen wir eine umfassende, umfassende Erkundung von durch Polyfabrikwobei der Schwerpunkt darauf liegt, wie wir direkt aus Python-Typhinweisen umfangreiche, realistische Scheindaten generieren können. Wir beginnen mit der Einrichtung der Umgebung und bauen nach und nach Fabriken für Datenklassen, Pydantic-Modelle und attrs-basierte Klassen auf, während wir Anpassungen, Überschreibungen, berechnete Felder und die Generierung verschachtelter Objekte demonstrieren. Während wir uns durch jedes Snippet bewegen, zeigen wir, wie wir Zufälligkeiten kontrollieren, Einschränkungen erzwingen und reale Strukturen modellieren können, sodass dieses Tutorial direkt auf Check-, Prototyping- und datengesteuerte Entwicklungsworkflows anwendbar ist. Schauen Sie sich das an VOLLSTÄNDIGE CODES hier.

import subprocess
import sys


def install_package(package deal):
   subprocess.check_call((sys.executable, "-m", "pip", "set up", "-q", package deal))


packages = (
   "polyfactory",
   "pydantic",
   "email-validator",
   "faker",
   "msgspec",
   "attrs"
)


for package deal in packages:
   strive:
       install_package(package deal)
       print(f"✓ Put in {package deal}")
   besides Exception as e:
       print(f"✗ Failed to put in {package deal}: {e}")


print("n")


print("=" * 80)
print("SECTION 2: Fundamental Dataclass Factories")
print("=" * 80)


from dataclasses import dataclass
from typing import Listing, Optionally available
from datetime import datetime, date
from uuid import UUID
from polyfactory.factories import DataclassFactory


@dataclass
class Tackle:
   avenue: str
   metropolis: str
   nation: str
   zip_code: str


@dataclass
class Particular person:
   id: UUID
   identify: str
   electronic mail: str
   age: int
   birth_date: date
   is_active: bool
   tackle: Tackle
   phone_numbers: Listing(str)
   bio: Optionally available(str) = None


class PersonFactory(DataclassFactory(Particular person)):
   move


individual = PersonFactory.construct()
print(f"Generated Particular person:")
print(f"  ID: {individual.id}")
print(f"  Title: {individual.identify}")
print(f"  Electronic mail: {individual.electronic mail}")
print(f"  Age: {individual.age}")
print(f"  Tackle: {individual.tackle.metropolis}, {individual.tackle.nation}")
print(f"  Cellphone Numbers: {individual.phone_numbers(:2)}")
print()


individuals = PersonFactory.batch(5)
print(f"Generated {len(individuals)} individuals:")
for i, p in enumerate(individuals, 1):
   print(f"  {i}. {p.identify} - {p.electronic mail}")
print("n")

Wir richten die Umgebung ein und stellen sicher, dass alle erforderlichen Abhängigkeiten installiert sind. Wir stellen auch die Kernidee der Verwendung von Polyfactory zum Generieren von Scheindaten aus Typhinweisen vor. Durch die Initialisierung der grundlegenden Datenklassenfabriken legen wir die Grundlage für alle nachfolgenden Beispiele.

print("=" * 80)
print("SECTION 3: Customizing Manufacturing unit Habits")
print("=" * 80)


from faker import Faker
from polyfactory.fields import Use, Ignore


@dataclass
class Worker:
   employee_id: str
   full_name: str
   division: str
   wage: float
   hire_date: date
   is_manager: bool
   electronic mail: str
   internal_notes: Optionally available(str) = None


class EmployeeFactory(DataclassFactory(Worker)):
   __faker__ = Faker(locale="en_US")
   __random_seed__ = 42


   @classmethod
   def employee_id(cls) -> str:
       return f"EMP-{cls.__random__.randint(10000, 99999)}"


   @classmethod
   def full_name(cls) -> str:
       return cls.__faker__.identify()


   @classmethod
   def division(cls) -> str:
       departments = ("Engineering", "Advertising", "Gross sales", "HR", "Finance")
       return cls.__random__.alternative(departments)


   @classmethod
   def wage(cls) -> float:
       return spherical(cls.__random__.uniform(50000, 150000), 2)


   @classmethod
   def electronic mail(cls) -> str:
       return cls.__faker__.company_email()


workers = EmployeeFactory.batch(3)
print("Generated Staff:")
for emp in workers:
   print(f"  {emp.employee_id}: {emp.full_name}")
   print(f"    Division: {emp.division}")
   print(f"    Wage: ${emp.wage:,.2f}")
   print(f"    Electronic mail: {emp.electronic mail}")
   print()
print()


print("=" * 80)
print("SECTION 4: Subject Constraints and Calculated Fields")
print("=" * 80)


@dataclass
class Product:
   product_id: str
   identify: str
   description: str
   worth: float
   discount_percentage: float
   stock_quantity: int
   final_price: Optionally available(float) = None
   sku: Optionally available(str) = None


class ProductFactory(DataclassFactory(Product)):
   @classmethod
   def product_id(cls) -> str:
       return f"PROD-{cls.__random__.randint(1000, 9999)}"


   @classmethod
   def identify(cls) -> str:
       adjectives = ("Premium", "Deluxe", "Traditional", "Fashionable", "Eco")
       nouns = ("Widget", "Gadget", "Gadget", "Software", "Equipment")
       return f"{cls.__random__.alternative(adjectives)} {cls.__random__.alternative(nouns)}"


   @classmethod
   def worth(cls) -> float:
       return spherical(cls.__random__.uniform(10.0, 1000.0), 2)


   @classmethod
   def discount_percentage(cls) -> float:
       return spherical(cls.__random__.uniform(0, 30), 2)


   @classmethod
   def stock_quantity(cls) -> int:
       return cls.__random__.randint(0, 500)


   @classmethod
   def construct(cls, **kwargs):
       occasion = tremendous().construct(**kwargs)
       if occasion.final_price is None:
           occasion.final_price = spherical(
               occasion.worth * (1 - occasion.discount_percentage / 100), 2
           )
       if occasion.sku is None:
           name_part = occasion.identify.substitute(" ", "-").higher()(:10)
           occasion.sku = f"{occasion.product_id}-{name_part}"
       return occasion


merchandise = ProductFactory.batch(3)
print("Generated Merchandise:")
for prod in merchandise:
   print(f"  {prod.sku}")
   print(f"    Title: {prod.identify}")
   print(f"    Worth: ${prod.worth:.2f}")
   print(f"    Low cost: {prod.discount_percentage}%")
   print(f"    Last Worth: ${prod.final_price:.2f}")
   print(f"    Inventory: {prod.stock_quantity} models")
   print()
print()

Wir konzentrieren uns auf die Generierung einfacher, aber realistischer Scheindaten mithilfe von Datenklassen und dem Standardverhalten von Polyfactory. Wir zeigen, wie Sie schnell einzelne Instanzen und Batches erstellen, ohne eine benutzerdefinierte Logik zu schreiben. Es hilft uns zu validieren, wie Polyfactory Typhinweise automatisch interpretiert, um verschachtelte Strukturen zu füllen.

print("=" * 80)
print("SECTION 6: Complicated Nested Buildings")
print("=" * 80)


from enum import Enum


class OrderStatus(str, Enum):
   PENDING = "pending"
   PROCESSING = "processing"
   SHIPPED = "shipped"
   DELIVERED = "delivered"
   CANCELLED = "cancelled"


@dataclass
class OrderItem:
   product_name: str
   amount: int
   unit_price: float
   total_price: Optionally available(float) = None


@dataclass
class ShippingInfo:
   service: str
   tracking_number: str
   estimated_delivery: date


@dataclass
class Order:
   order_id: str
   customer_name: str
   customer_email: str
   standing: OrderStatus
   gadgets: Listing(OrderItem)
   order_date: datetime
   shipping_info: Optionally available(ShippingInfo) = None
   total_amount: Optionally available(float) = None
   notes: Optionally available(str) = None


class OrderItemFactory(DataclassFactory(OrderItem)):
   @classmethod
   def product_name(cls) -> str:
       merchandise = ("Laptop computer", "Mouse", "Keyboard", "Monitor", "Headphones",
                  "Webcam", "USB Cable", "Cellphone Case", "Charger", "Pill")
       return cls.__random__.alternative(merchandise)


   @classmethod
   def amount(cls) -> int:
       return cls.__random__.randint(1, 5)


   @classmethod
   def unit_price(cls) -> float:
       return spherical(cls.__random__.uniform(5.0, 500.0), 2)


   @classmethod
   def construct(cls, **kwargs):
       occasion = tremendous().construct(**kwargs)
       if occasion.total_price is None:
           occasion.total_price = spherical(occasion.amount * occasion.unit_price, 2)
       return occasion


class ShippingInfoFactory(DataclassFactory(ShippingInfo)):
   @classmethod
   def service(cls) -> str:
       carriers = ("FedEx", "UPS", "DHL", "USPS")
       return cls.__random__.alternative(carriers)


   @classmethod
   def tracking_number(cls) -> str:
       return ''.be part of(cls.__random__.decisions('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', ok=12))


class OrderFactory(DataclassFactory(Order)):
   @classmethod
   def order_id(cls) -> str:
       return f"ORD-{datetime.now().12 months}-{cls.__random__.randint(100000, 999999)}"


   @classmethod
   def gadgets(cls) -> Listing(OrderItem):
       return OrderItemFactory.batch(cls.__random__.randint(1, 5))


   @classmethod
   def construct(cls, **kwargs):
       occasion = tremendous().construct(**kwargs)
       if occasion.total_amount is None:
           occasion.total_amount = spherical(sum(merchandise.total_price for merchandise in occasion.gadgets), 2)
       if occasion.shipping_info is None and occasion.standing in (OrderStatus.SHIPPED, OrderStatus.DELIVERED):
           occasion.shipping_info = ShippingInfoFactory.construct()
       return occasion


orders = OrderFactory.batch(2)
print("Generated Orders:")
for order in orders:
   print(f"n  Order {order.order_id}")
   print(f"    Buyer: {order.customer_name} ({order.customer_email})")
   print(f"    Standing: {order.standing.worth}")
   print(f"    Objects ({len(order.gadgets)}):")
   for merchandise so as.gadgets:
       print(f"      - {merchandise.amount}x {merchandise.product_name} @ ${merchandise.unit_price:.2f} = ${merchandise.total_price:.2f}")
   print(f"    Complete: ${order.total_amount:.2f}")
   if order.shipping_info:
       print(f"    Transport: {order.shipping_info.service} - {order.shipping_info.tracking_number}")
print("n")

Wir bauen eine komplexere Domänenlogik auf, indem wir berechnete und abhängige Felder in Fabriken einführen. Wir zeigen, wie wir nach der Objekterstellung Werte wie Endpreise, Gesamtsummen und Versanddetails ableiten können. Dadurch können wir realistische Geschäftsregeln direkt in unseren Testdatengeneratoren modellieren.

print("=" * 80)
print("SECTION 7: Attrs Integration")
print("=" * 80)


import attrs
from polyfactory.factories.attrs_factory import AttrsFactory


@attrs.outline
class BlogPost:
   title: str
   creator: str
   content material: str
   views: int = 0
   likes: int = 0
   printed: bool = False
   published_at: Optionally available(datetime) = None
   tags: Listing(str) = attrs.subject(manufacturing unit=listing)


class BlogPostFactory(AttrsFactory(BlogPost)):
   @classmethod
   def title(cls) -> str:
       templates = (
           "10 Ideas for {}",
           "Understanding {}",
           "The Full Information to {}",
           "Why {} Issues",
           "Getting Began with {}"
       )
       subjects = ("Python", "Knowledge Science", "Machine Studying", "Internet Improvement", "DevOps")
       template = cls.__random__.alternative(templates)
       subject = cls.__random__.alternative(subjects)
       return template.format(subject)


   @classmethod
   def content material(cls) -> str:
       return " ".be part of(Faker().sentences(nb=cls.__random__.randint(3, 8)))


   @classmethod
   def views(cls) -> int:
       return cls.__random__.randint(0, 10000)


   @classmethod
   def likes(cls) -> int:
       return cls.__random__.randint(0, 1000)


   @classmethod
   def tags(cls) -> Listing(str):
       all_tags = ("python", "tutorial", "newbie", "superior", "information",
                  "suggestions", "best-practices", "2024")
       return cls.__random__.pattern(all_tags, ok=cls.__random__.randint(2, 5))


posts = BlogPostFactory.batch(3)
print("Generated Weblog Posts:")
for publish in posts:
   print(f"n  '{publish.title}'")
   print(f"    Writer: {publish.creator}")
   print(f"    Views: {publish.views:,} | Likes: {publish.likes:,}")
   print(f"    Printed: {publish.printed}")
   print(f"    Tags: {', '.be part of(publish.tags)}")
   print(f"    Preview: {publish.content material(:100)}...")
print("n")


print("=" * 80)
print("SECTION 8: Constructing with Particular Overrides")
print("=" * 80)


custom_person = PersonFactory.construct(
   identify="Alice Johnson",
   age=30,
   electronic mail="(electronic mail protected)"
)
print(f"Customized Particular person:")
print(f"  Title: {custom_person.identify}")
print(f"  Age: {custom_person.age}")
print(f"  Electronic mail: {custom_person.electronic mail}")
print(f"  ID (auto-generated): {custom_person.id}")
print()


vip_customers = PersonFactory.batch(
   3,
   bio="VIP Buyer"
)
print("VIP Prospects:")
for buyer in vip_customers:
   print(f"  {buyer.identify}: {buyer.bio}")
print("n")

Wir erweitern die Polyfactory-Nutzung auf validierte Pydantic-Modelle und attrs-basierte Klassen. Wir zeigen, wie wir Feldeinschränkungen, Validatoren und Standardverhalten respektieren und gleichzeitig gültige Daten im großen Maßstab generieren können. Es stellt sicher, dass unsere Scheindaten mit echten Anwendungsschemata kompatibel bleiben.

print("=" * 80)
print("SECTION 9: Subject-Stage Management with Use and Ignore")
print("=" * 80)


from polyfactory.fields import Use, Ignore


@dataclass
class Configuration:
   app_name: str
   model: str
   debug: bool
   created_at: datetime
   api_key: str
   secret_key: str


class ConfigFactory(DataclassFactory(Configuration)):
   app_name = Use(lambda: "MyAwesomeApp")
   model = Use(lambda: "1.0.0")
   debug = Use(lambda: False)


   @classmethod
   def api_key(cls) -> str:
       return f"api_key_{''.be part of(cls.__random__.decisions('0123456789abcdef', ok=32))}"


   @classmethod
   def secret_key(cls) -> str:
       return f"secret_{''.be part of(cls.__random__.decisions('0123456789abcdef', ok=64))}"


configs = ConfigFactory.batch(2)
print("Generated Configurations:")
for config in configs:
   print(f"  App: {config.app_name} v{config.model}")
   print(f"    Debug: {config.debug}")
   print(f"    API Key: {config.api_key(:20)}...")
   print(f"    Created: {config.created_at}")
   print()
print()


print("=" * 80)
print("SECTION 10: Mannequin Protection Testing")
print("=" * 80)


from pydantic import BaseModel, ConfigDict
from typing import Union


class PaymentMethod(BaseModel):
   model_config = ConfigDict(use_enum_values=True)
   kind: str
   card_number: Optionally available(str) = None
   bank_name: Optionally available(str) = None
   verified: bool = False


class PaymentMethodFactory(ModelFactory(PaymentMethod)):
   __model__ = PaymentMethod


payment_methods = (
   PaymentMethodFactory.construct(kind="card", card_number="4111111111111111"),
   PaymentMethodFactory.construct(kind="financial institution", bank_name="Chase Financial institution"),
   PaymentMethodFactory.construct(verified=True),
)


print("Fee Technique Protection:")
for i, pm in enumerate(payment_methods, 1):
   print(f"  {i}. Sort: {pm.kind}")
   if pm.card_number:
       print(f"     Card: {pm.card_number}")
   if pm.bank_name:
       print(f"     Financial institution: {pm.bank_name}")
   print(f"     Verified: {pm.verified}")
print("n")


print("=" * 80)
print("TUTORIAL SUMMARY")
print("=" * 80)
print("""
This tutorial lined:


1. ✓ Fundamental Dataclass Factories - Easy mock information technology
2. ✓ Customized Subject Mills - Controlling particular person subject values
3. ✓ Subject Constraints - Utilizing PostGenerated for calculated fields
4. ✓ Pydantic Integration - Working with validated fashions
5. ✓ Complicated Nested Buildings - Constructing associated objects
6. ✓ Attrs Help - Different to dataclasses
7. ✓ Construct Overrides - Customizing particular situations
8. ✓ Use and Ignore - Specific subject management
9. ✓ Protection Testing - Making certain complete check information


Key Takeaways:
- Polyfactory mechanically generates mock information from kind hints
- Customise technology with classmethods and interior decorators
- Helps a number of libraries: dataclasses, Pydantic, attrs, msgspec
- Use PostGenerated for calculated/dependent fields
- Override particular values whereas preserving others random
- Excellent for testing, improvement, and prototyping


For extra info:
- Documentation: https://polyfactory.litestar.dev/
- GitHub: https://github.com/litestar-org/polyfactory
""")
print("=" * 80)

Wir decken erweiterte Nutzungsmuster wie explizite Überschreibungen, konstante Feldwerte und Abdeckungstestszenarien ab. Wir zeigen, wie wir gezielt Randfälle und Varianteninstanzen für robuste Checks konstruieren können. Dieser letzte Schritt verbindet alles miteinander, indem er zeigt, wie Polyfactory umfassende und produktionstaugliche Testdatenstrategien unterstützt.

Abschließend haben wir gezeigt, wie Polyfactory es uns ermöglicht, umfassende, versatile Testdaten mit minimalem Boilerplate zu erstellen und dabei dennoch die detaillierte Kontrolle über jedes Feld zu behalten. Wir haben gezeigt, wie man mit einfachen Entitäten, komplexen verschachtelten Strukturen und Pydantic-Modellvalidierung sowie expliziten Feldüberschreibungen innerhalb eines einzigen, konsistenten, fabrikbasierten Ansatzes umgeht. Insgesamt haben wir festgestellt, dass wir mit Polyfactory schneller vorankommen und sicherer testen können, da es zuverlässig realistische Datensätze generiert, die produktionsähnliche Szenarien genau widerspiegeln, ohne dass die Klarheit oder Wartbarkeit darunter leidet.


Schauen Sie sich das an VOLLSTÄNDIGE CODES hier. Sie können uns auch gerne weiter folgen Twitter und vergessen Sie nicht, bei uns mitzumachen 100.000+ ML SubReddit und Abonnieren Unser E-newsletter. Warten! Bist du im Telegram? Jetzt können Sie uns auch per Telegram kontaktieren.


[ad_2]

]]>
http://chatgpz.de/artificial-intelligence/so-entwerfen-sie-mock-knowledge-pipelines-in-produktionsqualitaet-mithilfe-von-polyfactory-mit-datenklassen-pydantic-attrs-und-verschachtelten-modellen/feed/ 0 16156
Verwalten Sie Umgebungsvariablen mit Pydantic http://chatgpz.de/machine-learning/verwalten-sie-umgebungsvariablen-mit-pydantic/ http://chatgpz.de/machine-learning/verwalten-sie-umgebungsvariablen-mit-pydantic/#respond Wed, 12 Feb 2025 20:30:10 +0000 http://chatgpz.de/machine-learning/verwalten-sie-umgebungsvariablen-mit-pydantic/

Einführung

Entwickler arbeiten an Anwendungen, die auf einem Server bereitgestellt werden sollen, damit jeder diese verwenden kann. In der Regel richten Entwickler in der Maschine, in der diese Apps leben, Umgebungsvariablen ein, die es der App ermöglichen, auszuführen. Diese Variablen können API -Schlüssel von externen Diensten, URL Ihrer Datenbank und vielem mehr sein.

Für die lokale Entwicklung ist es jedoch wirklich unpraktisch, diese Variablen auf der Maschine zu deklarieren, da es sich um einen langsamen und chaotischen Prozess handelt. Ich möchte additionally dieses kurze Tutorial wie man verwenden Pydantisch Um Umgebungsvariablen auf sichere Weise zu bewältigen.

.Env -Datei

Was Sie häufig in einem tun Python Projekt besteht darin, alle Ihre Umgebungsvariablen in einer Datei mit dem Namen .Env zu speichern. Dies ist eine Textdatei, die alle Variablen in a enthält key : worth Format. Sie können auch den Wert einer der Variablen verwenden, um eine der anderen Variablen zu deklarieren, indem Sie die nutzen {} Syntax.

Das Folgende ist ein Beispiel:

#.env file

OPENAI_API_KEY="sk-your non-public key"
OPENAI_MODEL_ID="gpt-4o-mini"

# Improvement settings
DOMAIN=instance.org
ADMIN_EMAIL=admin@${DOMAIN}

WANDB_API_KEY="your-private-key"
WANDB_PROJECT="myproject"
WANDB_ENTITY="my-entity"

SERPAPI_KEY= "your-api-key"
PERPLEXITY_TOKEN = "your-api-token"

Beachten Sie, dass die Datei .Env privat bleiben sollte. Daher ist es wichtig, dass diese Datei in Ihrem erwähnt wird .Gitignore Datei, um sicherzugehen, dass Sie Schieben Sie es niemals auf GithubAndernfalls könnten andere Entwickler Ihre Schlüssel stehlen und die Instruments verwenden, für die Sie bezahlt haben.

env.instance -Datei

Um das Leben von Entwicklern zu erleichtern, die Ihr Repository klonen, können Sie eine Env. -Beispieldatei in Ihr Projekt aufnehmen. Dies ist eine Datei, die nur die Schlüssel dessen enthält, was in die .Env -Datei gehen soll. Auf diese Weise wissen andere Menschen, welche APIs, Token oder Geheimnisse im Allgemeinen festlegen müssen, damit die Skripte funktionieren.

#env.instance

OPENAI_API_KEY=""
OPENAI_MODEL_ID=""

DOMAIN=""
ADMIN_EMAIL=""

WANDB_API_KEY=""
WANDB_PROJECT=""
WANDB_ENTITY=""

SERPAPI_KEY= ""
PERPLEXITY_TOKEN = ""

Python-dotenv ist die Bibliothek, mit der Sie die in die .Env-Datei deklarierten Variablen laden. So installieren Sie diese Bibliothek:

pip set up python-dotenv

Jetzt können Sie mit dem Load_Dotenv die Variablen laden. Erhalten Sie dann einen Verweis auf diese Variablen mit dem Betriebssystemmodul.

import os
from dotenv import load_dotenv

load_dotenv()

OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
OPENAI_MODEL_ID = os.getenv('OPENAI_MODEL_ID')

Diese Methode untersucht zunächst in Ihre .EnV -Datei, um die von Ihnen dort deklarierten Variablen zu laden. Wenn diese Datei nicht vorhanden ist, wird die Variable aus dem Host -Laptop entnommen. Dies bedeutet, dass Sie die .Env -Datei für Ihre lokale Entwicklung verwenden können. Wenn der Code dann in einer Hostumgebung wie einem virtuellen Laptop oder einem Docker -Container bereitgestellt wird, werden wir die in der Hostumgebung definierten Umgebungsvariablen direkt verwenden.

Pydantisch

Pydantic ist eine der am häufigsten verwendeten Bibliotheken in Python zur Datenvalidierung. Es wird auch zum Serialisieren und Deserialisieren von Klassen in JSON und Rücken verwendet. Es generiert automatisch ein JSON -Schema und verringert die Notwendigkeit des manuellen Schemasmanagements. Es bietet auch eine integrierte Datenvalidierung, um sicherzustellen, dass die serialisierten Daten das erwartete Format anhalten. Zuletzt integriert es sich leicht in beliebte Webrahmen wie Fastapi.

Pydantic-Settings ist eine pydantische Funktion, die zum Laden und Validieren von Einstellungen oder Konfigurationsklassen aus Umgebungsvariablen erforderlich ist.

!pip set up pydantic-settings

Wir werden eine Klasse namens erstellen Settings. Diese Klasse wird erben BaseSettings. Dies macht das Standardverhalten der Bestimmung der Werte aller Felder aus der .Env -Datei. Wenn in der .Env -Datei kein VAR gefunden wird, wird der Standardwert verwendet, falls angegeben.

from pydantic_settings import BaseSettings, SettingsConfigDict

from pydantic import (
    AliasChoices,
    Area,
    RedisDsn,
)


class Settings(BaseSettings):
    auth_key: str = Area(validation_alias="my_auth_key")  
    api_key: str = Area(alias="my_api_key")  

    redis_dsn: RedisDsn = Area(
        'redis://consumer:cross@localhost:6379/1', #default worth
        validation_alias=AliasChoices('service_redis_dsn', 'redis_url'),  
    )

    model_config = SettingsConfigDict(env_prefix='my_prefix_')

Im Settings Klasse oben haben wir mehrere Felder definiert. Der Area Klasse wird verwendet, um bereitzustellen zusätzliche Informationen über ein Attribut.

In unserem Fall haben wir a eingerichtet validation_alias. Der in der .Env -Datei zu suchen, nach dem variablen Namen zu suchen, wird additionally überschrieben. In dem oben angegebenen Fall die Umgebungsvariable my_auth_key wird gelesen anstelle von auth_key.

Sie können auch mehrere Aliase haben AliasChoises(choise1, choise2).

Das letzte Attribut model_config enthält alle Variablen zu einem bestimmten Thema (z. B. Verbindung zu einem DB). Und diese Variable speichert alle .Env var, die mit dem Präfix beginnen env_prefix.

Einstellungen instanziieren und verwenden

Der nächste Schritt wäre, diese Einstellungen in Ihrem Python -Projekt tatsächlich zu instanziieren und zu verwenden.

from pydantic_settings import BaseSettings, SettingsConfigDict

from pydantic import (
    AliasChoices,
    Area,
    RedisDsn,
)


class Settings(BaseSettings):
    auth_key: str = Area(validation_alias="my_auth_key")  
    api_key: str = Area(alias="my_api_key")  

    redis_dsn: RedisDsn = Area(
        'redis://consumer:cross@localhost:6379/1', #default worth
        validation_alias=AliasChoices('service_redis_dsn', 'redis_url'),  
    )

    model_config = SettingsConfigDict(env_prefix='my_prefix_')

# create instantly a settings object
settings = Settings()

Was verwenden nun die Einstellungen in anderen Teilen unserer Codebasis?

from Settings import settings

print(settings.auth_key) 

Sie haben endlich einen einfachen Zugriff auf Ihre Einstellungen, und Pydantic hilft Ihnen, zu bestätigen, dass die Geheimnisse das richtige Format haben. Für fortgeschrittene Validierungs -Tipps finden Sie in der pydantischen Dokumentation: https://docs.pydantic.dev/newest/

Letzte Gedanken

Die Verwaltung der Konfiguration eines Projekts ist ein langweiliger, aber wichtiger Bestandteil der Softwareentwicklung. Geheimnisse wie API -Tasten, DB -Verbindungen führen normalerweise Ihre Anwendung mit. Naiv können Sie diese Variablen in Ihrem Code harten und es funktioniert weiterhin, aber aus offensichtlichen Gründen könnte dies keine gute Praxis sein. In diesem Artikel habe ich Ihnen eine Einführung gezeigt, wie Sie pydantische Einstellungen verwenden, um eine strukturierte und sichere Möglichkeit zu erhalten, Ihre Konfigurationen zu bewältigen.

💼 LinkedIn | 🐦 X (Twitter) | 💻 Webseite


[ad_2]]]>
http://chatgpz.de/machine-learning/verwalten-sie-umgebungsvariablen-mit-pydantic/feed/ 0 7181
Utilized Python Chronicles: Eine sanfte Einführung in Pydantic | von Ilija Lazarevic | Jul, 2024 http://chatgpz.de/artificial-intelligence/utilized-python-chronicles-eine-sanfte-einfuehrung-in-pydantic-von-ilija-lazarevic-jul-2024/ http://chatgpz.de/artificial-intelligence/utilized-python-chronicles-eine-sanfte-einfuehrung-in-pydantic-von-ilija-lazarevic-jul-2024/#respond Fri, 26 Jul 2024 09:56:09 +0000 https://chatgpz.de/artificial-intelligence/applied-python-chronicles-eine-sanfte-einfuehrung-in-pydantic-von-ilija-lazarevic-jul-2024/ [ad_1]

Was ist mit Standardwerten und Argumentextraktionen?

from pydantic import validate_call

@validate_call(validate_return=True)
def add(*args: int, a: int, b: int = 4) -> int:
return str(sum(args) + a + b)

# ----
add(4,3,4)
> ValidationError: 1 validation error for add
a
Lacking required key phrase solely argument (kind=missing_keyword_only_argument, input_value=ArgsKwargs((4, 3, 4)), input_type=ArgsKwargs)
For additional data go to <https://errors.pydantic.dev/2.5/v/missing_keyword_only_argument>

# ----

add(4, 3, 4, a=3)
> 18

# ----

@validate_call
def add(*args: int, a: int, b: int = 4) -> int:
return str(sum(args) + a + b)

# ----

add(4, 3, 4, a=3)
> '18'

Erkenntnisse aus diesem Beispiel:

  • Sie können den Typ der variablen Anzahl von Argumentendeklarationen kommentieren (*args).
  • Standardwerte sind weiterhin eine Choice, auch wenn Sie variable Datentypen kommentieren.
  • validate_call akzeptiert validate_return Argument, das auch die Validierung des Funktionsrückgabewerts vornimmt. In diesem Fall wird auch eine Datentypkonvertierung angewendet. validate_return ist eingestellt auf False standardmäßig. Wenn es so belassen wird, gibt die Funktion möglicherweise nicht das zurück, was in den Typhinweisen deklariert ist.

Was ist, wenn Sie den Datentyp validieren, aber auch die Werte einschränken möchten, die die Variable annehmen kann? Beispiel:

from pydantic import validate_call, Subject
from typing import Annotated

type_age = Annotated(int, Subject(lt=120))

@validate_call(validate_return=True)
def add(age_one: int, age_two: type_age) -> int:
return age_one + age_two

add(3, 300)
> ValidationError: 1 validation error for add
1
Enter ought to be lower than 120 (kind=less_than, input_value=200, input_type=int)
For additional data go to <https://errors.pydantic.dev/2.5/v/less_than>

Dieses Beispiel zeigt:

  • Sie können Annotated Und pydantic.Subject um nicht nur den Datentyp zu validieren, sondern auch Metadaten hinzuzufügen, die Pydantic verwendet, um variable Werte und Formate einzuschränken.
  • ValidationError ist wieder einmal sehr ausführlich darüber, was mit unserem Funktionsaufruf nicht stimmte. Das kann wirklich hilfreich sein.

Hier ist ein weiteres Beispiel, wie Sie Variablenwerte sowohl validieren als auch einschränken können. Wir simulieren eine Nutzlast (ein Wörterbuch), die Sie in Ihrer Funktion verarbeiten möchten, nachdem sie validiert wurde:

from pydantic import HttpUrl, PastDate
from pydantic import Subject
from pydantic import validate_call
from typing import Annotated

Identify = Annotated(str, Subject(min_length=2, max_length=15))

@validate_call(validate_return=True)
def process_payload(url: HttpUrl, identify: Identify, birth_date: PastDate) -> str:
return f'{identify=}, {birth_date=}'

# ----

payload = {
'url': 'httpss://instance.com',
'identify': 'J',
'birth_date': '2024-12-12'
}

process_payload(**payload)
> ValidationError: 3 validation errors for process_payload
url
URL scheme ought to be 'http' or 'https' (kind=url_scheme, input_value='httpss://instance.com', input_type=str)
For additional data go to <https://errors.pydantic.dev/2.5/v/url_scheme>
identify
String ought to have at the very least 2 characters (kind=string_too_short, input_value='J', input_type=str)
For additional data go to <https://errors.pydantic.dev/2.5/v/string_too_short>
birth_date
Date ought to be up to now (kind=date_past, input_value='2024-12-12', input_type=str)
For additional data go to <https://errors.pydantic.dev/2.5/v/date_past>

# ----

payload = {
'url': '<https://instance.com>',
'identify': 'Joe-1234567891011121314',
'birth_date': '2020-12-12'
}

process_payload(**payload)
> ValidationError: 1 validation error for process_payload
identify
String ought to have at most 15 characters (kind=string_too_long, input_value='Joe-1234567891011121314', input_type=str)
For additional data go to <https://errors.pydantic.dev/2.5/v/string_too_long>

Dies waren die Grundlagen zur Validierung von Funktionsargumenten und deren Rückgabewerten.

Nun kommen wir zur zweitwichtigsten Möglichkeit, Pydantic zur Validierung und Verarbeitung von Daten zu verwenden: durch die Definition von Modellen.

Wie Sie sehen werden, ist dieser Teil für die Zwecke der Datenverarbeitung interessanter.

Bisher haben wir validate_call um Funktionen und angegebene Funktionsargumente sowie ihre entsprechenden Typen und Einschränkungen zu dekorieren.

Hier definieren wir Modelle, indem wir Modellklassen definieren, in denen wir Felder, ihre Typen und Einschränkungen angeben. Dies ist sehr ähnlich zu dem, was wir zuvor getan haben. Indem wir eine Modellklasse definieren, die von Pydantic erbt BaseModelverwenden wir einen versteckten Mechanismus, der die Datenvalidierung, -analyse und -serialisierung durchführt. Dadurch können wir Objekte erstellen, die den Modellspezifikationen entsprechen.

Hier ist ein Beispiel:

from pydantic import Subject
from pydantic import BaseModel

class Individual(BaseModel):
identify: str = Subject(min_length=2, max_length=15)
age: int = Subject(gt=0, lt=120)

# ----

john = Individual(identify='john', age=20)
> Individual(identify='john', age=20)

# ----

mike = Individual(identify='m', age=0)
> ValidationError: 2 validation errors for Individual
identify
String ought to have at the very least 2 characters (kind=string_too_short, input_value='j', input_type=str)
For additional data go to <https://errors.pydantic.dev/2.5/v/string_too_short>
age
Enter ought to be larger than 0 (kind=greater_than, input_value=0, input_type=int)
For additional data go to <https://errors.pydantic.dev/2.5/v/greater_than>

Sie können hier auch Anmerkungen verwenden und Standardwerte für Felder angeben. Sehen wir uns ein weiteres Beispiel an:

from pydantic import Subject
from pydantic import BaseModel
from typing import Annotated

Identify = Annotated(str, Subject(min_length=2, max_length=15))
Age = Annotated(int, Subject(default=1, ge=0, le=120))

class Individual(BaseModel):
identify: Identify
age: Age

# ----

mike = Individual(identify='mike')
> Individual(identify='mike', age=1)

Die Dinge werden sehr interessant, wenn Ihr Anwendungsfall etwas komplexer wird. Denken Sie daran, payload die wir definiert haben? Ich werde eine andere, komplexere Struktur definieren, die wir durchgehen und validieren werden. Um es interessanter zu machen, erstellen wir eine Nutzlast, die wir verwenden, um einen Dienst abzufragen, der als Vermittler zwischen uns und LLM-Anbietern fungiert. Dann werden wir es validieren.

Hier ist ein Beispiel:

from pydantic import Subject
from pydantic import BaseModel
from pydantic import ConfigDict

from typing import Literal
from typing import Annotated
from enum import Enum

payload = {
"req_id": "take a look at",
"textual content": "It is a pattern textual content.",
"instruction": "embed",
"llm_provider": "openai",
"llm_params": {
"llm_temperature": 0,
"llm_model_name": "gpt4o"
},
"misc": "what"
}

ReqID = Annotated(str, Subject(min_length=2, max_length=15))

class LLMProviders(str, Enum):
OPENAI = 'openai'
CLAUDE = 'claude'

class LLMParams(BaseModel):
temperature: int = Subject(validation_alias='llm_temperature', ge=0, le=1)
llm_name: str = Subject(validation_alias='llm_model_name',
serialization_alias='mannequin')

class Payload(BaseModel):
req_id: str = Subject(exclude=True)
textual content: str = Subject(min_length=5)
instruction: Literal('embed', 'chat')
llm_provider: LLMProviders
llm_params: LLMParams

# model_config = ConfigDict(use_enum_values=True)

# ----

validated_payload = Payload(**payload)
validated_payload
> Payload(req_id='take a look at',
textual content='It is a pattern textual content.',
instruction='embed',
llm_provider=<LLMProviders.OPENAI: 'openai'>,
llm_params=LLMParams(temperature=0, llm_name='gpt4o'))

# ----

validated_payload.model_dump()
> {'textual content': 'It is a pattern textual content.',
'instruction': 'embed',
'llm_provider': <LLMProviders.OPENAI: 'openai'>,
'llm_params': {'temperature': 0, 'llm_name': 'gpt4o'}}

# ----

validated_payload.model_dump(by_alias=True)
> {'textual content': 'It is a pattern textual content.',
'instruction': 'embed',
'llm_provider': <LLMProviders.OPENAI: 'openai'>,
'llm_params': {'temperature': 0, 'mannequin': 'gpt4o'}}

# ----

# After including
# model_config = ConfigDict(use_enum_values=True)
# in Payload mannequin definition, you get

validated_payload.model_dump(by_alias=True)
> {'textual content': 'It is a pattern textual content.',
'instruction': 'embed',
'llm_provider': 'openai',
'llm_params': {'temperature': 0, 'mannequin': 'gpt4o'}}

Einige der wichtigen Erkenntnisse aus diesem ausführlichen Beispiel sind:

  • Sie können Enums verwenden oder Literal um eine Liste spezifischer Werte zu definieren, die erwartet werden.
  • Wenn Sie ein Modellfeld anders benennen möchten als in den validierten Daten, können Sie validation_alias. Es gibt den Feldnamen in den zu validierenden Daten an.
  • serialization_alias wird verwendet, wenn der interne Feldname des Modells nicht unbedingt derselbe Identify ist, den Sie beim Serialisieren des Modells verwenden möchten.
  • Felder können von der Serialisierung ausgeschlossen werden mit exclude=True.
  • Modellfelder können auch Pydantic-Modelle sein. Der Validierungsprozess wird in diesem Fall rekursiv durchgeführt. Dieser Teil ist wirklich großartig, da Pydantic bei der Validierung verschachtelter Strukturen in die Tiefe geht.
  • Felder, die in der Modelldefinition nicht berücksichtigt werden, werden nicht geparst.

Hier zeige ich Ihnen Codeausschnitte, die verdeutlichen, wo und wie Sie Pydantic in Ihren täglichen Aufgaben verwenden können.

Angenommen, Sie haben Daten, die Sie validieren und verarbeiten müssen. Sie können in CSV- oder Parquet-Dateien oder beispielsweise in einer NoSQL-Datenbank in Kind eines Dokuments gespeichert sein. Nehmen wir das Beispiel einer CSV-Datei und nehmen wir an, Sie möchten deren Inhalt verarbeiten.

Hier ist die CSV-Datei (take a look at.csv) Beispiel:

identify,age,bank_account
johnny,0,20
matt,10,0
abraham,100,100000
mary,15,15
linda,130,100000

Und so wird es validiert und analysiert:

from pydantic import BaseModel
from pydantic import Subject
from pydantic import field_validator
from pydantic import ValidationInfo
from typing import Listing
import csv

FILE_NAME = 'take a look at.csv'

class DataModel(BaseModel):
identify: str = Subject(min_length=2, max_length=15)
age: int = Subject(ge=1, le=120)
bank_account: float = Subject(ge=0, default=0)

@field_validator('identify')
@classmethod
def validate_name(cls, v: str, information: ValidationInfo) -> str:
return str(v).capitalize()

class ValidatedModels(BaseModel):
validated: Listing(DataModel)

validated_rows = ()

with open(FILE_NAME, 'r') as f:
reader = csv.DictReader(f, delimiter=',')
for row in reader:
attempt:
validated_rows.append(DataModel(**row))
besides ValidationError as ve:
# print out error
# disregard the report
print(f'{ve=}')

validated_rows
> (DataModel(identify='Matt', age=10, bank_account=0.0),
DataModel(identify='Abraham', age=100, bank_account=100000.0),
DataModel(identify='Mary', age=15, bank_account=15.0))

validated = ValidatedModels(validated=validated_rows)
validated.model_dump()
> {'validated': ({'identify': 'Matt', 'age': 10, 'bank_account': 0.0},
{'identify': 'Abraham', 'age': 100, 'bank_account': 100000.0},
{'identify': 'Mary', 'age': 15, 'bank_account': 15.0})}

FastAPI ist bereits in Pydantic integriert, daher wird dieser Artikel sehr kurz gehalten. FastAPI verarbeitet Anfragen, indem es sie an eine Funktion weiterleitet, die die Route verarbeitet. Durch die Weiterleitung dieser Anfrage an eine Funktion wird die Validierung automatisch durchgeführt. Etwas Ähnliches wie validate_call, das wir am Anfang dieses Artikels erwähnt haben.

Beispiel von app.py das zum Ausführen eines auf FastAPI basierenden Dienstes verwendet wird:

from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl

class Request(BaseModel):
request_id: str
url: HttpUrl

app = FastAPI()

@app.submit("/search/by_url/")
async def create_item(req: Request):
return merchandise

Pydantic ist eine wirklich leistungsstarke Bibliothek und verfügt über zahlreiche Mechanismen für eine Vielzahl unterschiedlicher Anwendungsfälle und Randfälle. Heute habe ich die grundlegendsten Aspekte der Verwendung erklärt und werde unten Referenzen für diejenigen bereitstellen, die nicht schwache Nerven haben.

Gehen Sie auf Entdeckungsreise. Ich bin sicher, es wird Ihnen in vielerlei Hinsicht von Nutzen sein.

[ad_2]

]]>
http://chatgpz.de/artificial-intelligence/utilized-python-chronicles-eine-sanfte-einfuehrung-in-pydantic-von-ilija-lazarevic-jul-2024/feed/ 0 2622