Înapoi la catalog
Season 9 20 Episoade 1h 15m 2026

Pydantic: Data Validation

v2.12 — Ediția 2026. O analiză aprofundată a Pydantic v2.12, cea mai utilizată bibliotecă de validare a datelor pentru Python, de la utilizarea de bază până la funcționalități avansate precum core schemas personalizate și observabilitate cu Logfire.

Validarea datelor Python Core
Pydantic: Data Validation
Se redă acum
Click play to start
0:00
0:00
1
Filosofia Pydantic: Type Hints ca Validare
Acest episod prezintă premisa de bază a Pydantic. Vei învăța cum type hints din Python pot fi folosite pentru a impune scheme și cum nucleul Rust aduce creșteri imense de performanță.
3m 54s
2
Anatomia unui BaseModel
Aprofundează BaseModel, abstracția fundamentală a Pydantic. Vei învăța cum instanțierea validează datele, cum sunt convertite automat câmpurile și cum sunt afișate erorile de validare.
4m 01s
3
Constrângeri de Câmp și Pattern-ul Annotated
Învață cum să impui limite dincolo de tipurile de bază. Vei descoperi cum să folosești funcția Field și constructul de tipizare Annotated pentru a adăuga constrângeri precum valori minime și lungimi maxime.
4m 34s
4
Alias-uri de Câmp pentru Validare și Serializare
Rezolvă conflictul convențiilor de denumire dintre API-urile externe și codul intern Python. Vei învăța cum să decuplezi numele atributelor Python de cheile JSON folosind alias-uri de validare și serializare.
3m 34s
5
Conversia Datelor vs Strict Mode
Preia controlul asupra tendinței Pydantic de a converti datele. Vei învăța cum să impui potriviri exacte de tip prin activarea Strict Mode la nivel de câmp sau de model.
4m 04s
6
Observabilitate în Lumea Reală cu Logfire
Adu transparență în pipeline-urile tale de date. Vei învăța cum să integrezi Pydantic cu Logfire pentru a monitoriza în timp real validările reușite și eșuate.
3m 38s
7
Validarea Tipurilor Arbitrare cu TypeAdapter
Învață cum să validezi primitive independente și liste fără a crea un BaseModel. Vei descoperi cum TypeAdapter transformă orice tip Python într-o țintă completă de validare.
4m 18s
8
Tipuri Union și Validare Inteligentă
Înțelege complexitatea validării tipurilor Union. Vei învăța cum Smart Mode din Pydantic evaluează exactitatea și câmpurile valide pentru a alege cea mai bună potrivire.
3m 35s
9
Instrument de Putere: Discriminated Unions
Îmbunătățește-ți performanța de validare. Vei învăța cum să folosești Discriminated (Tagged) Unions pentru a-i spune lui Pydantic exact ce schemă să aplice pe baza unui câmp specific.
3m 40s
10
Preprocesarea cu Before și Wrap Validators
Gestionează datele de intrare dezordonate înainte să ajungă la schema ta. Vei învăța cum să folosești validatorii de câmp Before și Wrap pentru a curăța datele brute înainte ca Pydantic să le evalueze.
4m 00s
11
Postprocesarea cu After și Plain Validators
Impune reguli stricte de logică de business. Vei învăța cum să folosești validatorii After pentru a verifica datele deja parsate și validatorii Plain pentru a scurtcircuita complet Pydantic.
3m 24s
12
Hook-uri de Validare la Nivel de Model
Validează interacțiunile dintre mai multe câmpuri. Vei învăța cum să folosești decoratorul model_validator pentru a impune reguli care depind de întregul payload.
3m 28s
13
Serializare: Exportarea Datelor în Siguranță
Controlează modul în care datele tale părăsesc sistemul. Vei învăța diferențele dintre exportarea în dicționare Python versus șiruri JSON și cum să excluzi câmpurile nesetate sau implicite.
4m 01s
14
Personalizarea Logicii de Serializare
Schimbă modul în care tipurile tale sunt reprezentate la ieșire. Vei învăța cum să scrii serializatoare personalizate Field și Model pentru a muta datele în timpul fazei de exportare.
3m 28s
15
Generarea JSON Schema din Modele
Transformă-ți modelele în contracte API care se autodocumentează. Vei învăța cum să generezi scheme JSON compatibile cu OpenAPI și să injectezi exemple direct în schemă.
4m 24s
16
RootModel: Când Payload-ul Tău Nu Este un Dicționar
Gestionează elegant payload-urile JSON non-standard. Vei descoperi cum RootModel îți permite să parsezi array-uri și primitive la nivel de rădăcină, păstrând în același timp puterile BaseModel.
3m 43s
17
Dataclasses Standard vs Pydantic Dataclasses
Adu validarea în clasele tale native Python. Vei învăța când să folosești decoratorul dataclass din Pydantic pentru a moderniza bazele de cod vechi fără a rescrie totul.
3m 41s
18
Ajustarea Fină a Configurației Modelului
Controlează strictețea întregului tău model. Vei învăța cum să folosești ConfigDict pentru a interzice atributele suplimentare, a îngheța instanțele și a valida atribuirile.
3m 23s
19
Configurarea Aplicației cu Pydantic Settings
Gestionează-ți variabilele de mediu ca un profesionist. Vei învăța cum pachetul pydantic-settings automatizează parsarea secretelor, a fișierelor dot-env și a prefixelor.
3m 27s
20
Sub Capotă: Core Schemas Personalizate
Acesta este ultimul episod al seriei! Preia controlul suprem asupra motorului de validare. Vei învăța cum să scrii o metodă __get_pydantic_core_schema__ pentru a învăța nucleul Rust cum să gestioneze obiecte Python complet străine.
3m 36s

Episoade

1

Filosofia Pydantic: Type Hints ca Validare

3m 54s

Acest episod prezintă premisa de bază a Pydantic. Vei învăța cum type hints din Python pot fi folosite pentru a impune scheme și cum nucleul Rust aduce creșteri imense de performanță.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Data Validation, episodul 1 din 20. Majoritatea librăriilor de data validation te obligă să înveți un limbaj complet nou, specific domeniului, doar pentru a defini o schemă. Dar cum ar fi dacă sintaxa built-in din Python ar fi deja suficientă pentru a-ți impune regulile? Filosofia Pydantic: Type Hints ca validare rezolvă exact această tensiune. Înainte să ne uităm la cum funcționează, trebuie să clarificăm o confuzie comună. Pydantic nu este un static type checker precum mypy. Mypy îți analizează codul sursă înainte să-l rulezi pentru a prinde erorile de logică. Pydantic operează la runtime. Preia date untrusted din exterior, cum ar fi un JSON payload dintr-un API request, și le forțează să se conformeze tipurilor pe care le-ai definit, exact în timp ce programul tău rulează. Filosofia de bază aici este simplitatea. Definești un data model folosind type annotations standard din Python. Creezi o clasă care reprezintă un user și declari că user ID-ul este un integer, iar data înscrierii este un obiect datetime. Asta este toată schema ta. Nu scrii funcții de validare custom și nu imporți field types proprietare. Când un dicționar dezordonat ajunge de la un web form, pur și simplu îl pasezi clasei tale. Pydantic îl interceptează și garantează că obiectul rezultat respectă cu strictețe acele tipuri. Aici este ideea cheie. Pydantic este fundamental o librărie de parsing, nu doar o poartă strictă de validare. Dacă un user trimite un web form în care user ID-ul este string-ul patruzeci și doi, Pydantic va recunoaște că modelul tău așteaptă un integer. Convertește automat acel string într-un integer nativ Python. Încearcă să facă datele să se potrivească în schema ta înainte să arunce o eroare. Asta rezolvă partea plictisitoare de data coercion, astfel încât să nu fii nevoit să scrii manual logica de parsing pentru fiecare input field. Validarea și convertirea fiecărei bucăți de date primite la runtime sună inerent lent, mai ales în Python. Pentru a rezolva asta, logica de execuție nu rulează de fapt în Python. Pydantic deleagă greul către un core engine dedicat, scris în întregime în Rust. Acest design îți oferă un developer experience rapid, scriind Python pur, combinat cu viteza brută de execuție a unui cod de sistem compilat. Gândește-te la un background task care face parsing pe un fișier JSON masiv, unde fiecare înregistrare conține o adresă web. Dacă scrii cod Python pur ca să iterezi prin mii de dicționare, să extragi fiecare string, să încarci o librărie de regular expressions și să verifici dacă fiecare string este un URL valid, procesul tău se va mișca în reluare. Pydantic gestionează asta fără probleme. Trebuie doar să adnotezi field-ul adresei ca un tip URL și să dai JSON-ul raw modelului tău. Engine-ul din Rust zboară prin text, făcând parsing și validând formatele la viteze pe care Python-ul nativ nu le poate egala. Adevărata putere a acestei abordări este că autocomplete-ul din editorul tău, tool-urile de static analysis și validarea la runtime împart exact aceeași sursă de adevăr, adică type hints-urile tale standard. Dacă găsești aceste episoade utile și vrei să susții emisiunea, poți căuta DevStoriesEU pe Patreon. Asta e tot pentru acest episod. Mulțumesc pentru audiție și continuă să construiești!
2

Anatomia unui BaseModel

4m 01s

