-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlecture_11.py
More file actions
126 lines (102 loc) · 3.61 KB
/
lecture_11.py
File metadata and controls
126 lines (102 loc) · 3.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
from pydantic import BaseModel, ValidationError, Field, EmailStr, HttpUrl, SecretStr, computed_field, field_validator, model_validator
from datetime import datetime, UTC
from functools import partial
from uuid import UUID, uuid4
from typing import Literal,Annotated
class User(BaseModel):
uid : UUID = Field(default_factory=uuid4)
username : Annotated[str, Field(min_length=3, max_length=20)]
email : EmailStr
age : Annotated[int, Field(ge=13,le=130)]
website : HttpUrl | None = None
password : SecretStr
verified_at : datetime | None = None
bio : str = ""
is_active : bool = True
full_name : str | None = None
first_name : str | None = None
last_name : str | None = None
followers_count : int = 0
@field_validator("username")
@classmethod
def validate_username(cls, v : str) -> str:
if not v.replace("_","").isalnum():
raise ValueError("Username must be alphanumeric or contain underscores")
return v.lower()
@field_validator("website", mode="before")
@classmethod
def add_https(cls, v : str | None) -> str | None:
if v and not v.startswith(("http://","https://")):
return f"https://{v}"
return v
@computed_field
@property
def display_name(self) -> str:
if self.first_name and self.last_name:
return f"{self.first_name} {self.last_name}"
return self.username
@computed_field
@property
def is_influencer(self) -> bool:
return self.followers_count >= 10000
class Comment(BaseModel):
content : str
author_email : EmailStr
likes : int = 0
class BlogPost(BaseModel):
title : Annotated[str, Field(min_length=1,max_length=200)]
content : Annotated[str, Field(min_length=20)]
author : User
view_count : int = 0
is_published : bool = False
tags : list[str] = Field(default_factory=list)
# create_at : datetime = Field(default_factory=lambda : datetime.now(tz=UTC))
# both will do same work lambda or partial function
create_at : datetime = Field(default_factory=partial(datetime.now,tz=UTC))
author_id : str | int | None = None
status : Literal["draft", "published", "archived"] = "draft"
slug : Annotated[str, Field(pattern=r"^[a-z0-9-]+$")]
comments : list[Comment] = Field(default_factory=list)
class UserRegistration(BaseModel):
email : EmailStr
password : str
confirm_password : str
@model_validator(mode="after")
def passwords_match(self) -> "UserRegistration":
if self.password != self.confirm_password:
raise ValueError("Passwords do not match")
return self
user = User(
username="Ashwini_123",
email="[email protected]",
age=25,
password="mysecretpassword",
website="www.ashwini.com",
# first_name="Ashwini",
# last_name="Samal",
# followers_count=15000,
)
# print(user.display_name) # Output: Ashwini Samal
# print(user.is_influencer) # Output: True
# print(user.model_dump_json(indent=2))
post_data = {
"title": "Understanding Pydantic Models",
"content": "Pydantic makes data validation easy and intuitive...",
"slug": "understanding-pydantic",
"author": user,
"author_id": "coreyms-1",
"comments": [
{
"content": "I think I understand nested models now!",
"author_email": "[email protected]",
"likes": 25,
},
{
"content": "Can you cover FastAPI next?",
"author_email": "[email protected]",
"likes": 15,
},
],
}
post = BlogPost(**post_data)
print(post.model_dump_json(indent=2))