fastapi-rtk 1.0.0__py3-none-any.whl → 1.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fastapi_rtk/api/model_rest_api.py +101 -58
- fastapi_rtk/manager.py +2 -0
- {fastapi_rtk-1.0.0.dist-info → fastapi_rtk-1.0.1.dist-info}/METADATA +1 -1
- {fastapi_rtk-1.0.0.dist-info → fastapi_rtk-1.0.1.dist-info}/RECORD +7 -7
- {fastapi_rtk-1.0.0.dist-info → fastapi_rtk-1.0.1.dist-info}/WHEEL +0 -0
- {fastapi_rtk-1.0.0.dist-info → fastapi_rtk-1.0.1.dist-info}/entry_points.txt +0 -0
- {fastapi_rtk-1.0.0.dist-info → fastapi_rtk-1.0.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -206,6 +206,19 @@ class ModelRestApi(BaseApi):
|
|
|
206
206
|
"""
|
|
207
207
|
The list of routes to exclude from protection. Defaults to `[]`.
|
|
208
208
|
"""
|
|
209
|
+
expose_params: dict[AVAILABLE_ROUTES, dict[str, Any]] = lazy(lambda: dict())
|
|
210
|
+
"""
|
|
211
|
+
Additional parameters to pass to the `expose` decorator for each route. See `expose` decorator for more information.
|
|
212
|
+
|
|
213
|
+
Example:
|
|
214
|
+
```python
|
|
215
|
+
expose_params = {
|
|
216
|
+
'image': {
|
|
217
|
+
'description': 'Custom description for image endpoint',
|
|
218
|
+
},
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
"""
|
|
209
222
|
base_order: Tuple[str, Literal["asc", "desc"]] | None = None
|
|
210
223
|
"""
|
|
211
224
|
The default order for the list endpoint. Set this to set the default order for the list endpoint.
|
|
@@ -1040,12 +1053,15 @@ class ModelRestApi(BaseApi):
|
|
|
1040
1053
|
expose(
|
|
1041
1054
|
"/_image/{filename}",
|
|
1042
1055
|
methods=["GET"],
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1056
|
+
**{
|
|
1057
|
+
"name": "Get Image",
|
|
1058
|
+
"description": f"Get an image associated with an existing {self.datamodel.obj.__name__} item.",
|
|
1059
|
+
"response_class": FileResponse,
|
|
1060
|
+
"dependencies": [Depends(has_access_dependency(self, "image"))]
|
|
1061
|
+
if "image" in self.protected_routes
|
|
1062
|
+
else None,
|
|
1063
|
+
**self.expose_params.get("image", {}),
|
|
1064
|
+
},
|
|
1049
1065
|
)(self.image_headless)
|
|
1050
1066
|
|
|
1051
1067
|
def file(self):
|
|
@@ -1062,12 +1078,15 @@ class ModelRestApi(BaseApi):
|
|
|
1062
1078
|
expose(
|
|
1063
1079
|
"/_file/{filename}",
|
|
1064
1080
|
methods=["GET"],
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1081
|
+
**{
|
|
1082
|
+
"name": "Get File",
|
|
1083
|
+
"description": f"Get a file associated with an existing {self.datamodel.obj.__name__} item.",
|
|
1084
|
+
"response_class": FileResponse,
|
|
1085
|
+
"dependencies": [Depends(has_access_dependency(self, "file"))]
|
|
1086
|
+
if "file" in self.protected_routes
|
|
1087
|
+
else None,
|
|
1088
|
+
**self.expose_params.get("file", {}),
|
|
1089
|
+
},
|
|
1071
1090
|
)(self.file_headless)
|
|
1072
1091
|
|
|
1073
1092
|
def info(self):
|
|
@@ -1079,12 +1098,15 @@ class ModelRestApi(BaseApi):
|
|
|
1079
1098
|
expose(
|
|
1080
1099
|
"/_info",
|
|
1081
1100
|
methods=["GET"],
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1101
|
+
**{
|
|
1102
|
+
"name": "Get Info",
|
|
1103
|
+
"description": f"Get metadata information about the model {self.datamodel.obj.__name__}. such as add/edit columns, filter options, titles, and JSONForms schemas.",
|
|
1104
|
+
"response_model": self.info_return_schema | typing.Any,
|
|
1105
|
+
"dependencies": [Depends(has_access_dependency(self, "info"))]
|
|
1106
|
+
if "info" in self.protected_routes
|
|
1107
|
+
else None,
|
|
1108
|
+
**self.expose_params.get("info", {}),
|
|
1109
|
+
},
|
|
1088
1110
|
)(self.info_headless)
|
|
1089
1111
|
|
|
1090
1112
|
def download(self):
|
|
@@ -1096,11 +1118,14 @@ class ModelRestApi(BaseApi):
|
|
|
1096
1118
|
expose(
|
|
1097
1119
|
"/download",
|
|
1098
1120
|
methods=["GET"],
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1121
|
+
**{
|
|
1122
|
+
"name": "Download",
|
|
1123
|
+
"description": f"Download list of {self.datamodel.obj.__name__} items as a CSV file with support for filtering, ordering, and global search.",
|
|
1124
|
+
"dependencies": [Depends(has_access_dependency(self, "download"))]
|
|
1125
|
+
if "download" in self.protected_routes
|
|
1126
|
+
else None,
|
|
1127
|
+
**self.expose_params.get("download", {}),
|
|
1128
|
+
},
|
|
1104
1129
|
)(self.download_headless)
|
|
1105
1130
|
|
|
1106
1131
|
#! Disabled until further notice
|
|
@@ -1127,11 +1152,14 @@ class ModelRestApi(BaseApi):
|
|
|
1127
1152
|
expose(
|
|
1128
1153
|
"/bulk/{handler}",
|
|
1129
1154
|
methods=["POST"],
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1155
|
+
**{
|
|
1156
|
+
"name": "Bulk",
|
|
1157
|
+
"description": f"Handle bulk operations for the model {self.datamodel.obj.__name__} that are set in the API.",
|
|
1158
|
+
"dependencies": [Depends(has_access_dependency(self, "bulk"))]
|
|
1159
|
+
if "bulk" in self.protected_routes
|
|
1160
|
+
else None,
|
|
1161
|
+
**self.expose_params.get("bulk", {}),
|
|
1162
|
+
},
|
|
1135
1163
|
)(self.bulk_headless)
|
|
1136
1164
|
|
|
1137
1165
|
def get_list(self):
|
|
@@ -1143,12 +1171,15 @@ class ModelRestApi(BaseApi):
|
|
|
1143
1171
|
expose(
|
|
1144
1172
|
"/",
|
|
1145
1173
|
methods=["GET"],
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1174
|
+
**{
|
|
1175
|
+
"name": "Get items",
|
|
1176
|
+
"description": f"Get a list of {self.datamodel.obj.__name__} items with support for column selection, filtering, ordering, pagination, and global search.",
|
|
1177
|
+
"response_model": self.list_return_schema | typing.Any,
|
|
1178
|
+
"dependencies": [Depends(has_access_dependency(self, "get"))]
|
|
1179
|
+
if "get_list" in self.protected_routes
|
|
1180
|
+
else None,
|
|
1181
|
+
**self.expose_params.get("get_list", {}),
|
|
1182
|
+
},
|
|
1152
1183
|
)(self.get_list_headless)
|
|
1153
1184
|
|
|
1154
1185
|
def get(self):
|
|
@@ -1160,12 +1191,15 @@ class ModelRestApi(BaseApi):
|
|
|
1160
1191
|
expose(
|
|
1161
1192
|
"/{id}",
|
|
1162
1193
|
methods=["GET"],
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1194
|
+
**{
|
|
1195
|
+
"name": "Get item",
|
|
1196
|
+
"description": f"Get a single {self.datamodel.obj.__name__} item.",
|
|
1197
|
+
"response_model": self.show_return_schema | typing.Any,
|
|
1198
|
+
"dependencies": [Depends(has_access_dependency(self, "get"))]
|
|
1199
|
+
if "get" in self.protected_routes
|
|
1200
|
+
else None,
|
|
1201
|
+
**self.expose_params.get("get", {}),
|
|
1202
|
+
},
|
|
1169
1203
|
)(self.get_headless)
|
|
1170
1204
|
|
|
1171
1205
|
def post(self):
|
|
@@ -1177,12 +1211,15 @@ class ModelRestApi(BaseApi):
|
|
|
1177
1211
|
expose(
|
|
1178
1212
|
"/",
|
|
1179
1213
|
methods=["POST"],
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1214
|
+
**{
|
|
1215
|
+
"name": "Add item",
|
|
1216
|
+
"description": f"Add a new {self.datamodel.obj.__name__} item.",
|
|
1217
|
+
"response_model": self.add_return_schema | typing.Any,
|
|
1218
|
+
"dependencies": [Depends(has_access_dependency(self, "post"))]
|
|
1219
|
+
if "post" in self.protected_routes
|
|
1220
|
+
else None,
|
|
1221
|
+
**self.expose_params.get("post", {}),
|
|
1222
|
+
},
|
|
1186
1223
|
)(self.post_headless)
|
|
1187
1224
|
|
|
1188
1225
|
def put(self):
|
|
@@ -1194,12 +1231,15 @@ class ModelRestApi(BaseApi):
|
|
|
1194
1231
|
expose(
|
|
1195
1232
|
"/{id}",
|
|
1196
1233
|
methods=["PUT"],
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1234
|
+
**{
|
|
1235
|
+
"name": "Update item",
|
|
1236
|
+
"description": f"Update an existing {self.datamodel.obj.__name__} item.",
|
|
1237
|
+
"response_model": self.edit_return_schema | typing.Any,
|
|
1238
|
+
"dependencies": [Depends(has_access_dependency(self, "put"))]
|
|
1239
|
+
if "put" in self.protected_routes
|
|
1240
|
+
else None,
|
|
1241
|
+
**self.expose_params.get("put", {}),
|
|
1242
|
+
},
|
|
1203
1243
|
)(self.put_headless)
|
|
1204
1244
|
|
|
1205
1245
|
def delete(self):
|
|
@@ -1211,12 +1251,15 @@ class ModelRestApi(BaseApi):
|
|
|
1211
1251
|
expose(
|
|
1212
1252
|
"/{id}",
|
|
1213
1253
|
methods=["DELETE"],
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1254
|
+
**{
|
|
1255
|
+
"name": "Delete item",
|
|
1256
|
+
"description": f"Delete an existing {self.datamodel.obj.__name__} item.",
|
|
1257
|
+
"response_model": GeneralResponse | typing.Any,
|
|
1258
|
+
"dependencies": [Depends(has_access_dependency(self, "delete"))]
|
|
1259
|
+
if "delete" in self.protected_routes
|
|
1260
|
+
else None,
|
|
1261
|
+
**self.expose_params.get("delete", {}),
|
|
1262
|
+
},
|
|
1220
1263
|
)(self.delete_headless)
|
|
1221
1264
|
|
|
1222
1265
|
"""
|
fastapi_rtk/manager.py
CHANGED
|
@@ -500,6 +500,7 @@ class UserManager(IDParser, BaseUserManager[User, int]):
|
|
|
500
500
|
# Associate account
|
|
501
501
|
user = await self.get_by_email(account_email)
|
|
502
502
|
if not associate_by_email:
|
|
503
|
+
await self.on_after_authenticate(user, False)
|
|
503
504
|
raise exceptions.UserAlreadyExists()
|
|
504
505
|
user = await self.user_db.add_oauth_account(user, oauth_account_dict)
|
|
505
506
|
except exceptions.UserNotExists:
|
|
@@ -557,6 +558,7 @@ class UserManager(IDParser, BaseUserManager[User, int]):
|
|
|
557
558
|
user = await self._handle_role_keys(
|
|
558
559
|
user, oauth_callback_params["user_dict"].pop("role_keys", None)
|
|
559
560
|
)
|
|
561
|
+
await self.on_after_authenticate(user)
|
|
560
562
|
return user
|
|
561
563
|
|
|
562
564
|
@overload
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi-rtk
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.1
|
|
4
4
|
Summary: A package that provides a set of tools to build a FastAPI application with a Class-Based CRUD API.
|
|
5
5
|
Project-URL: Homepage, https://codeberg.org/datatactics/fastapi-rtk
|
|
6
6
|
Project-URL: Issues, https://codeberg.org/datatactics/fastapi-rtk/issues
|
|
@@ -9,7 +9,7 @@ fastapi_rtk/exceptions.py,sha256=P0qwd4VkeWFotgMVQHgmdT1NphFQaEznKLFIvJzW4Zs,259
|
|
|
9
9
|
fastapi_rtk/fastapi_react_toolkit.py,sha256=gDqHq7Bk90LTZm6muOlqBbiFtOMR8xMOxa9edm8ad8w,31891
|
|
10
10
|
fastapi_rtk/filters.py,sha256=weCH3suCxpGJQYmwhj9D1iAqMPiRnmbRiN7stK0rhoE,181
|
|
11
11
|
fastapi_rtk/globals.py,sha256=TcoMHCueM7sFwZ8iYorUe4q-3KpVFfV04RAPuMTYFKY,8863
|
|
12
|
-
fastapi_rtk/manager.py,sha256=
|
|
12
|
+
fastapi_rtk/manager.py,sha256=J86sBByj6E1kZ3CRS0NayI0n5firrfMhAU2d58mz0JM,33965
|
|
13
13
|
fastapi_rtk/middlewares.py,sha256=ycdaAdLIUaNEZ7KotczTHS6OOqy98Mn1_O7Hpe7Sma8,10325
|
|
14
14
|
fastapi_rtk/mixins.py,sha256=78RqwrRJFOz6KAxf-GSNOmRdr7R3b-ws7OIENYlzRQQ,238
|
|
15
15
|
fastapi_rtk/models.py,sha256=lQSqe-r0H7jWBVdqXjEi_bNL1cGQr0YWnyI1ToS_coc,178
|
|
@@ -20,7 +20,7 @@ fastapi_rtk/types.py,sha256=-LPnTIbHvqJW81__gab3EWrhjNmznHhptz0BtXkEAHQ,3612
|
|
|
20
20
|
fastapi_rtk/version.py,sha256=J-j-u0itpEFT6irdmWmixQqYMadNl1X91TxUmoiLHMI,22
|
|
21
21
|
fastapi_rtk/api/__init__.py,sha256=MwFR7HHppnhbjZGg3sOdQ6nqy9uxnHHXvicpswNFMNA,245
|
|
22
22
|
fastapi_rtk/api/base_api.py,sha256=42I9v3b25lqxNAMDGEtajA5-btIDSyUWF0xMDgGkA8c,8078
|
|
23
|
-
fastapi_rtk/api/model_rest_api.py,sha256=
|
|
23
|
+
fastapi_rtk/api/model_rest_api.py,sha256=Hp6ws1CjLG-2e-yHxniIudUUmnKff9js2VVZ4Q5JMoo,105111
|
|
24
24
|
fastapi_rtk/auth/__init__.py,sha256=iX7O41NivBYDfdomEaqm4lUx9KD17wI4g3EFLF6kUTw,336
|
|
25
25
|
fastapi_rtk/auth/auth.py,sha256=MZmuueioiMbSHjd_F3frKEqCA3yjtanRWyKOy6CnOd0,20994
|
|
26
26
|
fastapi_rtk/auth/hashers/__init__.py,sha256=uBThFj2VPPSMSioxYTktNiM4-mVgtDAjTpKA3ZzWxxs,110
|
|
@@ -122,8 +122,8 @@ fastapi_rtk/utils/timezone.py,sha256=62S0pPWuDFFXxV1YTFCsc4uKiSP_Ba36Fv7S3gYjfhs
|
|
|
122
122
|
fastapi_rtk/utils/update_signature.py,sha256=PIzZgNpGEwvDNgQ3G51Zi-QhVV3mbxvUvSwDwf_-yYs,2209
|
|
123
123
|
fastapi_rtk/utils/use_default_when_none.py,sha256=H2HqhKy_8eYk3i1xijEjuaKak0oWkMIkrdz6T7DK9QU,469
|
|
124
124
|
fastapi_rtk/utils/werkzeug.py,sha256=1Gv-oyqSmhVGrmNbB9fDqpqJzPpANOzWf4zMMrhW9UA,3245
|
|
125
|
-
fastapi_rtk-1.0.
|
|
126
|
-
fastapi_rtk-1.0.
|
|
127
|
-
fastapi_rtk-1.0.
|
|
128
|
-
fastapi_rtk-1.0.
|
|
129
|
-
fastapi_rtk-1.0.
|
|
125
|
+
fastapi_rtk-1.0.1.dist-info/METADATA,sha256=Nar7z0i7UfidWgYcijllpGWUaKUxYAhFbIy0l0hCvyA,1270
|
|
126
|
+
fastapi_rtk-1.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
127
|
+
fastapi_rtk-1.0.1.dist-info/entry_points.txt,sha256=UuTkxSVIokSlVN28TMhoxzRRUaPxlVRSH3Gsx6yip60,53
|
|
128
|
+
fastapi_rtk-1.0.1.dist-info/licenses/LICENSE,sha256=NDrWi4Qwcxal3u1r2lBWGA6TVh3OeW7yMan098mQz98,1073
|
|
129
|
+
fastapi_rtk-1.0.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|