Aprofundează BaseModel, abstracția fundamentală a Pydantic. Vei învăța cum instanțierea validează datele, cum sunt convertite automat câmpurile și cum sunt afișate erorile de validare.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Validarea datelor, episodul 2 din 20. Vorbim adesea despre validarea datelor, dar dacă te uiți cu atenție la Pydantic, scopul său principal este de fapt coercion. Garantează structura pentru output, nu pentru input. Anatomia unui BaseModel este ceea ce face posibilă această distincție. Clasa BaseModel este fundamentul Pydantic. Pentru a defini o schemă, creezi o clasă Python standard care moștenește din BaseModel. Odată ce faci asta, Pydantic îți transformă clasa într-un data container strict. Definești forma datelor folosind type hints standard din Python. Nu ai nevoie de funcții proprietare pentru a declara un string sau un număr. Pur și simplu scrii numele atributului, două puncte și tipul Python așteptat. Ia în considerare un model User. În interiorul clasei, definești un singur câmp numit id și îi pui tipul integer. Ai putea adăuga și un câmp name cu tipul string. Asta este toată definiția. Aici este ideea cheie. Munca propriu-zisă are loc în momentul în care instanțiezi modelul. Creezi o instanță pasând datele ca keyword arguments, care se potrivesc cu numele câmpurilor pe care le-ai definit. Când faci asta, Pydantic interceptează datele înainte ca obiectul să fie complet inițializat. Compară valorile primite cu acele type hints. Aici are loc acel coercion. Dacă pasezi acel integer unu-doi-trei în câmpul id, Pydantic îl acceptă imediat. Dar să presupunem că primești date de la un web request sau dintr-un fișier text și pasezi acel string "123" în exact același câmp. Pydantic nu aruncă instantaneu o eroare. Recunoaște că tipul țintă este un integer și încearcă să convertească acel string. Deoarece caracterele pot primi cast în siguranță către un număr, Pydantic efectuează conversia în mod silențios. Obiectul este creat, iar câmpul id stochează un integer Python real, nu un string. Acest comportament dovedește că Pydantic este în esență o librărie de parsing. Transformă datele primite pentru a se potrivi schemei stricte pe care ai definit-o. Desigur, această conversie are limite logice. Dacă instanțiezi modelul User și pasezi stringul "not an int" câmpului id, Pydantic încearcă conversia și eșuează. Când acel coercion este imposibil, Pydantic aruncă un ValidationError. Această eroare oprește imediat execuția. Un detaliu crucial despre ValidationError este că Pydantic evaluează toate câmpurile înainte de a o arunca. Dacă modelul tău are mai multe câmpuri cu date invalide, excepția va conține detaliile pentru toate eșecurile, în loc să se oprească la prima greșeală. Eroarea indică exact câmpurile care au cauzat problema, valorile specifice furnizate și motivele pentru care au dat fail la parsing. Odată ce datele trec cu succes de instanțiere, obiectul rezultat este garantat să corespundă acelor type hints. Accesezi datele exact ca la orice obiect Python standard, folosind dot notation. Dacă ai atribuit instanța unei variabile numite user, pur și simplu scrii user punct id pentru a recupera acel integer. Nu sunt necesare metode de tip getter sau setter. Interacționezi cu un obiect curat, strongly typed. Adevărata valoare a moștenirii din BaseModel nu constă doar în faptul că respinge inputuri greșite, ci și în faptul că normalizează în siguranță date externe imprevizibile într-o stare internă extrem de previzibilă. Mulțumesc pentru audiție. Aveți grijă de voi, tuturor.
3

Constrângeri de Câmp și Pattern-ul Annotated

4m 34s

Învață cum să impui limite dincolo de tipurile de bază. Vei descoperi cum să folosești funcția Field și constructul de tipizare Annotated pentru a adăuga constrângeri precum valori minime și lungimi maxime.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Validarea datelor, episodul 3 din 20. Type hints-urile standard îți spun că un field este un integer, dar nu îți pot spune că trebuie să fie mai mare decât zero. Când o vârstă negativă sau un username de zece mii de caractere trece de limitele aplicației tale, type checking-ul de bază nu mai este suficient pentru a-ți proteja backend-ul. Pentru a impune limite stricte asupra datelor tale, ai nevoie de Field Constraints și de pattern-ul Annotated. În Pydantic, constrângerile îți permit să restricționezi valorile permise pentru un anumit tip. În loc să scrii funcții custom de validare pentru fiecare regulă minoră, poți defini limite matematice sau structurale direct pe field. Pentru tipurile numerice, poți impune limite greater than sau less than folosind parametri precum g-t și l-t. Pentru string-uri, poți restricționa dimensiunea input-ului folosind max length și min length. Pentru a aplica aceste reguli, Pydantic oferă o funcție utilitară numită Field. Modul tradițional prin care developerii aplicau aceste constrângeri era prin atribuirea unui apel de funcție Field ca valoare default a unui atribut din model. De exemplu, ai declara un atribut age, i-ai pune un type hint de integer și l-ai seta egal cu Field, pasând g-t egal cu zero. Această structură funcționează, dar introduce fricțiune. Dacă ai nevoie de un integer pozitiv în cincisprezece modele diferite, scrii exact aceeași atribuire Field de cincisprezece ori. Mai rău, deoarece funcția Field ocupă slotul de atribuire a valorii default din model, complică lucrurile atunci când vrei de fapt să atribui un integer default real acelui atribut. Iată ideea cheie. Nu trebuie să legi deloc regulile de validare de atribuirea atributului. Le poți integra direct în definiția tipului folosind typing dot Annotated din Python. Annotated este o funcționalitate din standard library care îți permite să atașezi metadate arbitrare la un type hint de bază. Pydantic este special conceput pentru a căuta în interiorul unui tip Annotated, a găsi orice funcții Field pe care le-ai furnizat și a extrage automat regulile lor de validare. Când folosești Annotated, îi pasezi două informații distincte. Mai întâi, furnizezi tipul de bază Python, cum ar fi un integer sau un string. În al doilea rând, furnizezi metadatele, care în cazul nostru sunt funcția Pydantic Field care conține constrângerile tale. Să construim un tip reutilizabil pentru age ca să vedem cum funcționează asta. Definești o nouă variabilă în codul tău numită PositiveInt. O atribui lui Annotated. În Annotated, pasezi integer ca tip de bază, urmat de o virgulă, iar apoi funcția Field cu g-t egal cu zero. Tocmai ai creat o constrângere de tip custom, reutilizabilă. Acum, ori de câte ori definești un model de user sau un model de angajat, pur și simplu îi pui type hint field-ului tău age cu PositiveInt. Nu este nevoie să apelezi funcția Field pe atributul modelului. Această abordare separă definițiile de tip de structurile modelului. Modelele tale rămân incredibil de curate, citindu-se exact ca niște clase Python standard, fără clutter. Dacă logica ta de business se schimbă ulterior și ai nevoie brusc ca un field age să fie mai mare de optsprezece în loc de zero, actualizezi definiția PositiveInt exact într-un singur loc. Această constrângere actualizată se propagă instantaneu la fiecare model care o folosește. În plus, deoarece Annotated este o funcționalitate nativă Python, static type checkers înțeleg perfect faptul că tipul tău custom PositiveInt este evaluat în cele din urmă ca un integer standard. Prin decuplarea metadatelor de validare de slotul valorii default, pattern-ul Annotated transformă field constraints din boilerplate repetitiv într-o shared library de domain types stricte și reutilizabile. Îți mulțumesc că ai petrecut câteva minute cu mine. Până data viitoare, numai bine.
4

Alias-uri de Câmp pentru Validare și Serializare

3m 34s

Rezolvă conflictul convențiilor de denumire dintre API-urile externe și codul intern Python. Vei învăța cum să decuplezi numele atributelor Python de cheile JSON folosind alias-uri de validare și serializare.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Validarea datelor, episodul 4 din 20. Ai fost vreodată forțat să denumești o variabilă Python folosind camel case doar pentru a face parse la un payload dintr-un API extern? Știi că asta încalcă convențiile standard de naming din Python, dar JSON-ul primit dictează cheia. Soluția pentru asta sunt Field Aliases pentru validare și serializare. Când faci ingest la date, cheile din acel payload adesea nu se potrivesc cu modul în care vrei să îți structurezi codul Python. Dacă un serviciu third-party trimite un profil de user cu cheia userName cu N mare, tu vrei să o mapezi la o variabilă standard snake case, numită user underscore name. Pydantic gestionează acest layer de traducere folosind funcția Field, mai exact prin argumentele sale de tip alias. Cea mai simplă abordare este argumentul alias de bază. Când declari atributul modelului, îi atribui un Field și setezi parametrul alias la string-ul așteptat din exterior. Dacă setezi alias-ul la versiunea camel case, Pydantic folosește exact acel string atât pentru citire, cât și pentru scriere. Când validează datele primite, caută cheia camel case. Când serializezi ulterior modelul pentru a face dump înapoi în JSON, va scrie cheia camel case. Codul tău intern de Python operează în întregime pe atributul snake case, complet izolat de convenția externă de naming. Asta rezolvă problema datelor simetrice, unde formatul de input și formatul de output sunt identice. Acum, a doua parte a discuției sunt datele asimetrice. Ce se întâmplă când consumi date dintr-un sistem legacy care folosește o convenție de naming, dar trebuie să le servești unui client nou folosind o alta? Aici separi logica folosind alias-uri de validare și alias-uri de serializare. Acestea sunt argumente separate pe care le pasezi funcției Field. Un alias de validare dictează strict ce caută Pydantic atunci când creează modelul. Dacă oferi un alias de validare, Pydantic îl va folosi pentru a extrage valoarea din payload-ul primit, făcând override la orice alias de bază pe care l-ai fi putut seta. În schimb, un alias de serializare controlează doar faza de output. Când apelezi o metodă pentru a face dump la model într-un dicționar sau într-un string JSON, Pydantic folosește alias-ul de serializare drept cheie de output. Iată ideea principală. Poți defini un singur field cu trei identități distincte. Alias-ul de validare prinde string-ul de input dezordonat din API-ul legacy. Atributul Python conține variabila curată, snake case, pe care o folosești în logica ta de business. În cele din urmă, alias-ul de serializare definește cheia finisată și standardizată care este trimisă către frontend. Uneori, problema nu este o convenție de naming rigidă, ci una inconsistentă. S-ar putea să primești payload-uri în care identificatorul userului este uneori camel case, iar alteori un singur cuvânt fără spații. Pentru a gestiona asta, Pydantic oferă un utilitar numit alias choices. În loc să pasezi un singur string către alias-ul de validare, pasezi acest utilitar care conține o listă de string-uri. În timpul validării, Pydantic scanează payload-ul primit după fiecare string, în ordinea pe care ai oferit-o. În momentul în care găsește o cheie care se potrivește, extrage valoarea, o atribuie atributului tău Python și ignoră restul. Prin separarea modului în care se face parse la date de modul în care sunt exportate, alias-urile decuplează designul intern al obiectului tău Python de constrângerile arbitrare de naming din exterior. Asta e tot pentru acest episod. Îți mulțumesc că ai ascultat și continuă să construiești!
5

