4
4
from dataclasses import dataclass , field
5
5
from datetime import date , datetime
6
6
from enum import Enum
7
- from typing import (
8
- TYPE_CHECKING ,
9
- Any ,
10
- ClassVar ,
11
- Dict ,
12
- Generic ,
13
- List ,
14
- Literal ,
15
- Optional ,
16
- Type ,
17
- TypeVar ,
18
- cast ,
19
- )
7
+ from typing import Any , Dict , List , Literal , Optional , Type , cast
20
8
from uuid import UUID
21
9
22
10
import marshmallow_dataclass
23
11
from marshmallow import (
24
- EXCLUDE ,
25
- Schema ,
26
12
ValidationError ,
27
13
fields ,
28
14
post_dump ,
29
15
post_load ,
30
16
pre_load ,
31
17
validate ,
32
18
)
33
- from typing_extensions import Self
34
19
35
20
from .config import (
36
21
DEFAULT_PRE_COMMIT_MESSAGE ,
39
24
DOCUMENT_SIZE_THRESHOLD_BYTES ,
40
25
MULTI_DOCUMENT_LIMIT ,
41
26
)
42
-
43
-
44
- if TYPE_CHECKING :
45
- import requests
46
-
47
-
48
- class ToDictMixin :
49
- """
50
- Provides a type-safe `to_dict()` method for classes using Marshmallow
51
- """
52
-
53
- SCHEMA : ClassVar [Schema ]
54
-
55
- def to_dict (self ) -> Dict [str , Any ]:
56
- return cast (Dict [str , Any ], self .SCHEMA .dump (self ))
57
-
58
-
59
- class FromDictMixin :
60
- """This class must be used as an additional base class for all classes whose schema
61
- implements a `post_load` function turning the received dict into a class instance.
62
-
63
- It makes it possible to deserialize an object using `MyClass.from_dict(dct)` instead
64
- of `MyClass.SCHEMA.load(dct)`. The `from_dict()` method is shorter, but more
65
- importantly, type-safe: its return type is an instance of `MyClass`, not
66
- `list[Any] | Any`.
67
-
68
- Reference: https://marshmallow.readthedocs.io/en/stable/quickstart.html#deserializing-to-objects E501
69
- """
70
-
71
- SCHEMA : ClassVar [Schema ]
72
-
73
- @classmethod
74
- def from_dict (cls , dct : Dict [str , Any ]) -> Self :
75
- return cast (Self , cls .SCHEMA .load (dct ))
76
-
77
-
78
- class BaseSchema (Schema ):
79
- class Meta :
80
- ordered = True
81
- unknown = EXCLUDE
82
-
83
-
84
- class Base (ToDictMixin ):
85
- def __init__ (self , status_code : Optional [int ] = None ) -> None :
86
- self .status_code = status_code
87
-
88
- def to_json (self ) -> str :
89
- """
90
- to_json converts model to JSON string.
91
- """
92
- return cast (str , self .SCHEMA .dumps (self ))
93
-
94
- @property
95
- def success (self ) -> bool :
96
- return self .__bool__ ()
97
-
98
- def __bool__ (self ) -> bool :
99
- return self .status_code == 200
27
+ from .models_utils import (
28
+ Base ,
29
+ BaseSchema ,
30
+ FromDictMixin ,
31
+ PaginationParameter ,
32
+ SearchParameter ,
33
+ ToDictMixin ,
34
+ )
100
35
101
36
102
37
class DocumentSchema (BaseSchema ):
@@ -1148,44 +1083,6 @@ class AccessLevel(str, Enum):
1148
1083
RESTRICTED = "restricted"
1149
1084
1150
1085
1151
- class PaginationParameter (ToDictMixin ):
1152
- """Pagination mixin used for endpoints that support pagination."""
1153
-
1154
- cursor : str = ""
1155
- per_page : int = 20
1156
-
1157
-
1158
- class SearchParameter (ToDictMixin ):
1159
- search : Optional [str ] = None
1160
-
1161
-
1162
- PaginatedData = TypeVar ("PaginatedData" , bound = FromDictMixin )
1163
-
1164
-
1165
- @dataclass
1166
- class CursorPaginatedResponse (Generic [PaginatedData ]):
1167
- status_code : int
1168
- data : List [PaginatedData ]
1169
- prev : Optional [str ] = None
1170
- next : Optional [str ] = None
1171
-
1172
- @classmethod
1173
- def from_response (
1174
- cls , response : "requests.Response" , data_type : Type [PaginatedData ]
1175
- ) -> "CursorPaginatedResponse[PaginatedData]" :
1176
- data = cast (
1177
- List [PaginatedData ], [data_type .from_dict (obj ) for obj in response .json ()]
1178
- )
1179
- paginated_response = cls (status_code = response .status_code , data = data )
1180
-
1181
- if previous_page := response .links .get ("prev" ):
1182
- paginated_response .prev = previous_page ["url" ]
1183
- if next_page := response .links .get ("next" ):
1184
- paginated_response .prev = next_page ["url" ]
1185
-
1186
- return paginated_response
1187
-
1188
-
1189
1086
@dataclass
1190
1087
class MembersParameters (PaginationParameter , SearchParameter , ToDictMixin ):
1191
1088
"""
@@ -1228,6 +1125,11 @@ class Member(Base, FromDictMixin):
1228
1125
1229
1126
1230
1127
class MemberSchema (BaseSchema ):
1128
+ """
1129
+ This schema cannot be done through marshmallow_dataclass as we want to use the
1130
+ values of the AccessLevel enum to create the enum field
1131
+ """
1132
+
1231
1133
id = fields .Int (required = True )
1232
1134
access_level = fields .Enum (AccessLevel , by_value = True , required = True )
1233
1135
email = fields .Str (required = True )
@@ -1249,6 +1151,11 @@ def return_member(
1249
1151
1250
1152
1251
1153
class UpdateMemberSchema (BaseSchema ):
1154
+ """
1155
+ This schema cannot be done through marshmallow_dataclass as we want to use the
1156
+ values of the AccessLevel enum to create the enum field
1157
+ """
1158
+
1252
1159
id = fields .Int (required = True )
1253
1160
access_level = fields .Enum (AccessLevel , by_value = True , allow_none = True )
1254
1161
active = fields .Bool (allow_none = True )
@@ -1323,14 +1230,10 @@ class CreateTeam(Base, FromDictMixin):
1323
1230
description : Optional [str ] = ""
1324
1231
1325
1232
1326
- class CreateTeamSchema (BaseSchema ):
1327
- many = False
1328
-
1329
- name = fields .Str (required = True )
1330
- description = fields .Str (allow_none = True )
1331
-
1332
- class Meta :
1333
- exclude_none = True
1233
+ CreateTeamSchema = cast (
1234
+ Type [BaseSchema ],
1235
+ marshmallow_dataclass .class_schema (CreateTeam , base_schema = BaseSchema ),
1236
+ )
1334
1237
1335
1238
1336
1239
CreateTeam .SCHEMA = CreateTeamSchema ()
0 commit comments