forked from mongodb/docs-sample-apps
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodels.py
More file actions
159 lines (134 loc) · 4.71 KB
/
models.py
File metadata and controls
159 lines (134 loc) · 4.71 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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
from pydantic import BaseModel, Field
from datetime import datetime
from typing import Optional, TypeVar, Generic, Any
T = TypeVar("T")
class Awards(BaseModel):
wins: Optional[int] = None
nominations: Optional[int] = None
text: Optional[str] = None
class Imdb(BaseModel):
rating: Optional[float] = None
votes: Optional[int] = None
id: Optional[int] = None
class Movie(BaseModel):
id: Optional[str] = Field(alias="_id")
title: str
year: Optional[int] = None
plot: Optional[str] = None
fullplot: Optional[str] = None
released: Optional[datetime] = None
runtime: Optional[int] = None
poster: Optional[str] = None
genres: Optional[list[str]] = None
directors: Optional[list[str]] = None
writers: Optional[list[str]] = None
cast: Optional[list[str]] = None
countries: Optional[list[str]] = None
languages: Optional[list[str]] = None
rated: Optional[str] = None
awards: Optional[Awards] = None
imdb: Optional[Imdb] = None
model_config = {
"populate_by_name" : True
}
'''
So this an interesting conversion. Pydanic doesn't cleanly support constructing
models that have MongoDB query operators as field names. This becomes an issue when
we want to convert the validated model back to a dictionary to use as a MongoDB query filter.
For example, if a user leaves the 'q' parameter blank, we don't want to include the '$text' operator
in the filter at all but validation will send an empty value for it and that causes errors. So
I am handling the validation in the query router itself, but leaving this here as an example of how
it could be done, if I am wrong about Pydantic's capabilities.
'''
class TextFilter(BaseModel):
search: str = Field(..., alias="$search")
class RegexFilter(BaseModel):
regex: str = Field(..., alias="$regex")
options: Optional[str] = Field(None, alias="$options")
class RatingFilter(BaseModel):
gte: Optional[float] = Field(None, alias="$gte")
lte: Optional[float] = Field(None, alias="$lte")
class Pagination(BaseModel):
page: int
limit: int
total: int
pages: int
class CreateMovieRequest(BaseModel):
title: str
year: Optional[int] = None
plot: Optional[str] = None
fullplot: Optional[str] = None
genres: Optional[list[str]] = None
directors: Optional[list[str]] = None
writers: Optional[list[str]] = None
cast: Optional[list[str]] = None
countries: Optional[list[str]] = None
languages: Optional[list[str]] = None
rated: Optional[str] = None
runtime: Optional[int] = None
poster: Optional[str] = None
class UpdateMovieRequest(BaseModel):
title: Optional[str] = None
year: Optional[int] = None
plot: Optional[str] = None
fullplot: Optional[str] = None
genres: Optional[list[str]] = None
directors: Optional[list[str]] = None
writers: Optional[list[str]] = None
cast: Optional[list[str]] = None
countries: Optional[list[str]] = None
languages: Optional[list[str]] = None
rated: Optional[str] = None
runtime: Optional[int] = None
poster: Optional[str] = None
class MovieFilter(BaseModel):
_id: Optional[Any] = None # Support for MongoDB ID queries like { $in: [...] }
title: Optional[str] = None
year: Optional[int] = None
plot: Optional[str] = None
fullplot: Optional[str] = None
genres: Optional[list[str]] = None
directors: Optional[list[str]] = None
writers: Optional[list[str]] = None
cast: Optional[list[str]] = None
countries: Optional[list[str]] = None
languages: Optional[list[str]] = None
rated: Optional[str] = None
runtime: Optional[int] = None
poster: Optional[str] = None
class SearchMoviesResponse(BaseModel):
movies: list[Movie]
totalCount: int
class VectorSearchResult(BaseModel):
id: Optional[str] = Field(alias="_id")
title: str
plot: Optional[str] = None
poster: Optional[str] = None
year: Optional[int] = None
genres: Optional[list[str]] = None
directors: Optional[list[str]] = None
cast: Optional[list[str]] = None
score: float
model_config = {
"populate_by_name": True
}
class SuccessResponse(BaseModel, Generic[T]):
success: bool = True
message: Optional[str]
data: T
timestamp: str
pagination: Optional[Pagination] = None
class ErrorDetails(BaseModel):
message: str
code: Optional[str]
details: Optional[Any] = None
class BatchUpdateRequest(BaseModel):
filter: MovieFilter
update: UpdateMovieRequest
class BatchDeleteRequest(BaseModel):
filter: MovieFilter
class ErrorResponse(BaseModel):
success: bool = False
message: str
error: ErrorDetails
timestamp: str