Conversia Datelor vs Strict Mode

4m 04s

Preia controlul asupra tendinței Pydantic de a converti datele. Vei învăța cum să impui potriviri exacte de tip prin activarea Strict Mode la nivel de câmp sau de model.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Validarea datelor, episodul 5 din 20. Faptul că Pydantic este atât de dornic să transforme string-ul „123” într-un integer este un killer feature, până când ascunde silențios un bug de data-type în JSON payload-ul tău. Te aștepți la numere, primești string-uri, iar aplicația ta continuă fără probleme până când un sistem downstream strict dă crash. Mecanismul care controlează acest comportament este Data Coercion, iar ca să-l îmblânzești trebuie să înțelegi Strict Mode. By default, Pydantic funcționează în ceea ce documentația numește lax mode. În acest mod, Pydantic acționează ca un data parser, mai degrabă decât ca un simplu type checker. Încearcă în mod activ să facă coerce, sau să convertească, datele primite în tipul pe care l-ai declarat. Dacă definești un câmp ca integer, iar input payload-ul furnizează string-ul „123”, Pydantic evaluează string-ul, extrage numărul valid și îl transformă într-un integer real. Acest comportament este incredibil de util atunci când procesezi user input din web forms sau query parameters, unde fiecare valoare primită este fundamental un string. Totuși, atunci când construiești API-uri machine-to-machine, conversia silențioasă este adesea periculoasă. Dacă un client promite să trimită un integer, dar trimite în schimb un string, acesta încalcă API contract-ul. Lax mode acoperă această încălcare. Aici intervine strict mode. Strict mode dezactivează type coercion-ul automat. Când îl activezi, Pydantic cere ca tipul de date primit să corespundă exact type annotation-ului tău. Pasează string-ul „123” unui câmp strict de tip integer, iar Pydantic îl respinge imediat cu o validation error. Forțează sursa de date să respecte schema. Ai două modalități de a aplica strict mode: global pe tot modelul, sau local pe câmpuri specifice. Pentru a-l impune global, modifici configurația modelului. Setând flag-ul de configurare strict la true, fiecare câmp din acel model nu mai face type coercion. Un câmp boolean va accepta doar o valoare booleană true sau false, nu string-ul „true” sau integer-ul 1. Un câmp integer va accepta doar integer-uri. Iată ideea cheie. Strictețea globală este adesea prea rigidă pentru aplicațiile din lumea reală în care datele sosesc din surse mixte. De obicei, vrei să blochezi câțiva identificatori critici, lăsând restul modelului flexibil. Pentru a realiza asta, Pydantic permite strictețea locală. Poți impune strict mode pe un câmp individual utilizând tipuri specializate furnizate de bibliotecă, cum ar fi StrictInt, StrictStr sau StrictBool. Dacă definești un câmp de user ID utilizând StrictInt, acel câmp specific va respinge reprezentările de tip string ale numerelor, în timp ce restul modelului tău continuă să funcționeze în lax mode. De asemenea, poți realiza asta pasând un flag strict direct în funcția de definire a câmpului pentru orice tip standard. Ia în considerare un serviciu care procesează un JSON payload pentru o tranzacție financiară. Payload-ul conține un account ID. Dacă este definit ca un integer normal, un payload care furnizează account ID-ul ca string-ul „123” trece fără probleme. Pydantic repară data type-ul în memorie. Dacă actualizezi acel câmp pentru a utiliza StrictInt, exact același JSON payload pică validarea. Clientul primește o eroare explicită care precizează că input-ul trebuie să fie un integer valid, detectând încălcarea contractului la limita sistemului înainte ca aceasta să-ți polueze baza de date. Strict mode transformă Pydantic dintr-un parser util care curăță input-urile dezordonate într-un enforcer rigid care garantează data contracts. Mulțumesc pentru audiție. Aveți grijă de voi.
6

Observabilitate în Lumea Reală cu Logfire

3m 38s

Adu transparență în pipeline-urile tale de date. Vei învăța cum să integrezi Pydantic cu Logfire pentru a monitoriza în timp real validările reușite și eșuate.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Validarea datelor, episodul 6 din 20. Când un payload complex eșuează la validare în producție, stack trace-ul standard rareori îți spune exact de ce datele au fost respinse. Știi că un request a eșuat, dar nu vezi deloc valorile reale primite care cauzează crash-ul. Asta e exact problema pe care o rezolvă observabilitatea în lumea reală cu Logfire. Logfire este o platformă de observabilitate construită de echipa Pydantic și are o integrare directă chiar cu Pydantic. Scopul este să îți ofere vizibilitate asupra a ceea ce face de fapt layer-ul tău de validare a datelor în producție. În loc să tratezi validarea ca pe un black box care aruncă ocazional excepții, această integrare transformă fiecare verificare de validare în telemetrie. Imaginează-ți un background worker care procesează înscrierile utilizatorilor dintr-un message queue. Sute de evenimente sosesc pe secundă. Dintr-o dată, o înscriere eșuează cu o eroare de validare. Fără o instrumentare adecvată, log-urile tale arată un crash generic. Trebuie să cauți payload-ul brut din queue ca să îți dai seama că utilizatorul a introdus vârsta de minus cinci. Ca să repari asta, imporți pachetul Logfire și apelezi o singură funcție numită instrument underscore pydantic. Pui asta imediat după inițializarea clientului tău Logfire. Din acel moment, modelele tale Pydantic sunt complet observabile. Nu trebuie să schimbi modul în care îți definești modelele sau cum le instanțiezi. Iată partea esențială. Odată instrumentate, de fiecare dată când Pydantic validează date, Logfire creează automat un span. Un span este pur și simplu o înregistrare cronometrată a unei operațiuni. Dacă payload-ul de înscriere este perfect valid, Logfire înregistrează un span de succes, arătând exact cât timp a durat validarea. Asta e foarte util dacă ai validatori custom complecși și trebuie să monitorizezi bottleneck-urile de performanță. Dacă payload-ul este invalid, Pydantic aruncă o eroare de validare. Logfire prinde acest eveniment și atașează detaliile la trace. Acesta capturează modelul specific implicat și câmpurile exacte care au declanșat eșecul. Când te uiți la dashboard-ul tău de observabilitate, nu vezi doar un mesaj de eroare generic. Vezi exact valorile respinse, cum ar fi acea vârstă negativă sau un string de email malformat. Setup-ul este complet hands-off. În primul rând, configurezi clientul. În al doilea rând, apelezi funcția instrument. În al treilea rând, îți lași worker-ul să proceseze date. Când worker-ul încearcă să parseze un string JSON greșit în modelul tău de înscriere, telemetria capturează automat contextul erorii. Nu scrii absolut niciun bloc custom de excepții ca să loghezi input-ul greșit. Pentru că Logfire înțelege Pydantic nativ, îți respectă structurile de date. Știe diferența dintre un câmp lipsă și un type mismatch și formatează acea telemetrie astfel încât să o poți interoga mai târziu. Îți poți filtra metricile ca să afli exact de câte ori câmpul de email a eșuat la validare în întregul tău worker cluster astăzi. Adevărata valoare a acestei integrări este că ridică validarea datelor de la o simplă verificare în cod la un eveniment de observabilitate first-class, transformând respingerile silențioase de date în telemetrie structurată și actionable. Dacă vrei să susții emisiunea, ne poți găsi căutând DevStoriesEU pe Patreon. Asta e tot pentru acest episod. Îți mulțumesc că ai ascultat și continuă să construiești!
7

Validarea Tipurilor Arbitrare cu TypeAdapter

4m 18s

Învață cum să validezi primitive independente și liste fără a crea un BaseModel. Vei descoperi cum TypeAdapter transformă orice tip Python într-o țintă completă de validare.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Validarea datelor, episodul 7 din 20. Uneori trebuie doar să validezi o listă simplă de strings care vine dintr-un API request, dar crearea unei clase model întregi doar pentru a ține acea singură listă pare un overkill masiv. Nu vrei un wrapper object, vrei doar lista validată. Soluția la asta este validarea tipurilor arbitrare cu TypeAdapter. În Pydantic, workflow-ul standard se învârte în jurul definirii unei clase care moștenește din base model. Acel model îți oferă acces la metode puternice pentru parsing și serializarea datelor. Dar Pydantic este perfect capabil să valideze tipuri Python standard, cum ar fi un plain dictionary, un standalone integer, un dataclass standard sau un typed dict. Faza e că aceste tipuri standard nu posedă în mod inerent metode de validare Pydantic. Nu poți apela validate pe un list Python standard. Aici intervine type adapter-ul. Acționează ca o punte, făcând wrapping pe orice tip Python arbitrar și expunând toate metodele familiare de model pentru el. Gândește-te la un web endpoint care acceptă un raw JSON array de strings. În trecut, poate ai fi creat un dummy model cu un singur câmp numit items, doar ca să-i poți pasa JSON payload-ul. Asta forțează clientul să trimită un JSON object cu o cheie items, sau te forțează pe tine să faci unpack la modelul validat mai târziu. Cu un type adapter, sari complet peste dummy model. Mai întâi, instanțiezi adapter-ul și îi pasezi exact type definition-ul pe care îl aștepți. În acest caz, pasezi type hint-ul din Python pentru un list de strings. Asta creează un adapter object configurat special pentru acea structură exactă. Acum, ai acces la metodele standard de validare. Iei raw JSON payload-ul de la endpoint-ul tău și îl pasezi metodei validate json de pe instanța ta de adapter. Pydantic parsează raw byte string-ul, verifică dacă este un JSON array, verifică dacă fiecare element din interior este un string și returnează un list Python standard. Dacă payload-ul conține un integer sau un boolean, aruncă o eroare de validare exact cum ar face-o un model obișnuit. Iată ideea principală. Adapter-ul nu se limitează la o simplă validare. El oglindește complet core API-ul unui model standard. Asta înseamnă că îl poți folosi și pentru a serializa date. Dacă ai un dictionary complex sau un dataclass Python standard și trebuie să le convertești înapoi într-un JSON string, pasezi acele date metodei dump json de pe adapter-ul tău. Aplică aceleași reguli de serializare, custom encoders și formatare pe care Pydantic le aplică modelelor obișnuite. Acest feature este util în special atunci când lucrezi cu typed dicts. Un typed dict oferă structural typing pentru dictionaries Python standard, dar face zero runtime validation. Pasând un typed dict către un adapter, obții un runtime enforcement complet al structurii dictionary-ului. Se asigură că toate cheile necesare sunt prezente și că valorile se potrivesc cu tipurile așteptate, fără a converti dictionary-ul într-un object instance. Output-ul rămâne un dictionary simplu. Instanțierea unui adapter necesită ca Pydantic să construiască validation schemas interne. Pentru că acest proces de setup necesită o cantitate mică de compute time, ar trebui să îți creezi instanțele de adapter la nivel de modul, în loc să le reconstruiești în interiorul unei funcții de fiecare dată când este apelat un endpoint. Definește adapter-ul o singură dată în partea de sus a fișierului și refolosește-l în mai multe requests. Type adapter-ul îți oferă toată puterea core validation engine-ului pentru orice tip Python standard, păstrându-ți structurile de date curate și lipsite de wrapper classes inutile. Asta e tot pentru azi. Mersi că ai ascultat — du-te și construiește ceva cool.
8

Tipuri Union și Validare Inteligentă

3m 35s

Înțelege complexitatea validării tipurilor Union. Vei învăța cum Smart Mode din Pydantic evaluează exactitatea și câmpurile valide pentru a alege cea mai bună potrivire.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Data Validation, episodul 8 din 20. Când un field este adnotat ca un Union de tip string sau integer, și îi pasezi integer-ul 123, ce validare încearcă Pydantic, de fapt, prima dată? Dacă presupui că îți citește codul pur și simplu de la stânga la dreapta, s-ar putea să fii surprins când datele tale se comportă diferit față de cum te-ai aștepta. Asta ne aduce la Union Types și Smart Validation. Un union type îi permite unui singur field să accepte mai multe data types distincte. Validarea union-urilor este inerent complexă, deoarece Pydantic încearcă în mod activ să facă coerce datelor la tipul cerut. Un integer poate deveni cu ușurință un string, iar un string care conține cifre poate fi parsat într-un integer. Dacă motorul de validare ar lua pur și simplu primul match găsit, output-ul tău s-ar schimba în totalitate pe baza ordinii arbitrare în care ai listat tipurile în codul tău. Acest comportament rigid chiar există și se numește modul Left to Right. În acest mod, sistemul evaluează input-ul în raport cu primul tip definit în union. Dacă validarea reușește, se oprește imediat. Dacă eșuează, trece la al doilea tip. Dacă field-ul tău are tipul string sau integer, în această ordine, și îi pasezi integer-ul 123, modul Left to Right evaluează mai întâi condiția de string. Pentru că integer-ul 123 poate fi convertit prin coerce fără probleme în string-ul „123”, validarea trece. Integer-ul tău este convertit silențios într-un string doar pentru că string a fost scris primul. Iată ideea cheie. By default, Pydantic evită această capcană folosind Smart Mode. În loc să se oprească la primul match acceptabil, Smart Mode evaluează input-ul în raport cu toate tipurile posibile din union. Apoi compară validările reușite și alege cel mai bun match pe baza unor criterii specifice de scoring. Criteriul principal pentru tipurile simple este exactitatea. Smart Mode penalizează puternic procesul de data coercion. Revenind la scenariul nostru anterior cu un field care are tipul string sau integer. Când pasezi integer-ul 123, Smart Mode testează ambele opțiuni. Recunoaște că input-ul poate fi convertit prin coerce într-un string valid, dar vede și că input-ul este deja un match perfect și exact pentru un integer. Pentru că un exact match obține mereu un scor mai bun decât un coerced match, Smart Mode returnează corect integer-ul 123, indiferent de ce tip a fost scris primul în union. Când union-ul tău conține data models complexe în loc de tipuri de bază, Smart Mode se bazează pe o metrică diferită. Numără câte field-uri valide sunt setate. Motorul evaluează dictionary-ul de input în raport cu fiecare model din union. Calculează câte field-uri din input se mapează exact pe field-urile definite ale fiecărui model. Modelul care absoarbe cu succes cel mai mare număr de field-uri de input fără să arunce erori de validare este declarat câștigător. Asta previne ca un model mai mic și mai puțin specific să înghită date care erau în mod clar destinate unui model mai mare și mai detaliat din același union. Smart Validation se asigură că datele tale își păstrează forma originală precisă ori de câte ori este posibil, protejându-te de erorile silențioase de coercion, care sunt notoriu de dificil de depistat în producție. Mulțumesc că m-ai ascultat, happy coding tuturor!
9

Instrument de Putere: Discriminated Unions

3m 40s

Îmbunătățește-ți performanța de validare. Vei învăța cum să folosești Discriminated (Tagged) Unions pentru a-i spune lui Pydantic exact ce schemă să aplice pe baza unui câmp specific.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Data Validation, episodul 9 din 20. Validarea unui payload primit pe douăzeci de modele de date diferite prin trial and error este un coșmar pentru performanță. Când sistemul tău primește un event generic, să ghicești ce schema să aplici irosește cicluri de CPU și generează mesaje de eroare foarte confuze atunci când validarea eșuează. Poți evita complet acest joc de ghicit folosind un tool puternic: Discriminated Unions. Un union standard îi spune lui Pydantic că un field ar putea fi unul din mai multe modele diferite. By default, Pydantic ia datele primite și le testează pe primul model. Dacă asta eșuează, îl încearcă pe al doilea, și așa mai departe. Acest parsing secvențial este ineficient. Discriminated unions rezolvă asta folosind un tag explicit. Să presupunem că construiești un analytics pipeline care primește diferite tipuri de events, cum ar fi un click event, un scroll event și un purchase event. Fiecare event necesită data fields diferite. Modelul de click ar putea avea nevoie de un element ID, în timp ce modelul de purchase are nevoie de o sumă a tranzacției. Pentru a seta un discriminated union, adaugi un field comun fiecărui model din acel grup. Ai putea numi acest field event type. Apoi, atribui un tip literal string acestui field. Modelul de click impune ca event type-ul să fie exact string-ul click. Modelul de purchase impune strict string-ul purchase. Mai departe, îți creezi modelul principal de payload. Acest model are un singur event field, definit ca un union al modelelor tale specifice de events. Aici configurezi discriminator-ul. Împachetezi definiția de union într-o configurație de field Pydantic și atribui string-ul event type argumentului discriminator. Aici e ideea de bază. Când sosește un payload, Pydantic nu mai testează modelele unul câte unul. Se uită direct la cheia event type din datele primite. Dacă valoarea este purchase, Pydantic rutează imediat întregul payload către modelul de purchase. Este un lookup direct. Dacă lipsește suma tranzacției, mesajul de eroare indică clar că lipsește un field obligatoriu pentru un purchase event, în loc să genereze un wall of text masiv care explică cum datele nu s-au potrivit cu toate tipurile de events posibile. Asta acoperă o structură curată în care fiecare payload are în comun o cheie top-level. Uneori ai de-a face cu date third-party nestructurate, unde tag-ul de identificare este nested în interiorul altui obiect, sau modelul corect depinde de prezența unor chei specifice, mai degrabă decât de o singură valoare dedicată. Pentru aceste situații, Pydantic oferă callable discriminators. În loc să pasezi un nume de field de tip string argumentului discriminator, pasezi o funcție custom. Această funcție primește datele de input raw, nevalidate. Scrii logica în interiorul acestei funcții pentru a inspecta dictionary-ul raw, a găsi orice indiciu determină tipul de date și a returna un simplu string tag care reprezintă modelul corect. Pydantic îți execută funcția mai întâi, primește înapoi string tag-ul și îl folosește pentru a ruta datele către modelul precis din union. Folosirea unui discriminated union transformă validarea dintr-un joc secvențial de ghicit într-un constant-time lookup precis. Mulțumesc că m-ați ascultat, o zi bună tuturor!
10

Preprocesarea cu Before și Wrap Validators

4m 00s

Gestionează datele de intrare dezordonate înainte să ajungă la schema ta. Vei învăța cum să folosești validatorii de câmp Before și Wrap pentru a curăța datele brute înainte ca Pydantic să le evalueze.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Data Validation, episodul 10 din 20. Uneori, datele primite sunt atât de dezordonate încât un parsing standard eșuează în momentul în care atinge modelul tău. Trebuie să interceptezi și să sanitizezi inputul brut înainte ca framework-ul măcar să încerce să îl citească. Exact asta îți permite preprocesarea cu validatoarele Before și Wrap. În mod normal, Pydantic face o treabă excelentă aplicând automat coercion pe date pentru a le aduce la tipul corect. Dar dacă forma fundamentală a datelor este complet greșită, procesul de coercion eșuează imediat. Un validator Before este conceput exact pentru această problemă. Este o funcție atașată unui câmp, care se execută înainte ca Pydantic să facă orice type checking sau conversie proprie. Primește inputul brut, neatins, exact așa cum a fost pasat modelului. Gândește-te la un scenariu în care modelul tău definește un câmp care necesită strict o listă de integers. Totuși, tu consumi un API extern care trimite incorect aceste date ca un singur string continuu de numere separate prin virgulă, cum ar fi stringul unu virgulă doi virgulă trei. Pydantic se așteaptă la un array, vede un singur string și îl respinge cu o eroare de validare. Repari asta scriind un validator Before. În interiorul funcției tale de validare, te uiți la inputul brut. Verifici dacă valoarea este un string. Dacă este, dai split acelui string la fiecare virgulă, ceea ce creează o listă de stringuri individuale. Nu trebuie să convertești tu acele caractere în integers. Pur și simplu returnezi lista nou creată. Pydantic preia controlul de acolo. Vede lista pe care o aștepta, rulează procesul standard de coercion intern și transformă acele valori de tip string în integers pentru tine. A trebuit doar să repari forma structurală a datelor. Asta acoperă inputurile care rulează înainte de logica principală. Următorul nivel de control este validatorul Wrap. Validatorii Wrap sunt cel mai flexibil tool de validare pe care îl oferă Pydantic. În loc să ruleze doar înainte de pasul de validare, un validator Wrap înconjoară la propriu motorul intern de validare din Pydantic pentru acel câmp. Când scrii un validator Wrap, funcția ta primește două argumente. Primul este inputul brut, la fel ca la validatorul Before. Al doilea argument este o funcție de tip handler. Acest handler reprezintă logica de bază de validare și coercion din Pydantic. Aici devine interesant. Tu decizi exact când, sau chiar dacă, acel handler rulează. Fluxul logic este în întregime în mâinile tale. Poți inspecta inputul brut și îl poți modifica. Apoi, apelezi explicit acel handler, pasându-i datele tale curățate. Pydantic rulează propriul type checking intern pe ceea ce ai furnizat și returnează valoarea complet parsată înapoi către validatorul tău. Apoi poți modifica din nou acea valoare parsată înainte de a o pasa modelului final. Pentru că tu controlezi când se execută acel handler, îl poți plasa într-un bloc standard try except. Dacă validarea internă din Pydantic aruncă o eroare, o prinzi chiar acolo, în validatorul Wrap. Poți să dai log la eroare, să modifici datele și să încerci din nou, sau pur și simplu să returnezi o valoare default sigură. Poți chiar să scrii o logică care dă skip complet la handler pentru anumite inputuri specifice, ocolind cu totul validarea standard. Validatorii Before sanitizează formele greșite de input pentru ca Pydantic să le poată citi, în timp ce validatorii Wrap îți oferă autoritate totală asupra întregului ciclu de validare din jurul unui singur câmp. Asta e tot pentru acest episod. Mulțumesc că m-ai ascultat și continuă să construiești!
11

Postprocesarea cu After și Plain Validators

3m 24s

Impune reguli stricte de logică de business. Vei învăța cum să folosești validatorii After pentru a verifica datele deja parsate și validatorii Plain pentru a scurtcircuita complet Pydantic.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Validarea datelor, episodul 11 din 20. Să verifici dacă un string arată ca un format de e-mail este simplu. Să verifici că datele respectă o logică de business strictă, cum ar fi să faci cross-referencing cu un sistem extern sau să impui reguli matematice specifice, necesită un loc sigur pentru a rula custom code. Exact asta oferă post-processing-ul cu validatorii After și Plain. Când definești un field într-un model Pydantic, librăria verifică automat input-ul în funcție de type hint. Tipurile te duc doar până la un anumit punct. Un integer este un integer, fie că este unu sau un milion. Pentru a impune reguli dincolo de tipurile de bază, adaugi funcții custom de validare. Pydantic îți permite să injectezi aceste funcții în lifecycle-ul de validare. Cel mai comun injection point este validatorul After. După cum sugerează și numele, acesta rulează după ce Pydantic termină parsing-ul intern și type coercion-ul. Aici e partea esențială. Când funcția ta custom primește datele într-un validator After, Pydantic garantează că datele se potrivesc deja cu tipul field-ului. Nu trebuie să scrii boilerplate code pentru a gestiona type conversion sau pentru a prinde data types neașteptate. Gândește-te la un scenariu în care trebuie să te asiguri că un field de tip integer este un număr par. Definești un model cu un field cu tipul integer. Apoi, scrii o funcție custom care primește o valoare ca argument. Pentru că configurezi această funcție ca un validator After, știi că valoarea este absolut un integer. Pur și simplu folosești operatorul modulo pentru a verifica dacă împărțirea valorii la doi lasă un rest. Dacă restul nu este zero, faci raise la un ValueError standard din Python cu un mesaj custom. Dacă restul este zero, returnezi valoarea. Pydantic preia acea valoare returnată și o atribuie modelului. Împărțirea sarcinilor este clară. Pydantic impune tipul, iar tu aplici regula de business. Uneori, parsing-ul default din Pydantic îți stă în cale. Aici intervine validatorul Plain. Un validator Plain înlocuiește complet validarea internă din Pydantic pentru un anumit field. Pydantic se dă la o parte și predă input-ul raw, nevalidat, direct funcției tale custom. Folosești un validator Plain atunci când regulile standard de coercion nu se potrivesc use case-ului tău, sau când ai de-a face cu o structură de date foarte custom pe care Pydantic nu o înțelege nativ. În acest scenariu, funcția ta este responsabilă pentru tot. Primește input-ul raw, face orice type checking necesar, convertește datele și aplică logica de business. Dacă ceva eșuează, funcția ta trebuie să facă raise la un ValueError sau un AssertionError. Dacă reușește, returnează valoarea finală, curată, pentru model. Atașezi ambii validatori la field-uri folosind decorators din Pydantic pe class methods, sau adăugându-i ca metadata direct în interiorul type hint-ului folosind annotations. Alegerea dintre ei se reduce la cât de mult din muncă vrei să faci singur. Folosește un validator After atunci când vrei ca Pydantic să facă munca grea de type conversion, și apelează la un validator Plain doar atunci când ai nevoie de control absolut asupra parsing-ului de input raw de la zero. Apreciez că asculți — ne auzim data viitoare.
12

Hook-uri de Validare la Nivel de Model

3m 28s

Validează interacțiunile dintre mai multe câmpuri. Vei învăța cum să folosești decoratorul model_validator pentru a impune reguli care depind de întregul payload.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Validarea datelor, episodul 12 din 20. Validarea field-urilor în mod izolat funcționează perfect, până în momentul în care logica ta de business dictează că field-ul B poate fi setat doar dacă field-ul A are o valoare specifică. Când integritatea datelor se bazează pe interacțiunea mai multor field-uri, ai nevoie de validation hooks la nivel de model. În Pydantic, gestionezi field-urile interdependente folosind decoratorul model validator. Spre deosebire de field validators, care se concentrează pe o singură bucată de date primite, un model validator analizează întreaga structură de date simultan. Pydantic oferă trei moduri pentru acest decorator: before, after și wrap. Acestea determină exact când se execută logica ta custom în timpul lifecycle-ului de parsing. Să aplicăm asta pe un model standard de înregistrare a utilizatorilor. Ai două field-uri: password și password repeat. O verificare la nivel de field poate verifica lungimea sau complexitatea, dar nu le poate compara pe cele două. Pentru asta, folosești un model validator în modul after. Modul after se execută după ce Pydantic a făcut parsing și a validat cu succes toate field-urile individuale. În această etapă, funcția ta de validare primește modelul instanțiat în sine. Pur și simplu scrii o logică care verifică dacă atributul password al modelului este egal cu atributul password repeat. Dacă diferă, dai raise la un value error. Aici e partea esențială. Când folosești modul after, funcția ta trebuie să returneze explicit instanța modelului, denumită de obicei self, la sfârșitul metodei. Dacă uiți să returnezi self, Pydantic va renunța la datele tale validate și nu va returna nimic. Uneori trebuie să interceptezi datele mai devreme. Aici intervine modul before. Un model validator în modul before rulează înainte ca Pydantic să încerce orice parsing sau type coercion. În loc de o instanță de model tipizată, funcția ta primește raw input-ul, care este de obicei un dictionary. Folosești acest mod atunci când structura de raw data este dezordonată și necesită ajustări înainte ca validarea standard să poată măcar începe. De exemplu, dacă request-urile de la un legacy API trimit configurațiile de password într-un nested dictionary, un before validator poate extrage acele string-uri și le poate da flatten în top-level keys pe care le așteaptă modelul tău Pydantic. Funcția returnează apoi dictionary-ul modificat, dându-l mai departe pe chain. Al treilea mod este wrap. Acesta este pentru control total asupra validation lifecycle-ului. Un wrap validator preia raw input data și o funcție handler. Rulezi logica ta de pre-processing, apelezi explicit handler-ul pentru a declanșa validarea internă din Pydantic, și apoi rulezi post-processing pe rezultat. Folosești asta atunci când trebuie să prinzi erorile interne de validare din Pydantic, să le dai log într-un sistem extern și, eventual, să returnezi un mesaj de eroare modificat sau un default fallback object. Alegerea modului potrivit este doar o chestiune de timing. Folosește before pentru a modela raw input-ul, after pentru a compara strongly typed fields, și wrap pentru a controla execuția validării în sine. Dacă găsești aceste episoade utile și vrei să susții emisiunea, poți căuta DevStoriesEU pe Patreon. Asta e tot pentru episodul ăsta. Ne auzim data viitoare!
13

Serializare: Exportarea Datelor în Siguranță

4m 01s

Controlează modul în care datele tale părăsesc sistemul. Vei învăța diferențele dintre exportarea în dicționare Python versus șiruri JSON și cum să excluzi câmpurile nesetate sau implicite.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Validarea datelor, episodul 13 din 20. Să introduci date valide în sistemul tău este doar jumătate din luptă. Când vine momentul să returnezi acele date către un frontend, adesea descoperi că payload-urile tale sunt pline de câmpuri goale și valori default pe care userul nu le-a furnizat niciodată. Serializarea, sau un dump de date făcut în siguranță, este modul prin care cureți acel flux de ieșire. Odată ce datele tale stau în siguranță într-un model Pydantic, la un moment dat trebuie să le extragi pentru a le trimite în altă parte. Ai două modalități principale de a face asta. Prima este să apelezi model dump. Această metodă îți citește modelul și returnează un dicționar Python simplu. A doua este să apelezi model dump json. Această metodă sare peste pasul cu dicționarul și returnează un string JSON complet formatat, gata să fie trimis prin rețea. Diferența dintre cele două merge puțin mai departe decât un simplu dicționar versus un string. Totul se reduce la modurile de serializare. By default, model dump operează în modul Python. Dacă modelul tău conține un tip complex, cum ar fi un obiect datetime, dicționarul rezultat va conține în continuare un obiect datetime din Python. Pe de altă parte, model dump json operează în modul JSON. JSON nu știe ce este un obiect datetime din Python, așa că Pydantic îl convertește automat într-o reprezentare standard de tip string. Aici e ideea cheie. Poți chiar să forțezi output-ul dicționarului să folosească modul JSON. Dacă apelezi model dump și pasezi argumentul mode setat pe json, Pydantic returnează un dicționar în care toate tipurile complexe au fost deja traduse în formate de bază, JSON-safe, cum ar fi string-uri și integer-uri. Asta rezolvă partea de tipuri, dar tot trebuie să gestionezi forma payload-ului. Ia ca exemplu un model de profil de user care returnează date către un frontend. Modelul ar putea defini douăzeci de câmpuri posibile. Un user nou își face cont și furnizează doar numele și adresa de email. Celelalte optsprezece câmpuri fac fallback la string-uri goale, null-uri sau URL-uri default de avatar. Dacă faci dump la acel model în mod normal, trimiți toate cele douăzeci de câmpuri către frontend. Pentru a repara asta, Pydantic oferă trei keyword arguments specifice pe care le poți pasa oricărei metode de dump. Cel mai precis este exclude unset. Când setezi exclude unset pe true, Pydantic urmărește exact ce câmpuri au fost populate la crearea modelului. Va face dump doar la nume și email. Cele optsprezece câmpuri default sunt complet omise din dicționar sau din string-ul JSON. Asta te asigură că nu faci leak niciodată la date de fallback pe care userul nu le-a trimis de fapt. Dacă vrei un comportament ușor diferit, poți folosi exclude defaults. Acest flag îi spune lui Pydantic să omită orice câmp care corespunde în prezent cu valoarea sa default. Nu ține cont dacă userul a trimis explicit acea valoare default sau dacă sistemul a completat-o automat. Dacă valoarea se potrivește cu cea default, este eliminată din output. În cele din urmă, există exclude none. Setează asta pe true, iar Pydantic va elimina orice câmp în care valoarea este în prezent none. Asta este pur și simplu o verificare a valorii și ignoră complet tracking-ul de valori default sau unset. Aceste flag-uri de excludere îți oferă un control strict asupra traficului de rețea și a răspunsurilor API. Păstrează-ți modelele interne complet cuprinzătoare, dar folosește metodele de dump pentru a te asigura că payload-urile externe rămân exact atât de curate pe cât trebuie să fie. Mersi că ne-ai ascultat. Pe data viitoare!
14

Personalizarea Logicii de Serializare

3m 28s

Schimbă modul în care tipurile tale sunt reprezentate la ieșire. Vei învăța cum să scrii serializatoare personalizate Field și Model pentru a muta datele în timpul fazei de exportare.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Validarea datelor, episodul 14 din 20. Ce se întâmplă dacă stochezi o dată intern ca un obiect Python datetime, dar acel API contract de pe frontend cere un Unix timestamp brut, de tip integer? Ai putea să iterezi prin date chiar înainte să le trimiți, dar asta e o soluție dezordonată și predispusă la erori. Varianta mai curată este să personalizezi logica de serializare direct în modelele tale Pydantic. Pydantic îți oferă decoratori pentru a intercepta momentul exact în care un model se transformă înapoi într-un dictionary sau JSON. Vom începe cu field serializers. Un field serializer vizează un atribut specific. Ca să creezi unul, scrii o metodă obișnuită în interiorul clasei modelului tău și pui decoratorul field serializer direct deasupra ei. Îi pasezi decoratorului numele câmpului pe care vrei să-l modifici. Să folosim acel scenariu cu datetime. Ai un model cu un atribut numit created at, care are tipul standard Python datetime. În interiorul modelului, creezi o metodă numită serialize created at. Numele metodei nu contează. Deasupra ei, pui decoratorul field serializer, care indică spre câmpul created at. Metoda primește valoarea datetime ca input. În interiorul metodei, apelezi funcția standard timestamp pe acel datetime și returnezi acel integer rezultat. Acum, ori de câte ori modelul dă dump la date, Pydantic interceptează câmpul created at, rulează metoda ta custom și scoate un integer curat în loc de un ISO formatted string. Iată ideea cheie. Acești serializers funcționează în două moduri distincte: plain și wrap. Modul plain este cel default. Când un serializer este în modul plain, Pydantic ignoră complet propria logică internă pentru acel câmp și rulează doar codul tău custom. Este un override complet. Dar uneori trebuie să rulezi mai întâi logica default, și apoi să modifici rezultatul. Sau poate vrei să prinzi erori în jurul comportamentului default. Atunci folosești modul wrap. Ca să-l activezi, pasezi mode equals wrap în decorator. În modul wrap, metoda ta primește un al doilea argument numit handler. Acest handler este o referință către logica internă de serializare din Pydantic. Poți apela acel handler ca să obții output-ul default, să-l inspectezi, să-l modifici sau să faci fall back la el dacă logica ta custom eșuează. Asta acoperă câmpurile individuale. Dacă trebuie să schimbi structura întregului output, folosești un model serializer. Setup-ul este aproape identic, dar decoratorul vine deasupra unei metode care operează pe întreaga instanță a modelului. În loc să primească valoarea unui singur câmp, metoda accesează atributele modelului în sine. Dacă pui un model serializer în modul plain, returnezi o structură de dictionary complet nouă, de la zero. Dacă îl pui în modul wrap, metoda ta primește un argument handler, la fel ca acel field serializer. Apelezi handler-ul ca să obții mai întâi acel dictionary standard al modelului. Apoi, poți adăuga noi top-level keys, poți elimina date private sau poți da flatten la nested structures înainte să returnezi acel dictionary final. Cel mai puternic aspect al acestor decoratori este că decuplează tipurile tale interne din Python de acele API contracts externe, menținând validarea strictă la intrare și formatarea precisă la ieșire. Asta e tot pentru acest episod. Mulțumesc pentru audiție și continuă să construiești!
15

Generarea JSON Schema din Modele

4m 24s

Transformă-ți modelele în contracte API care se autodocumentează. Vei învăța cum să generezi scheme JSON compatibile cu OpenAPI și să injectezi exemple direct în schemă.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Data Validation, episodul 15 din 20. Dacă schemele tale API sunt deja strictly typed în Python, să menții un fișier YAML separat pentru documentația OpenAPI este o pierdere enormă de timp. Ajungi să menții două surse de adevăr care inevitabil se desincronizează. Generarea de JSON Schema direct din modelele tale rezolvă această problemă de sincronizare. Fiecare model Pydantic vine cu o metodă numită model json schema. Când apelezi această metodă, Pydantic îți inspectează modelul. Citește câmpurile, tipurile, valorile default și constrângerile de validare. Apoi traduce toată acea logică internă din Python într-un dicționar standard JSON Schema. Mai exact, Pydantic emite versiunea Draft 2020-12 a specificației JSON Schema. Asta e partea care contează. Pentru că output-ul respectă acest standard larg acceptat, este compatibil nativ cu OpenAPI. Îți definești regulile stricte de validare o singură dată în Python, iar framework-ul îți oferă automat definiția exactă a schemei de care au nevoie consumatorii tăi externi. Nu este nevoie de nicio traducere manuală. Generarea standard de scheme gestionează perfect tipurile și constrângerile de bază. Dar uneori trebuie să comunici business logic sau formate specifice care nu pot fi deduse doar dintr-un type hint din Python. Gândește-te la un scenariu în care construiești un model Configuration pentru un serviciu nou. Modelul conține un câmp care acceptă un dicționar de setări custom. Echipa de frontend trebuie să știe exact cum arată un payload valid, în loc să știe doar că este un obiect generic. Pentru a rezolva asta, folosești un feature numit json schema extra. Acest parametru îți permite să injectezi metadate custom arbitrare direct în JSON Schema generată. Îl poți folosi pentru a adăuga exemple mock, descrieri custom sau markere specifice de keyword pe care le-ar putea cere API gateway-ul tău. Poți aplica json schema extra la două niveluri distincte. Îl poți atașa unui câmp individual sau îl poți aplica întregului model. Pentru a oferi un exemplu mock pentru acel câmp specific de setări, îți definești modelul Configuration. Pentru atributul complex settings, îi atribui o funcție Field. În interiorul acelei funcții Field, oferi argumentul json schema extra. Îi pasezi un dicționar care conține cheia standard din JSON Schema numită examples. Valoarea mapată la acea cheie este o listă care conține exact payload-ul tău de configurare mock. Alternativ, dacă vrei să documentezi întregul model în loc de un singur câmp, definești un dicționar model config pe clasă. În interiorul acelui dicționar de configurare, oferi json schema extra cu un exemplu la nivel de schemă. Abordarea asta este foarte utilă atunci când vrei să arăți cum interacționează mai multe câmpuri împreună într-un request body complet. Când execuți model json schema pe modelul tău Configuration, Pydantic construiește arborele standard de schemă. Când ajunge la câmpurile sau la configurația modelului tău, face merge la dicționarul tău de exemple custom direct în output-ul standard. Tooling-ul de frontend citește această schemă, face parse la proprietatea examples și afișează imediat payload-ul mock dezvoltatorilor. Ei știu exact ce să trimită, iar codul tău Python rămâne singura sursă de adevăr. Adevărata putere a generării de scheme din Pydantic este că orice tool extern construit pentru ecosistemul JSON Schema poate consuma imediat regulile tale de validare din Python fără o integrare custom. Mulțumesc că ai petrecut câteva minute cu mine. Până data viitoare, numai bine.
16

RootModel: Când Payload-ul Tău Nu Este un Dicționar

3m 43s

Gestionează elegant payload-urile JSON non-standard. Vei descoperi cum RootModel îți permite să parsezi array-uri și primitive la nivel de rădăcină, păstrând în același timp puterile BaseModel.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Validarea datelor, episodul 16 din 20. Modelele standard presupun că payload-ul JSON primit este un obiect mapat cu chei și valori. Dar ce se întâmplă când un endpoint trebuie să accepte direct un array top-level, sau doar un string independent, fără să-l împacheteze într-un dictionary? Exact asta este conceput să gestioneze RootModel: When Your Payload Isn't a Dictionary. Când folosești un base model standard, Pydantic mapează atributele clasei tale la chei JSON. Dacă îi trimiți unui model standard o listă raw, cum ar fi un array JSON de numere, validarea eșuează. Se așteaptă la o structură de dictionary. Pentru a ocoli asta, developerii obligă adesea clientul să modifice payload-ul. Ei creează o cheie dummy, poate numită items, și împachetează array-ul într-un obiect. Ajungi să-ți modifici designul API-ului doar pentru a face librăria de validare fericită. RootModel elimină această fricțiune. Este un model Pydantic conceput special pentru payload-uri în care structura exterioară este o listă, un tuple, sau un tip primitiv, cum ar fi un integer sau un string. Gândește-te la un endpoint de bulk-delete. Vrei ca clientul să trimită un array JSON raw care conține user ID-uri de tip integer, și nimic altceva. Pentru a gestiona asta, imporți RootModel din Pydantic. Definești o clasă nouă, poate numită UserIdList, care moștenește din RootModel. Parametrizezi această moștenire cu o listă de integeri. Când array-ul JSON raw ajunge la server, îl transmiți direct metodei model validate de pe clasa ta UserIdList. Pydantic acceptă nativ array-ul top-level. Iterează prin payload, se asigură că fiecare item este un integer valid, și returnează o instanță de model complet validată. Iată ideea cheie. Chiar dacă validează o listă flat, un RootModel oferă exact aceeași interfață ca un model obișnuit. Ai în continuare acces la metodele standard. Poți apela model dump pentru a converti datele înapoi în obiecte Python, sau model dump json pentru a genera un string raw. Deoarece nu există field-uri numite în payload-ul tău, ai nevoie de o modalitate de a accesa datele odată ce sunt validate. Pydantic stochează datele parsate într-un singur atribut numit exact root. Dacă vrei să faci un loop peste acele user ID-uri validate, pur și simplu iterezi peste atributul root de pe instanța modelului tău. Acest mecanism nu este limitat la liste. Poți defini un RootModel pentru un singur string sau un integer. Dacă primești un payload de tip string independent, dar trebuie să-l treci prin verificări stricte de lungime sau pattern matching, definirea lui ca un RootModel de tip string îți permite să atașezi nativ acele reguli de validare. Datele rămân un simplu string în payload, dar beneficiază de protecția completă a motorului de validare. Ori de câte ori te trezești că inventezi o cheie de dictionary doar pentru ca Pydantic să aibă ceva de parsat, folosești tool-ul greșit. Folosește RootModel pentru a-ți adapta layer-ul de validare la contractul API, în loc să-ți modifici contractul API pentru a satisface layer-ul de validare. Mulțumesc pentru ascultare. Aveți grijă de voi, tuturor.
17

Dataclasses Standard vs Pydantic Dataclasses

3m 41s

Adu validarea în clasele tale native Python. Vei învăța când să folosești decoratorul dataclass din Pydantic pentru a moderniza bazele de cod vechi fără a rescrie totul.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Validarea datelor, episodul 17 din 20. Ai un codebase masiv construit în întregime pe dataclasses standard din Python și îți dai seama că ai nevoie disperată de runtime validation. S-ar putea să crezi că trebuie să rescrii totul pentru a moșteni dintr-un BaseModel. Nu e așa. Astăzi, ne uităm la dataclasses standard versus dataclasses din Pydantic. Standard library-ul din Python oferă un decorator dataclass care este excelent pentru reducerea boilerplate-ului. Îți scrie automat metodele de inițializare, reprezentare și egalitate. Totuși, are încredere oarbă în inputurile tale. Dacă declari un atribut age ca integer și îi pasezi un string, dataclass-ul standard acceptă pur și simplu acel string. Oferă type hints pentru static analysis, dar oferă zero runtime safety. Pydantic rezolvă asta cu propriul său decorator dataclass. Este conceput special ca un drop-in replacement pentru versiunea din standard library. Îți păstrezi exact aceeași structură a clasei. Nu adaugi nicio base class. Pur și simplu îți schimbi import statement-ul pentru a trage decoratorul din modulul pydantic dot dataclasses în loc de standard library. Gândește-te la acel legacy codebase construit pe dataclasses standard. Găsești un dataclass care gestionează un obiect de configurare. Schimbi decoratorul standard cu decoratorul Pydantic. Instantaneu, ori de câte ori aplicația ta creează acel obiect de configurare, Pydantic interceptează inițializarea. Citește type hints-urile existente și le aplică. Dacă este pasat un tip invalid, Pydantic încearcă să-i facă type coercion. Dacă acest coercion eșuează, aruncă imediat o eroare de validare. Obții atribuiri stricte, type-checked, cu zero modificări structurale la inheritance tree-ul tău. Iată ideea cheie. Dacă ambele opțiuni îți oferă validare, trebuie să înțelegi diferența dintre un dataclass Pydantic și un BaseModel standard. Ele gestionează datele din spate în mod diferit. Un BaseModel este construit fundamental în jurul dictionary parsing-ului și oferă o gamă largă de built-in methods pentru exportarea datelor. Un dataclass Pydantic rămâne la bază o clasă Python standard, păstrându-și memory footprint-ul și comportamentul tradițional. Pentru că rămâne o clasă standard, modul în care Pydantic aplică validarea se schimbă. Când instanțiezi un dataclass Pydantic, argumentele sunt copiate. Datele trec prin core validation engine-ul din Pydantic, care face parse și construiește obiecte noi pentru a se potrivi cu type hints-urile tale. Nu face doar o referință la inputurile mutabile originale pe care le-ai furnizat. Dacă pasezi o listă într-un dataclass Pydantic, validatorul o procesează, validează elementele interne și atribuie o listă complet nouă instanței. Lista de input originală și atributul de pe dataclass-ul tău nu mai sunt același obiect în memorie. Acest comportament de copiere asigură că datele tale respectă cu strictețe schema, fără a modifica variabilele de input originale. Utilitatea de bază a unui dataclass Pydantic este de a face o punte între paradigmele standard din Python și validarea riguroasă. Dacă ai nevoie de un migration path curat pentru legacy code care folosește deja dataclasses standard, pur și simplu schimbă decoratorul pentru a obține type safety instant, păstrând în același timp toată semantica existentă a clasei. Dacă îți place podcastul și vrei să susții emisiunea, poți căuta DevStoriesEU pe Patreon. Asta e tot pentru acest episod. Mulțumesc că ai ascultat și continuă să construiești!
18

Ajustarea Fină a Configurației Modelului

3m 23s

Controlează strictețea întregului tău model. Vei învăța cum să folosești ConfigDict pentru a interzice atributele suplimentare, a îngheța instanțele și a valida atribuirile.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Validarea datelor, episodul 18 din 20. În mod implicit, Pydantic ignoră în tăcere orice chei JSON extra pe care i le trimiți. Într-un API strict, să înghiți date necunoscute fără avertisment este un risc masiv de securitate. Pentru a repara asta, ai nevoie de fine-tuning la configurația modelului. Pentru a schimba modul în care un model se comportă global, definești un atribut de clasă numit model config. Îi atribui un ConfigDict, care este un dicționar tipizat importat direct din Pydantic. Pui această atribuire chiar în interiorul modelului tău, alături de definițiile câmpurilor. Pentru că ConfigDict este tipizat, editorul tău de cod va prinde typo-urile dacă încerci să pasezi o opțiune de configurare invalidă. Orice reguli pui în acest dicționar vor dicta modul în care întregul model parsează, validează și stochează datele. Hai să construim un model strict de setări de securitate pentru o aplicație. Un client malițios ar putea trimite un payload JSON cu câmpuri neașteptate, încercând poate să injecteze un flag de admin sau să suprascrie un parametru ascuns. În mod implicit, Pydantic setează comportamentul pentru câmpurile extra pe ignore. Citește câmpurile pe care le așteaptă, dă drop complet și în tăcere datelor necunoscute, și creează modelul. Ca să închizi această portiță, adaugi parametrul extra în ConfigDict-ul tău și îi setezi valoarea la string-ul forbid. Acum, dacă un client trimite o cheie neașteptată, Pydantic aruncă imediat o eroare de validare. Request-ul pică din start, respingând explicit payload-ul greșit înainte ca logica aplicației tale măcar să îl proceseze. Asta gestionează granița dintre lumea exterioară și sistemul tău. Dar ce se întâmplă în interiorul sistemului tău după ce modelul este creat? În mod normal, Pydantic validează datele doar în timpul inițializării. Dacă un alt developer scrie cod care modifică mai târziu un atribut pe o instanță de model existentă, Pydantic nu intervine. Ai putea atribui accidental un raw string unui câmp integer, iar modelul l-ar accepta. Ca să previi asta, poți seta validate assignment pe true în ConfigDict-ul tău. Cu opțiunea asta activată, de fiecare dată când un atribut este modificat în memorie, Pydantic interceptează schimbarea și rulează exact aceeași logică de validare pe care o folosește la creare. Uneori, chiar și validarea mutațiilor este prea permisivă pentru configurațiile de securitate. S-ar putea să vrei o garanție absolută că setările nu pot fi modificate în memorie de nicio parte a codului tău, odată ce trec de verificarea inițială. Aici devine interesant. Poți seta parametrul frozen pe true în configurația modelului tău. Asta face ca întreaga instanță a modelului să fie imutabilă. Dacă orice funcție downstream încearcă să facă update unui câmp, Pydantic aruncă o eroare. Un model frozen se comportă exact ca un tuple în Python. Pentru că nu se poate schimba, un model frozen este complet sigur să fie partajat între diferite părți ale aplicației tale și poate fi chiar folosit în siguranță ca o cheie într-un dicționar Python sau într-un in-memory cache. Prin combinarea acestor opțiuni de configurare în ConfigDict-ul tău, transformi un model dintr-un data parser flexibil într-o graniță absolută, de neclintit. Asta e tot pentru acest episod. Mulțumesc pentru ascultare și continuă să construiești!
19

Configurarea Aplicației cu Pydantic Settings

3m 27s

Gestionează-ți variabilele de mediu ca un profesionist. Vei învăța cum pachetul pydantic-settings automatizează parsarea secretelor, a fișierelor dot-env și a prefixelor.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Data Validation, episodul 19 din 20. Nu mai scoate string-uri din sistemul de operare, ținând pumnii strânși să se facă cast curat la un integer. Probabil ai scris zeci de fișiere utilitare care fac wrap peste apelurile standard de variabile de mediu, doar pentru a preveni ca o valoare de configurare lipsă să îți dea crash la aplicație la runtime. Configurarea aplicației cu Pydantic Settings înlocuiește tot acel boilerplate. În timp ce Pydantic standard se ocupă de validarea generală a datelor, gestionarea variabilelor de mediu necesită instalarea pachetului separat pydantic-settings. Acest pachet oferă o clasă specifică numită BaseSettings. În loc să faci fetch manual la variabile și să scrii logică de parsing custom, declari o clasă care moștenește din BaseSettings. Îți definești câmpurile de configurare exact ca la un model Pydantic standard, complet cu type hints din Python și valori default. Când instanțiezi această clasă, Pydantic citește automat variabilele de mediu din sistem. Mapează numele variabilelor la atributele clasei tale, case-insensitive by default. Dacă ai definit un câmp timeout pentru baza de date ca integer, iar variabila de mediu furnizează un string, Pydantic face coerce acelui string într-un obiect integer real. Dacă variabila de mediu conține text arbitrar în loc de un număr, Pydantic aruncă o eroare de validare clară imediat la startup-ul aplicației. Programul tău dă fail fast, în loc să ia crash imprevizibil mai târziu, în timpul unui apel activ către baza de date. În environment-uri mai mari, numele variabilelor globale au frecvent coliziuni. S-ar putea să ai mai multe servicii care rulează pe același host, toate căutând o variabilă numită pur și simplu database URL. BaseSettings rezolvă asta permițându-ți să definești un environment prefix în configurarea modelului. Dacă setezi prefixul la app underscore, Pydantic nu mai caută potriviri exacte pe numele câmpului. În schimb, pentru a popula un câmp numit database URL, va căuta specific variabila de mediu app underscore database URL. Codul aplicației tale Python accesează în continuare proprietatea pur și simplu ca database URL, ascunzând complet prefixul sistemului de operare de business logic-ul tău. Aici este ideea principală. Nu trebuie să îți aplatizezi obiectele Python doar ca să citești variabile de mediu. Configurarea devine adesea complexă, necesitând structuri de date nested. S-ar putea să ai o clasă principală de setări care include un sub-model dedicat pentru setările bazei de date, și un altul pentru logging. Pydantic suportă rezolvarea acestor structuri nested folosind o convenție cu double underscore. Dacă clasa ta principală de setări are un câmp numit database, care la rândul lui indică spre un model ce conține un câmp timeout, Pydantic va căuta o variabilă de mediu numită database double underscore timeout. Dacă folosești un prefix, îl va adăuga natural la început, rezultând ceva de genul app underscore database double underscore timeout. Acest mecanism îți permite să menții obiecte de configurare ierarhice, strictly typed, în codul sursă, în timp ce le mapezi curat la variabile de mediu standard, flat. Adevărata valoare a BaseSettings nu constă doar în eliminarea codului boilerplate, ci în garantarea faptului că, dacă aplicația ta pornește cu succes, întreaga sa stare de configurare este complet prezentă, explicitly typed și complet sigură pentru a fi consumată. Mulțumesc pentru audiție, happy coding tuturor!
20

Sub Capotă: Core Schemas Personalizate

3m 36s

Acesta este ultimul episod al seriei! Preia controlul suprem asupra motorului de validare. Vei învăța cum să scrii o metodă __get_pydantic_core_schema__ pentru a învăța nucleul Rust cum să gestioneze obiecte Python complet străine.

Descarcă
Salut, sunt Alex de la DEV STORIES DOT EU. Pydantic: Validarea datelor, episodul 20 din 20. Aduci o library rigidă, nedocumentată, de la o altă echipă și trebuie să-i treci obiectele prin pipeline-ul tău strict de validare. Obiectul nu are absolut nicio noțiune despre Pydantic și nu te poți atinge de codul lui sursă. Când adnotările și validatorii simpli nu sunt de ajuns, trebuie să vorbești direct cu engine-ul — iar asta înseamnă să deschizi capota ca să scrii core schemas custom. În mod normal, Pydantic își dă seama cum să-ți valideze datele citind type hints. Când îi dai un obiect străin, se lovește de un zid. Ca să rezolvi asta, definești o metodă numită dunder get pydantic core schema. Metoda asta acționează ca un layer de traducere directă. Trece peste wrapper-ele Python high-level și trimite instrucțiuni direct în Pydantic Core, engine-ul Rust din spate care gestionează logica efectivă de validare. Când implementezi metoda asta, ea primește tipul sursă și un handler. Handler-ul funcționează exact ca un middleware într-un web framework. Nu trebuie să scrii toată schema de validare de la zero. Poți să-i ceri handler-ului să genereze schema default pentru un anumit tip, iar apoi să faci wrap cu propria ta logică custom peste acel output. Ia ca exemplu wrapper-ul legacy de conexiune la baza de date. Să presupunem că singurul mod de a inițializa obiectul ăsta e să-i pasezi un anumit integer, cum ar fi un ID de conexiune. Vrei ca Pydantic să accepte un integer dintr-un API request, să-l valideze și să-ți returneze obiectul de conexiune complet instanțiat. Pentru că nu poți modifica direct clasa legacy, definești un tip custom folosind adnotări Python. În interiorul acelei adnotări, pui metoda ta de core schema custom. Aici e ideea cheie. În loc să scrii dicționare raw, folosești modulul core schema din Pydantic, care oferă funcții helper ca să construiești structurile astea în siguranță. Mai întâi, îi ceri handler-ului să construiască o schemă de integer standard. Apoi, construiești o chain schema. Îi spui engine-ului să ruleze mai întâi validarea standard de integer. Dacă input-ul este într-adevăr un integer, engine-ul îl pasează într-o funcție Python custom pe care o oferi tu. Funcția asta ia ID-ul de conexiune, inițializează wrapper-ul legacy pentru baza de date și returnează obiectul. La final, adaugi o instance check schema la chain, asigurându-te că output-ul final este exact clasa legacy pe care o aștepți. Aici devine interesant. Returnezi structura asta nested către Pydantic. Sub capotă, Pydantic ia aceste definiții de dicționare nested și le compilează într-un execution graph nativ de Rust. Ai programat engine-ul Rust din Python, spunându-i pas cu pas cum să preia un integer raw, să-l valideze și să construiască în siguranță un obiect străin la viteză maximă. Ăsta reprezintă cel mai low-level nivel de integrare pe care îl oferă Pydantic, dându-ți control total asupra validation tree-ului fără să sacrifici performanța. Pentru că ăsta e ultimul nostru episod, te încurajez serios să te scufunzi în documentația oficială Pydantic și să încerci să construiești o core schema custom hands-on. E cel mai bun mod de a consolida felul în care engine-ul gândește de fapt. De asemenea, poți vizita dev stories dot eu ca să sugerezi subiecte pe care vrei să le acoperim în seriile viitoare. Asta e tot pentru azi. Mulțumesc că m-ai ascultat — du-te și construiește ceva cool.