arpakitlib 1.8.13__py3-none-any.whl → 1.8.15__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.
- arpakitlib/_arpakit_project_template_v_2/project/api/auth.py +77 -64
- arpakitlib/_arpakit_project_template_v_2/project/api/response.py +1 -1
- arpakitlib/_arpakit_project_template_v_2/project/api/router/general/get_auth_data.py +31 -0
- arpakitlib/_arpakit_project_template_v_2/project/api/router/{v1 → general}/get_errors_info.py +9 -11
- arpakitlib/_arpakit_project_template_v_2/project/api/router/general/healthcheck.py +26 -0
- arpakitlib/_arpakit_project_template_v_2/project/api/router/general/main_router.py +24 -0
- arpakitlib/_arpakit_project_template_v_2/project/api/router/{v1 → general}/now_utc_datetime.py +5 -0
- arpakitlib/_arpakit_project_template_v_2/project/api/router/main_router.py +4 -3
- arpakitlib/_arpakit_project_template_v_2/project/api/schema/common/out.py +0 -5
- arpakitlib/_arpakit_project_template_v_2/project/api/schema/{v1 → example}/in_.py +1 -1
- arpakitlib/_arpakit_project_template_v_2/project/api/schema/example/out.py +45 -0
- arpakitlib/_arpakit_project_template_v_2/project/api/schema/general/__init__.py +0 -0
- arpakitlib/_arpakit_project_template_v_2/project/api/schema/general/in_.py +5 -0
- arpakitlib/_arpakit_project_template_v_2/project/api/schema/general/out.py +14 -0
- arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/add_admin_in_app.py +2 -2
- arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/admin_auth.py +29 -22
- arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/model_view/__init__.py +3 -0
- arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/model_view/common.py +24 -0
- arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/model_view/operation.py +43 -0
- arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/model_view/story_log.py +36 -0
- {arpakitlib-1.8.13.dist-info → arpakitlib-1.8.15.dist-info}/METADATA +1 -1
- {arpakitlib-1.8.13.dist-info → arpakitlib-1.8.15.dist-info}/RECORD +27 -26
- arpakitlib/_arpakit_project_template_v_2/project/api/router/v1/check_auth.py +0 -30
- arpakitlib/_arpakit_project_template_v_2/project/api/router/v1/clear_log_file.py +0 -34
- arpakitlib/_arpakit_project_template_v_2/project/api/router/v1/get_arpakitlib_project_template_info.py +0 -22
- arpakitlib/_arpakit_project_template_v_2/project/api/router/v1/get_log_file.py +0 -32
- arpakitlib/_arpakit_project_template_v_2/project/api/router/v1/healthcheck.py +0 -21
- arpakitlib/_arpakit_project_template_v_2/project/api/router/v1/main_router.py +0 -59
- arpakitlib/_arpakit_project_template_v_2/project/api/router/v1/raise_fake_error.py +0 -44
- arpakitlib/_arpakit_project_template_v_2/project/api/router/v1/reinit_sqlalchemy_db.py +0 -33
- arpakitlib/_arpakit_project_template_v_2/project/api/schema/v1/out.py +0 -47
- arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/model_view.py +0 -95
- /arpakitlib/_arpakit_project_template_v_2/project/api/router/{v1 → general}/__init__.py +0 -0
- /arpakitlib/_arpakit_project_template_v_2/project/api/schema/{v1 → example}/__init__.py +0 -0
- {arpakitlib-1.8.13.dist-info → arpakitlib-1.8.15.dist-info}/LICENSE +0 -0
- {arpakitlib-1.8.13.dist-info → arpakitlib-1.8.15.dist-info}/WHEEL +0 -0
- {arpakitlib-1.8.13.dist-info → arpakitlib-1.8.15.dist-info}/entry_points.txt +0 -0
@@ -20,34 +20,38 @@ class APIAuthData(BaseModel):
|
|
20
20
|
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True, from_attributes=True)
|
21
21
|
|
22
22
|
require_api_key_string: bool = False
|
23
|
-
|
23
|
+
require_user_token_string: bool = False
|
24
24
|
|
25
25
|
require_correct_api_key: bool = False
|
26
|
-
|
27
|
-
|
28
|
-
token_string: str | None = None
|
29
|
-
api_key_string: str | None = None
|
30
|
-
|
31
|
-
is_token_correct: bool | None = None
|
32
|
-
is_api_key_correct: bool | None = None
|
26
|
+
require_correct_user_token: bool = False
|
33
27
|
|
34
28
|
require_mode_type: str | None = None
|
35
29
|
require_not_mode_type: str | None = None
|
30
|
+
|
36
31
|
current_mode_type: str | None = None
|
37
32
|
|
33
|
+
user_token_string: str | None = None
|
34
|
+
api_key_string: str | None = None
|
35
|
+
|
36
|
+
is_user_token_correct: bool | None = None
|
37
|
+
is_api_key_correct: bool | None = None
|
38
|
+
|
38
39
|
|
39
40
|
def api_auth(
|
40
41
|
*,
|
41
42
|
require_api_key_string: bool = False,
|
42
|
-
|
43
|
-
|
44
|
-
validate_token_func: Callable | None = None,
|
45
|
-
correct_api_keys: str | list[str] | None = None,
|
46
|
-
correct_tokens: str | list[str] | None = None,
|
43
|
+
require_user_token_string: bool = False,
|
44
|
+
|
47
45
|
require_correct_api_key: bool = False,
|
48
|
-
|
46
|
+
require_correct_user_token: bool = False,
|
47
|
+
|
49
48
|
require_mode_type: str | None = None,
|
50
|
-
require_not_mode_type: str | None = None
|
49
|
+
require_not_mode_type: str | None = None,
|
50
|
+
|
51
|
+
validate_api_key_func: Callable | None = None,
|
52
|
+
validate_user_token_func: Callable | None = None,
|
53
|
+
correct_api_keys: str | list[str] | None = None,
|
54
|
+
correct_user_tokens: str | list[str] | None = None,
|
51
55
|
) -> Callable:
|
52
56
|
if isinstance(correct_api_keys, str):
|
53
57
|
correct_api_keys = [correct_api_keys]
|
@@ -55,21 +59,25 @@ def api_auth(
|
|
55
59
|
raise_for_type(correct_api_keys, list)
|
56
60
|
|
57
61
|
if validate_api_key_func is None and correct_api_keys is not None:
|
58
|
-
validate_api_key_func =
|
62
|
+
validate_api_key_func = (
|
63
|
+
lambda *args, **kwargs_: kwargs_["api_auth_data"].api_key_string in correct_api_keys
|
64
|
+
)
|
59
65
|
|
60
|
-
if isinstance(
|
61
|
-
|
62
|
-
if
|
63
|
-
raise_for_type(
|
66
|
+
if isinstance(correct_user_tokens, str):
|
67
|
+
correct_user_tokens = [correct_user_tokens]
|
68
|
+
if correct_user_tokens is not None:
|
69
|
+
raise_for_type(correct_user_tokens, list)
|
64
70
|
|
65
|
-
if
|
66
|
-
|
71
|
+
if validate_user_token_func is None and correct_user_tokens is not None:
|
72
|
+
validate_user_token_func = (
|
73
|
+
lambda *args, **kwargs_: kwargs_["api_auth_data"].user_token_string in correct_user_tokens
|
74
|
+
)
|
67
75
|
|
68
76
|
if require_correct_api_key is True:
|
69
77
|
require_api_key_string = True
|
70
78
|
|
71
|
-
if
|
72
|
-
|
79
|
+
if require_correct_user_token is True:
|
80
|
+
require_user_token_string = True
|
73
81
|
|
74
82
|
async def func(
|
75
83
|
*,
|
@@ -84,9 +92,9 @@ def api_auth(
|
|
84
92
|
|
85
93
|
api_auth_data = APIAuthData(
|
86
94
|
require_api_key_string=require_api_key_string,
|
87
|
-
|
95
|
+
require_user_token_string=require_user_token_string,
|
88
96
|
require_correct_api_key=require_correct_api_key,
|
89
|
-
|
97
|
+
require_correct_user_token=require_correct_user_token,
|
90
98
|
require_mode_type=require_mode_type,
|
91
99
|
require_not_mode_type=require_not_mode_type,
|
92
100
|
current_mode_type=get_cached_settings().mode_type
|
@@ -110,34 +118,39 @@ def api_auth(
|
|
110
118
|
if not api_auth_data.api_key_string and "apikey" in request.query_params.keys():
|
111
119
|
api_auth_data.api_key_string = request.query_params["apikey"]
|
112
120
|
|
113
|
-
|
121
|
+
if api_auth_data.api_key_string:
|
122
|
+
api_auth_data.api_key_string = api_auth_data.api_key_string.strip()
|
123
|
+
if not api_auth_data.api_key_string:
|
124
|
+
api_auth_data.api_key_string = None
|
114
125
|
|
115
|
-
|
126
|
+
# parse user token
|
116
127
|
|
117
|
-
|
118
|
-
api_auth_data.token_string = request.headers["token"]
|
128
|
+
api_auth_data.user_token_string = ac.credentials if ac and ac.credentials and ac.credentials.strip() else None
|
119
129
|
|
120
|
-
if not api_auth_data.
|
121
|
-
api_auth_data.
|
122
|
-
if not api_auth_data.token_string and "user-token" in request.headers.keys():
|
123
|
-
api_auth_data.token_string = request.headers["user-token"]
|
124
|
-
if not api_auth_data.token_string and "usertoken" in request.headers.keys():
|
125
|
-
api_auth_data.token_string = request.headers["usertoken"]
|
130
|
+
if not api_auth_data.user_token_string and "token" in request.headers.keys():
|
131
|
+
api_auth_data.user_token_string = request.headers["token"]
|
126
132
|
|
127
|
-
if not api_auth_data.
|
128
|
-
api_auth_data.
|
133
|
+
if not api_auth_data.user_token_string and "user_token" in request.headers.keys():
|
134
|
+
api_auth_data.user_token_string = request.headers["user_token"]
|
135
|
+
if not api_auth_data.user_token_string and "user-token" in request.headers.keys():
|
136
|
+
api_auth_data.user_token_string = request.headers["user-token"]
|
137
|
+
if not api_auth_data.user_token_string and "usertoken" in request.headers.keys():
|
138
|
+
api_auth_data.user_token_string = request.headers["usertoken"]
|
129
139
|
|
130
|
-
if not api_auth_data.
|
131
|
-
api_auth_data.
|
132
|
-
if not api_auth_data.token_string and "user-token" in request.query_params.keys():
|
133
|
-
api_auth_data.token_string = request.query_params["user-token"]
|
134
|
-
if not api_auth_data.token_string and "usertoken" in request.query_params.keys():
|
135
|
-
api_auth_data.token_string = request.query_params["usertoken"]
|
140
|
+
if not api_auth_data.user_token_string and "token" in request.query_params.keys():
|
141
|
+
api_auth_data.user_token_string = request.query_params["token"]
|
136
142
|
|
137
|
-
if api_auth_data.
|
138
|
-
api_auth_data.
|
139
|
-
if not api_auth_data.
|
140
|
-
api_auth_data.
|
143
|
+
if not api_auth_data.user_token_string and "user_token" in request.query_params.keys():
|
144
|
+
api_auth_data.user_token_string = request.query_params["user_token"]
|
145
|
+
if not api_auth_data.user_token_string and "user-token" in request.query_params.keys():
|
146
|
+
api_auth_data.user_token_string = request.query_params["user-token"]
|
147
|
+
if not api_auth_data.user_token_string and "usertoken" in request.query_params.keys():
|
148
|
+
api_auth_data.user_token_string = request.query_params["usertoken"]
|
149
|
+
|
150
|
+
if api_auth_data.user_token_string:
|
151
|
+
api_auth_data.user_token_string = api_auth_data.user_token_string.strip()
|
152
|
+
if not api_auth_data.user_token_string:
|
153
|
+
api_auth_data.user_token_string = None
|
141
154
|
|
142
155
|
# require_mode_type
|
143
156
|
|
@@ -170,7 +183,7 @@ def api_auth(
|
|
170
183
|
|
171
184
|
# require_token_string
|
172
185
|
|
173
|
-
if
|
186
|
+
if require_user_token_string and not api_auth_data.user_token_string:
|
174
187
|
raise APIException(
|
175
188
|
status_code=fastapi.status.HTTP_401_UNAUTHORIZED,
|
176
189
|
error_code=APIErrorCodes.cannot_authorize,
|
@@ -192,14 +205,14 @@ def api_auth(
|
|
192
205
|
|
193
206
|
# validate_token_func
|
194
207
|
|
195
|
-
if
|
196
|
-
if is_async_callable(
|
197
|
-
api_auth_data.
|
208
|
+
if validate_user_token_func is not None:
|
209
|
+
if is_async_callable(validate_user_token_func):
|
210
|
+
api_auth_data.is_user_token_correct = await validate_user_token_func(
|
198
211
|
api_auth_data=api_auth_data,
|
199
212
|
request=request
|
200
213
|
)
|
201
|
-
elif is_sync_function(
|
202
|
-
api_auth_data.
|
214
|
+
elif is_sync_function(validate_user_token_func):
|
215
|
+
api_auth_data.is_user_token_correct = validate_user_token_func()
|
203
216
|
else:
|
204
217
|
raise TypeError("unknown validate_token_func type")
|
205
218
|
|
@@ -216,8 +229,8 @@ def api_auth(
|
|
216
229
|
|
217
230
|
# require_correct_token
|
218
231
|
|
219
|
-
if
|
220
|
-
if not api_auth_data.
|
232
|
+
if require_correct_user_token:
|
233
|
+
if not api_auth_data.is_user_token_correct:
|
221
234
|
raise APIException(
|
222
235
|
status_code=fastapi.status.HTTP_401_UNAUTHORIZED,
|
223
236
|
error_code=APIErrorCodes.cannot_authorize,
|
@@ -230,8 +243,8 @@ def api_auth(
|
|
230
243
|
return func
|
231
244
|
|
232
245
|
|
233
|
-
def
|
234
|
-
async def
|
246
|
+
def correct_api_keys_from_settings__is_api_key_correct_func() -> Callable:
|
247
|
+
async def async_func(
|
235
248
|
*,
|
236
249
|
api_auth_data: APIAuthData,
|
237
250
|
request: fastapi.requests.Request,
|
@@ -244,21 +257,21 @@ def correct_api_keys_from_settings__validate_api_key_func() -> Callable:
|
|
244
257
|
return False
|
245
258
|
return True
|
246
259
|
|
247
|
-
return
|
260
|
+
return async_func
|
248
261
|
|
249
262
|
|
250
|
-
def
|
251
|
-
async def
|
263
|
+
def correct_tokens_from_settings__is_user_token_correct_func() -> Callable:
|
264
|
+
async def async_func(
|
252
265
|
*,
|
253
266
|
api_auth_data: APIAuthData,
|
254
267
|
request: fastapi.requests.Request,
|
255
268
|
):
|
256
269
|
if get_cached_settings().api_correct_tokens is None:
|
257
270
|
return False
|
258
|
-
if api_auth_data.
|
271
|
+
if api_auth_data.user_token_string is None:
|
259
272
|
return False
|
260
|
-
if api_auth_data.
|
273
|
+
if api_auth_data.user_token_string.strip() not in get_cached_settings().api_correct_tokens:
|
261
274
|
return False
|
262
275
|
return True
|
263
276
|
|
264
|
-
return
|
277
|
+
return async_func
|
@@ -3,7 +3,7 @@ from typing import Any
|
|
3
3
|
import fastapi
|
4
4
|
|
5
5
|
from arpakitlib.ar_json_util import safely_transfer_obj_to_json_str_to_json_obj
|
6
|
-
from project.api.schema.
|
6
|
+
from project.api.schema.base_schema import BaseSO
|
7
7
|
|
8
8
|
|
9
9
|
class APIJSONResponse(fastapi.responses.JSONResponse):
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import fastapi.requests
|
2
|
+
from fastapi import APIRouter
|
3
|
+
|
4
|
+
from arpakitlib.ar_json_util import safely_transfer_obj_to_json_str_to_json_obj
|
5
|
+
from project.api.auth import APIAuthData, api_auth, correct_tokens_from_settings__is_user_token_correct_func, \
|
6
|
+
correct_api_keys_from_settings__is_api_key_correct_func
|
7
|
+
from project.api.schema.common.out import ErrorCommonSO, RawDataCommonSO
|
8
|
+
from project.core.settings import ModeTypes
|
9
|
+
|
10
|
+
api_router = APIRouter()
|
11
|
+
|
12
|
+
|
13
|
+
@api_router.get(
|
14
|
+
path="",
|
15
|
+
name="Get auth data",
|
16
|
+
status_code=fastapi.status.HTTP_200_OK,
|
17
|
+
response_model=RawDataCommonSO | ErrorCommonSO,
|
18
|
+
)
|
19
|
+
async def _(
|
20
|
+
*,
|
21
|
+
request: fastapi.requests.Request,
|
22
|
+
response: fastapi.responses.Response,
|
23
|
+
api_auth_data: APIAuthData = fastapi.Depends(api_auth(
|
24
|
+
validate_api_key_func=correct_api_keys_from_settings__is_api_key_correct_func(),
|
25
|
+
validate_user_token_func=correct_tokens_from_settings__is_user_token_correct_func(),
|
26
|
+
require_correct_api_key=False,
|
27
|
+
require_correct_user_token=False,
|
28
|
+
require_not_mode_type=ModeTypes.prod
|
29
|
+
))
|
30
|
+
):
|
31
|
+
return RawDataCommonSO(data=safely_transfer_obj_to_json_str_to_json_obj(api_auth_data.model_dump()))
|
arpakitlib/_arpakit_project_template_v_2/project/api/router/{v1 → general}/get_errors_info.py
RENAMED
@@ -1,9 +1,11 @@
|
|
1
1
|
import fastapi.requests
|
2
|
-
from fastapi import APIRouter
|
2
|
+
from fastapi import APIRouter
|
3
3
|
|
4
|
-
from project.api.auth import APIAuthData, api_auth,
|
4
|
+
from project.api.auth import APIAuthData, api_auth, \
|
5
|
+
correct_api_keys_from_settings__is_api_key_correct_func
|
5
6
|
from project.api.const import APIErrorCodes, APIErrorSpecificationCodes
|
6
|
-
from project.api.schema.common.out import ErrorCommonSO
|
7
|
+
from project.api.schema.common.out import ErrorCommonSO
|
8
|
+
from project.api.schema.general.out import ErrorsInfoGeneralSO
|
7
9
|
|
8
10
|
api_router = APIRouter()
|
9
11
|
|
@@ -12,22 +14,18 @@ api_router = APIRouter()
|
|
12
14
|
"",
|
13
15
|
name="Get errors info",
|
14
16
|
status_code=fastapi.status.HTTP_200_OK,
|
15
|
-
response_model=
|
17
|
+
response_model=ErrorsInfoGeneralSO | ErrorCommonSO,
|
16
18
|
)
|
17
19
|
async def _(
|
18
20
|
*,
|
19
21
|
request: fastapi.requests.Request,
|
20
22
|
response: fastapi.responses.Response,
|
21
|
-
api_auth_data: APIAuthData = Depends(api_auth(
|
22
|
-
|
23
|
-
require_token_string=False,
|
24
|
-
validate_api_key_func=correct_api_keys_from_settings__validate_api_key_func(),
|
25
|
-
validate_token_func=None,
|
23
|
+
api_auth_data: APIAuthData = fastapi.Depends(api_auth(
|
24
|
+
validate_api_key_func=correct_api_keys_from_settings__is_api_key_correct_func(),
|
26
25
|
require_correct_api_key=True,
|
27
|
-
require_correct_token=False,
|
28
26
|
))
|
29
27
|
):
|
30
|
-
return
|
28
|
+
return ErrorsInfoGeneralSO(
|
31
29
|
api_error_codes=APIErrorCodes.values_list(),
|
32
30
|
api_error_specification_codes=APIErrorSpecificationCodes.values_list()
|
33
31
|
)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import fastapi
|
2
|
+
from fastapi import APIRouter
|
3
|
+
|
4
|
+
from project.api.auth import APIAuthData, api_auth, correct_api_keys_from_settings__is_api_key_correct_func
|
5
|
+
from project.api.schema.common.out import ErrorCommonSO
|
6
|
+
from project.api.schema.general.out import HealthcheckGeneralSO
|
7
|
+
|
8
|
+
api_router = APIRouter()
|
9
|
+
|
10
|
+
|
11
|
+
@api_router.get(
|
12
|
+
"",
|
13
|
+
name="Healthcheck",
|
14
|
+
status_code=fastapi.status.HTTP_200_OK,
|
15
|
+
response_model=HealthcheckGeneralSO | ErrorCommonSO,
|
16
|
+
)
|
17
|
+
async def _(
|
18
|
+
*,
|
19
|
+
request: fastapi.requests.Request,
|
20
|
+
response: fastapi.responses.Response,
|
21
|
+
api_auth_data: APIAuthData = fastapi.Depends(api_auth(
|
22
|
+
validate_api_key_func=correct_api_keys_from_settings__is_api_key_correct_func(),
|
23
|
+
require_correct_api_key=True,
|
24
|
+
))
|
25
|
+
):
|
26
|
+
return HealthcheckGeneralSO(is_ok=True)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
from fastapi import APIRouter
|
2
|
+
|
3
|
+
from project.api.router.general import get_errors_info, healthcheck, now_utc_datetime, get_auth_data
|
4
|
+
from project.core.settings import get_cached_settings
|
5
|
+
|
6
|
+
main_general_api_router = APIRouter()
|
7
|
+
|
8
|
+
main_general_api_router.include_router(
|
9
|
+
router=healthcheck.api_router,
|
10
|
+
prefix="/healthcheck"
|
11
|
+
)
|
12
|
+
main_general_api_router.include_router(
|
13
|
+
router=get_errors_info.api_router,
|
14
|
+
prefix="/get_errors_info"
|
15
|
+
)
|
16
|
+
main_general_api_router.include_router(
|
17
|
+
router=now_utc_datetime.api_router,
|
18
|
+
prefix="/now_utc_datetime"
|
19
|
+
)
|
20
|
+
if not get_cached_settings().is_mode_type_prod:
|
21
|
+
main_general_api_router.include_router(
|
22
|
+
router=get_auth_data.api_router,
|
23
|
+
prefix="/get_auth_data"
|
24
|
+
)
|
arpakitlib/_arpakit_project_template_v_2/project/api/router/{v1 → general}/now_utc_datetime.py
RENAMED
@@ -2,6 +2,7 @@ import fastapi
|
|
2
2
|
from fastapi import APIRouter
|
3
3
|
|
4
4
|
from arpakitlib.ar_datetime_util import now_utc_dt
|
5
|
+
from project.api.auth import APIAuthData, api_auth, correct_api_keys_from_settings__is_api_key_correct_func
|
5
6
|
from project.api.schema.common.out import ErrorCommonSO, DatetimeCommonSO
|
6
7
|
|
7
8
|
api_router = APIRouter()
|
@@ -17,5 +18,9 @@ async def _(
|
|
17
18
|
*,
|
18
19
|
request: fastapi.requests.Request,
|
19
20
|
response: fastapi.responses.Response,
|
21
|
+
api_auth_data: APIAuthData = fastapi.Depends(api_auth(
|
22
|
+
validate_api_key_func=correct_api_keys_from_settings__is_api_key_correct_func(),
|
23
|
+
require_correct_api_key=True,
|
24
|
+
))
|
20
25
|
):
|
21
26
|
return DatetimeCommonSO.from_datetime(datetime_=now_utc_dt())
|
@@ -1,10 +1,11 @@
|
|
1
1
|
from fastapi import APIRouter
|
2
2
|
|
3
|
-
from project.api.router.
|
3
|
+
from project.api.router.general.main_router import main_general_api_router
|
4
4
|
|
5
5
|
main_api_router = APIRouter()
|
6
6
|
|
7
7
|
main_api_router.include_router(
|
8
|
-
prefix="/
|
9
|
-
router=
|
8
|
+
prefix="/general",
|
9
|
+
router=main_general_api_router,
|
10
|
+
tags=["General"]
|
10
11
|
)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import datetime as dt
|
4
|
+
from typing import Any
|
5
|
+
|
6
|
+
from project.api.schema.base_schema import BaseSO
|
7
|
+
from project.sqlalchemy_db_.sqlalchemy_model import StoryLogDBM, OperationDBM
|
8
|
+
|
9
|
+
|
10
|
+
class BaseExampleSO(BaseSO):
|
11
|
+
pass
|
12
|
+
|
13
|
+
|
14
|
+
class SimpleDBMExampleSO(BaseExampleSO):
|
15
|
+
id: int
|
16
|
+
long_id: str
|
17
|
+
slug: str | None
|
18
|
+
creation_dt: dt.datetime
|
19
|
+
|
20
|
+
|
21
|
+
class StoryLogExampleSO(SimpleDBMExampleSO):
|
22
|
+
level: str
|
23
|
+
type: str | None
|
24
|
+
title: str | None
|
25
|
+
data: dict[str, Any]
|
26
|
+
|
27
|
+
@classmethod
|
28
|
+
def from_story_log_dbm(cls, *, story_log_dbm: StoryLogDBM) -> StoryLogExampleSO:
|
29
|
+
return cls.model_validate(story_log_dbm.simple_dict_with_sd_properties())
|
30
|
+
|
31
|
+
|
32
|
+
class OperationExampleSO(SimpleDBMExampleSO):
|
33
|
+
execution_start_dt: dt.datetime | None
|
34
|
+
execution_finish_dt: dt.datetime | None
|
35
|
+
status: str
|
36
|
+
type: str
|
37
|
+
title: str | None
|
38
|
+
input_data: dict[str, Any]
|
39
|
+
output_data: dict[str, Any]
|
40
|
+
error_data: dict[str, Any]
|
41
|
+
duration_total_seconds: float | None
|
42
|
+
|
43
|
+
@classmethod
|
44
|
+
def from_operation_dbm(cls, *, operation_dbm: OperationDBM) -> OperationExampleSO:
|
45
|
+
return cls.model_validate(operation_dbm.simple_dict_with_sd_properties())
|
File without changes
|
@@ -0,0 +1,14 @@
|
|
1
|
+
from project.api.schema.base_schema import BaseSO
|
2
|
+
|
3
|
+
|
4
|
+
class BaseGeneralSO(BaseSO):
|
5
|
+
pass
|
6
|
+
|
7
|
+
|
8
|
+
class HealthcheckGeneralSO(BaseGeneralSO):
|
9
|
+
is_ok: bool = True
|
10
|
+
|
11
|
+
|
12
|
+
class ErrorsInfoGeneralSO(BaseGeneralSO):
|
13
|
+
api_error_codes: list[str] = []
|
14
|
+
api_error_specification_codes: list[str] = []
|
@@ -3,7 +3,7 @@ from sqladmin import Admin
|
|
3
3
|
|
4
4
|
from project.core.settings import get_cached_settings
|
5
5
|
from project.sqladmin_.admin_auth import SQLAdminAuth
|
6
|
-
from project.sqladmin_.model_view import
|
6
|
+
from project.sqladmin_.model_view import SimpleMV
|
7
7
|
from project.sqlalchemy_db_.sqlalchemy_db import get_cached_sqlalchemy_db
|
8
8
|
|
9
9
|
|
@@ -18,7 +18,7 @@ def add_sqladmin_in_app(*, app: FastAPI, base_url: str = "/sqladmin") -> FastAPI
|
|
18
18
|
title=get_cached_settings().project_name
|
19
19
|
)
|
20
20
|
|
21
|
-
for model_view in
|
21
|
+
for model_view in SimpleMV.__subclasses__():
|
22
22
|
admin.add_model_view(model_view)
|
23
23
|
|
24
24
|
return app
|
@@ -13,20 +13,35 @@ class SQLAdminAuth(AuthenticationBackend):
|
|
13
13
|
|
14
14
|
async def login(self, request: fastapi.Request) -> bool:
|
15
15
|
form = await request.form()
|
16
|
+
|
16
17
|
username, password = form.get("username"), form.get("password")
|
17
18
|
if username:
|
18
19
|
username = username.strip()
|
19
20
|
if password:
|
20
21
|
password = password.strip()
|
21
22
|
|
22
|
-
if get_cached_settings().sqladmin_correct_passwords is None:
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
if get_cached_settings().sqladmin_correct_passwords is not None:
|
24
|
+
if (
|
25
|
+
(
|
26
|
+
is_username_correct := (
|
27
|
+
username is not None
|
28
|
+
and username in get_cached_settings().sqladmin_correct_passwords
|
29
|
+
)
|
30
|
+
)
|
31
|
+
or
|
32
|
+
(
|
33
|
+
is_password_correct := (
|
34
|
+
password is not None
|
35
|
+
and password in get_cached_settings().sqladmin_correct_passwords
|
36
|
+
)
|
37
|
+
)
|
38
|
+
):
|
39
|
+
if is_username_correct is True:
|
40
|
+
request.session.update({"sqladmin_key": username})
|
41
|
+
elif is_password_correct is True:
|
42
|
+
request.session.update({"sqladmin_key": password})
|
43
|
+
|
44
|
+
return True
|
30
45
|
|
31
46
|
return False
|
32
47
|
|
@@ -35,20 +50,12 @@ class SQLAdminAuth(AuthenticationBackend):
|
|
35
50
|
return True
|
36
51
|
|
37
52
|
async def authenticate(self, request: fastapi.Request) -> bool:
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
username = username.strip()
|
42
|
-
if password:
|
43
|
-
password = password.strip()
|
53
|
+
sqladmin_key = request.session.get("sqladmin_key")
|
54
|
+
if sqladmin_key:
|
55
|
+
sqladmin_key = sqladmin_key.strip()
|
44
56
|
|
45
|
-
if get_cached_settings().sqladmin_correct_passwords is None:
|
46
|
-
|
47
|
-
|
48
|
-
(username is not None and username in get_cached_settings().sqladmin_correct_passwords)
|
49
|
-
or
|
50
|
-
(password is not None and password in get_cached_settings().sqladmin_correct_passwords)
|
51
|
-
):
|
52
|
-
return True
|
57
|
+
if get_cached_settings().sqladmin_correct_passwords is not None:
|
58
|
+
if sqladmin_key is not None and sqladmin_key in get_cached_settings().sqladmin_correct_passwords:
|
59
|
+
return True
|
53
60
|
|
54
61
|
return False
|
@@ -0,0 +1,24 @@
|
|
1
|
+
from sqladmin import ModelView
|
2
|
+
|
3
|
+
|
4
|
+
class SimpleMV(ModelView):
|
5
|
+
can_create = True
|
6
|
+
can_edit = True
|
7
|
+
can_delete = True
|
8
|
+
can_view_details = True
|
9
|
+
can_export = True
|
10
|
+
page_size = 50
|
11
|
+
page_size_options = [50, 100, 200]
|
12
|
+
save_as = True
|
13
|
+
save_as_continue = True
|
14
|
+
export_types = ["xlsx", "csv", "json"]
|
15
|
+
|
16
|
+
|
17
|
+
def get_simple_mv_class() -> type[SimpleMV]:
|
18
|
+
from project.sqladmin_.model_view import SimpleMV
|
19
|
+
return SimpleMV
|
20
|
+
|
21
|
+
|
22
|
+
if __name__ == '__main__':
|
23
|
+
for model_view in get_simple_mv_class().__subclasses__():
|
24
|
+
print(model_view)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
from project.sqladmin_.model_view.common import SimpleMV
|
2
|
+
from project.sqlalchemy_db_.sqlalchemy_model import OperationDBM
|
3
|
+
|
4
|
+
|
5
|
+
class OperationMV(SimpleMV, model=OperationDBM):
|
6
|
+
name = "Operation"
|
7
|
+
name_plural = "Operations"
|
8
|
+
column_list = [
|
9
|
+
OperationDBM.id,
|
10
|
+
OperationDBM.long_id,
|
11
|
+
OperationDBM.slug,
|
12
|
+
OperationDBM.creation_dt,
|
13
|
+
OperationDBM.status,
|
14
|
+
OperationDBM.type,
|
15
|
+
OperationDBM.title,
|
16
|
+
OperationDBM.execution_start_dt,
|
17
|
+
OperationDBM.execution_finish_dt,
|
18
|
+
OperationDBM.input_data,
|
19
|
+
OperationDBM.output_data,
|
20
|
+
OperationDBM.error_data
|
21
|
+
]
|
22
|
+
form_columns = [
|
23
|
+
OperationDBM.slug,
|
24
|
+
OperationDBM.status,
|
25
|
+
OperationDBM.type,
|
26
|
+
OperationDBM.title,
|
27
|
+
OperationDBM.execution_start_dt,
|
28
|
+
OperationDBM.execution_finish_dt,
|
29
|
+
OperationDBM.input_data,
|
30
|
+
OperationDBM.output_data,
|
31
|
+
OperationDBM.error_data
|
32
|
+
]
|
33
|
+
column_default_sort = [
|
34
|
+
(OperationDBM.creation_dt, True)
|
35
|
+
]
|
36
|
+
column_searchable_list = [
|
37
|
+
OperationDBM.id,
|
38
|
+
OperationDBM.long_id,
|
39
|
+
OperationDBM.slug,
|
40
|
+
OperationDBM.status,
|
41
|
+
OperationDBM.type,
|
42
|
+
OperationDBM.title
|
43
|
+
]
|
@@ -0,0 +1,36 @@
|
|
1
|
+
from project.sqladmin_.model_view.common import SimpleMV
|
2
|
+
from project.sqlalchemy_db_.sqlalchemy_model import StoryLogDBM
|
3
|
+
|
4
|
+
|
5
|
+
class StoryLogMV(SimpleMV, model=StoryLogDBM):
|
6
|
+
name = "StoryLog"
|
7
|
+
name_plural = "StoryLogs"
|
8
|
+
column_list = [
|
9
|
+
StoryLogDBM.id,
|
10
|
+
StoryLogDBM.long_id,
|
11
|
+
StoryLogDBM.slug,
|
12
|
+
StoryLogDBM.creation_dt,
|
13
|
+
StoryLogDBM.level,
|
14
|
+
StoryLogDBM.type,
|
15
|
+
StoryLogDBM.title,
|
16
|
+
StoryLogDBM.data
|
17
|
+
]
|
18
|
+
form_columns = [
|
19
|
+
StoryLogDBM.slug,
|
20
|
+
StoryLogDBM.level,
|
21
|
+
StoryLogDBM.type,
|
22
|
+
StoryLogDBM.title,
|
23
|
+
StoryLogDBM.data
|
24
|
+
]
|
25
|
+
column_default_sort = [
|
26
|
+
(StoryLogDBM.creation_dt, True)
|
27
|
+
]
|
28
|
+
column_searchable_list = [
|
29
|
+
StoryLogDBM.id,
|
30
|
+
StoryLogDBM.long_id,
|
31
|
+
StoryLogDBM.slug,
|
32
|
+
StoryLogDBM.level,
|
33
|
+
StoryLogDBM.type,
|
34
|
+
StoryLogDBM.title,
|
35
|
+
StoryLogDBM.data
|
36
|
+
]
|
@@ -71,35 +71,33 @@ arpakitlib/_arpakit_project_template_v_2/project/additional_model/__init__.py,sh
|
|
71
71
|
arpakitlib/_arpakit_project_template_v_2/project/additional_model/common.py,sha256=dcvj5C9E2F2KCsGZPBBncQf_EvVJAC1qQgnyD8P4ZEw,6
|
72
72
|
arpakitlib/_arpakit_project_template_v_2/project/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
73
73
|
arpakitlib/_arpakit_project_template_v_2/project/api/asgi.py,sha256=ES3YGwNxWUHVyD6e2ii6QkvTyB-vlVmr8_PhfVIXQ4Y,78
|
74
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/auth.py,sha256=
|
74
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/auth.py,sha256=L2i5dDfmuCPIrfr2iMZIQ6ecQgeA2IAaNUXS1ykf2LU,11418
|
75
75
|
arpakitlib/_arpakit_project_template_v_2/project/api/const.py,sha256=J9bqaRRiIc3RLn6SJTvdfDvFrSsM_Ixii9t2M8dA5Jc,433
|
76
76
|
arpakitlib/_arpakit_project_template_v_2/project/api/create_api_app.py,sha256=3jdYXS0unrXYc6XGy6b8RPCoqC6iWNq7tRrAc6lhVd4,2268
|
77
77
|
arpakitlib/_arpakit_project_template_v_2/project/api/event.py,sha256=OwY9ECruH5tWHA4748irsjRIYA8zHfNjskP25lOYt5Q,2414
|
78
78
|
arpakitlib/_arpakit_project_template_v_2/project/api/exception.py,sha256=L2GyA6iWmTBDg8bUX2kIML9wYct_fjVvFBL4A9itNBk,1274
|
79
79
|
arpakitlib/_arpakit_project_template_v_2/project/api/exception_handler.py,sha256=dTJipFnXZHKT4YEOCMq_5rVdqCrT8YJ5Po1wK-dhLLA,11881
|
80
80
|
arpakitlib/_arpakit_project_template_v_2/project/api/openapi_ui.py,sha256=_56-dxdVhL8uMPpG4u1hccCIvLCSYL9qieC5qCTXvbE,900
|
81
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/response.py,sha256=
|
81
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/response.py,sha256=ChTlkEcjbelQdnMuZZyng81tGR2Ym2i0JsaJdLvQrJA,1073
|
82
82
|
arpakitlib/_arpakit_project_template_v_2/project/api/router/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
83
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/router/
|
84
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/router/
|
85
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/router/
|
86
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/router/
|
87
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/router/
|
88
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/router/
|
89
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/router/
|
90
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/router/v1/healthcheck.py,sha256=O2MzUonpADIafYIegbBe1JrJEndIZIFzqeLuDAH4Mro,486
|
91
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/router/v1/main_router.py,sha256=F_6jjYrjKbfeb7ZviqHIfYhNk42NfpdLQjHu6ABZgxc,1525
|
92
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/router/v1/now_utc_datetime.py,sha256=C1THyD_jrKbDooxxf6Qa06uOwWepvJF_q0tkrw7bqqo,534
|
93
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/router/v1/raise_fake_error.py,sha256=yN6FBxbS8cfVEWL9V_GA7OZTMZTS0yo6lcpqO8XyWyc,1398
|
94
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/router/v1/reinit_sqlalchemy_db.py,sha256=Y2ONlpJZmM7Mw5frXBjlmUHMkrKTeqrcRlAXISTyD10,1064
|
83
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/router/general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
84
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/router/general/get_auth_data.py,sha256=OMfTaRw-Lw06faha1TYp1zuTMnSpO7XSlB6tJiMq2PQ,1229
|
85
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/router/general/get_errors_info.py,sha256=_leajgqFHcYbkvZM9GTPgNsYnaDWCbQGx_bJtBRC6i0,1038
|
86
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/router/general/healthcheck.py,sha256=nPn2--WdStxsST05blYQcwNCAHci386oansLsKs-Rxw,823
|
87
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/router/general/main_router.py,sha256=dcNCjv1qkiH35iSu_i7Fe3dc60KQTwfxdaP5rHOdmtA,724
|
88
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/router/general/now_utc_datetime.py,sha256=XAPdBBIDcZMbIEYPyvH8hwnPBbJddFGwsEpE-qg3Ylo,851
|
89
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/router/main_router.py,sha256=Sle-bUWGWKQ8xuGvkIbsMaBHEwCo32mB8rO9Gu4N_kU,252
|
95
90
|
arpakitlib/_arpakit_project_template_v_2/project/api/schema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
96
91
|
arpakitlib/_arpakit_project_template_v_2/project/api/schema/base_schema.py,sha256=DX6Yz63JHoNlgmZnpss2PuRgEtBh3PPlxM6wImYLpXo,718
|
97
92
|
arpakitlib/_arpakit_project_template_v_2/project/api/schema/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
98
93
|
arpakitlib/_arpakit_project_template_v_2/project/api/schema/common/in_.py,sha256=pRScg2GVwrWZWkky-U3tjws9BHQvOm2cfRq-SYBMptA,89
|
99
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/schema/common/out.py,sha256=
|
100
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/schema/
|
101
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/schema/
|
102
|
-
arpakitlib/_arpakit_project_template_v_2/project/api/schema/
|
94
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/schema/common/out.py,sha256=8pGAT7ZPQpnmdcbUA1yvs4YGE9zHWFsSMmShBC6rLdE,1307
|
95
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/schema/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
96
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/schema/example/in_.py,sha256=UtzhupYrqveg4Q_MpdRdHQShqKfOOOFymkvU1b_nKtM,90
|
97
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/schema/example/out.py,sha256=_ly0YnVvrHR_bFqyeIHEiAvzQta6ni2mPi2V4_UIM70,1196
|
98
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/schema/general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
99
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/schema/general/in_.py,sha256=wZk46WpJYAAuBJNkNoKk5g1S-SHtt2JSFUhd3wSuldY,90
|
100
|
+
arpakitlib/_arpakit_project_template_v_2/project/api/schema/general/out.py,sha256=lvtNrS9GS0npUsb2IKUp_okU8pACZrxvEER18ShuFlY,288
|
103
101
|
arpakitlib/_arpakit_project_template_v_2/project/api/util.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
104
102
|
arpakitlib/_arpakit_project_template_v_2/project/business_service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
105
103
|
arpakitlib/_arpakit_project_template_v_2/project/business_service/hello_world.py,sha256=lvWlVF6SlnC33swSCd-_QK6guxBg50myOd8cPS7hZrA,251
|
@@ -163,9 +161,12 @@ arpakitlib/_arpakit_project_template_v_2/project/site/exception_handler.py,sha25
|
|
163
161
|
arpakitlib/_arpakit_project_template_v_2/project/site/router/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
164
162
|
arpakitlib/_arpakit_project_template_v_2/project/site/router/main_router.py,sha256=J5jNfgd-3OiWTtuubimEUz6wrOogupj9PkUdDmwz-2U,62
|
165
163
|
arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
166
|
-
arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/add_admin_in_app.py,sha256=
|
167
|
-
arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/admin_auth.py,sha256=
|
168
|
-
arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/model_view.py,sha256=
|
164
|
+
arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/add_admin_in_app.py,sha256=V1O-gF4QaGNVOLnVDgscED3vMpLNo61bFUwo0-tSeSg,747
|
165
|
+
arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/admin_auth.py,sha256=JubipPiAC3VDhyQfBCG_NNFuSRVBujbTjQ-qwEaqIhw,2191
|
166
|
+
arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/model_view/__init__.py,sha256=fHKKdhJK-6h6tNNEK5FkoZWUpr-BtugLZ1DXz0p91hw,182
|
167
|
+
arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/model_view/common.py,sha256=WSlZ2wOyrUVX-6nO0NRCZJ9dgPrY2ytANrhkooYq_w8,560
|
168
|
+
arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/model_view/operation.py,sha256=6qzWrt2xQ_2PL8SQYp4AZ-9qSgfbckd05HZcEg7dR4M,1232
|
169
|
+
arpakitlib/_arpakit_project_template_v_2/project/sqladmin_/model_view/story_log.py,sha256=WCxPZANZhW6TTBqu2H11ajaLdSe8uYoTO3NJFE2_57c,918
|
169
170
|
arpakitlib/_arpakit_project_template_v_2/project/sqlalchemy_db_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
170
171
|
arpakitlib/_arpakit_project_template_v_2/project/sqlalchemy_db_/const.py,sha256=dcvj5C9E2F2KCsGZPBBncQf_EvVJAC1qQgnyD8P4ZEw,6
|
171
172
|
arpakitlib/_arpakit_project_template_v_2/project/sqlalchemy_db_/sqlalchemy_db.py,sha256=1y3FaMFzm_5UM2poqtBve_UP_mh1vjs--krq6yO8PsA,742
|
@@ -257,8 +258,8 @@ arpakitlib/ar_type_util.py,sha256=Cs_tef-Fc5xeyAF54KgISCsP11NHyzIsglm4S3Xx7iM,40
|
|
257
258
|
arpakitlib/ar_wata_api_client.py,sha256=gdHOqDbuqxhTjVDtRW1DvkRJLdDofCrOq51GTctzLns,242
|
258
259
|
arpakitlib/ar_yookassa_api_client_util.py,sha256=VozuZeCJjmLd1zj2BdC9WfiAQ3XYOrIMsdpNK-AUlm0,5347
|
259
260
|
arpakitlib/ar_zabbix_api_client_util.py,sha256=Q-VR4MvoZ9aHwZeYZr9G3LwN-ANx1T5KFmF6pvPM-9M,6402
|
260
|
-
arpakitlib-1.8.
|
261
|
-
arpakitlib-1.8.
|
262
|
-
arpakitlib-1.8.
|
263
|
-
arpakitlib-1.8.
|
264
|
-
arpakitlib-1.8.
|
261
|
+
arpakitlib-1.8.15.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
|
262
|
+
arpakitlib-1.8.15.dist-info/METADATA,sha256=LC4NiadY9ZuMD9HhME2g_gzOsavI8Xcvy3QXK6CVInY,3358
|
263
|
+
arpakitlib-1.8.15.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
264
|
+
arpakitlib-1.8.15.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
|
265
|
+
arpakitlib-1.8.15.dist-info/RECORD,,
|
@@ -1,30 +0,0 @@
|
|
1
|
-
import fastapi.requests
|
2
|
-
from fastapi import APIRouter, Depends
|
3
|
-
|
4
|
-
from project.api.auth import APIAuthData, api_auth, correct_api_keys_from_settings__validate_api_key_func, \
|
5
|
-
correct_tokens_from_settings__validate_api_key_func
|
6
|
-
from project.api.schema.common.out import ErrorCommonSO, RawDataCommonSO
|
7
|
-
|
8
|
-
api_router = APIRouter()
|
9
|
-
|
10
|
-
|
11
|
-
@api_router.get(
|
12
|
-
path="",
|
13
|
-
name="Check auth",
|
14
|
-
status_code=fastapi.status.HTTP_200_OK,
|
15
|
-
response_model=RawDataCommonSO | ErrorCommonSO,
|
16
|
-
)
|
17
|
-
async def _(
|
18
|
-
*,
|
19
|
-
request: fastapi.requests.Request,
|
20
|
-
response: fastapi.responses.Response,
|
21
|
-
api_auth_data: APIAuthData = Depends(api_auth(
|
22
|
-
require_api_key_string=False,
|
23
|
-
require_token_string=False,
|
24
|
-
validate_api_key_func=correct_api_keys_from_settings__validate_api_key_func(),
|
25
|
-
validate_token_func=correct_tokens_from_settings__validate_api_key_func(),
|
26
|
-
require_correct_api_key=False,
|
27
|
-
require_correct_token=False,
|
28
|
-
))
|
29
|
-
):
|
30
|
-
return RawDataCommonSO(data=api_auth_data.model_dump())
|
@@ -1,34 +0,0 @@
|
|
1
|
-
import fastapi
|
2
|
-
from fastapi import APIRouter, Depends
|
3
|
-
|
4
|
-
from arpakitlib.ar_logging_util import init_log_file
|
5
|
-
from project.api.auth import APIAuthData, api_auth, correct_api_keys_from_settings__validate_api_key_func
|
6
|
-
from project.api.schema.common.out import RawDataCommonSO, ErrorCommonSO
|
7
|
-
from project.core.settings import get_cached_settings
|
8
|
-
|
9
|
-
api_router = APIRouter()
|
10
|
-
|
11
|
-
|
12
|
-
@api_router.get(
|
13
|
-
path="",
|
14
|
-
name="Clear log file",
|
15
|
-
status_code=fastapi.status.HTTP_200_OK,
|
16
|
-
response_model=RawDataCommonSO | ErrorCommonSO,
|
17
|
-
)
|
18
|
-
async def _(
|
19
|
-
*,
|
20
|
-
request: fastapi.requests.Request,
|
21
|
-
response: fastapi.responses.Response,
|
22
|
-
api_auth_data: APIAuthData = Depends(api_auth(
|
23
|
-
require_api_key_string=True,
|
24
|
-
require_token_string=False,
|
25
|
-
validate_api_key_func=correct_api_keys_from_settings__validate_api_key_func(),
|
26
|
-
validate_token_func=None,
|
27
|
-
require_correct_api_key=True,
|
28
|
-
require_correct_token=False,
|
29
|
-
))
|
30
|
-
):
|
31
|
-
init_log_file(log_filepath=get_cached_settings().log_filepath)
|
32
|
-
with open(file=get_cached_settings().log_filepath, mode="w") as f:
|
33
|
-
f.write("")
|
34
|
-
return RawDataCommonSO(data={"log_file_was_cleared": True})
|
@@ -1,22 +0,0 @@
|
|
1
|
-
import fastapi
|
2
|
-
from fastapi import APIRouter
|
3
|
-
|
4
|
-
from project.api.schema.common.out import ErrorCommonSO, RawDataCommonSO
|
5
|
-
from project.util.arpakitlib_project_template import get_arpakitlib_project_template_info
|
6
|
-
|
7
|
-
api_router = APIRouter()
|
8
|
-
|
9
|
-
|
10
|
-
@api_router.get(
|
11
|
-
"",
|
12
|
-
name="Get arpakitlib project template info",
|
13
|
-
status_code=fastapi.status.HTTP_200_OK,
|
14
|
-
response_model=RawDataCommonSO | ErrorCommonSO
|
15
|
-
)
|
16
|
-
async def _(
|
17
|
-
*,
|
18
|
-
request: fastapi.requests.Request,
|
19
|
-
response: fastapi.responses.Response,
|
20
|
-
):
|
21
|
-
arpakitlib_project_template_data = get_arpakitlib_project_template_info()
|
22
|
-
return RawDataCommonSO(data=arpakitlib_project_template_data)
|
@@ -1,32 +0,0 @@
|
|
1
|
-
import fastapi
|
2
|
-
from fastapi import APIRouter, Depends
|
3
|
-
from fastapi.responses import FileResponse
|
4
|
-
|
5
|
-
from arpakitlib.ar_logging_util import init_log_file
|
6
|
-
from project.api.auth import APIAuthData, api_auth, correct_api_keys_from_settings__validate_api_key_func
|
7
|
-
from project.core.settings import get_cached_settings
|
8
|
-
|
9
|
-
api_router = APIRouter()
|
10
|
-
|
11
|
-
|
12
|
-
@api_router.get(
|
13
|
-
path="",
|
14
|
-
name="Get log file",
|
15
|
-
status_code=fastapi.status.HTTP_200_OK,
|
16
|
-
response_class=FileResponse
|
17
|
-
)
|
18
|
-
async def _(
|
19
|
-
*,
|
20
|
-
request: fastapi.requests.Request,
|
21
|
-
response: fastapi.responses.Response,
|
22
|
-
api_auth_data: APIAuthData = Depends(api_auth(
|
23
|
-
require_api_key_string=True,
|
24
|
-
require_token_string=False,
|
25
|
-
validate_api_key_func=correct_api_keys_from_settings__validate_api_key_func(),
|
26
|
-
validate_token_func=None,
|
27
|
-
require_correct_api_key=True,
|
28
|
-
require_correct_token=False,
|
29
|
-
))
|
30
|
-
):
|
31
|
-
init_log_file(log_filepath=get_cached_settings().log_filepath)
|
32
|
-
return FileResponse(path=get_cached_settings().log_filepath)
|
@@ -1,21 +0,0 @@
|
|
1
|
-
import fastapi
|
2
|
-
from fastapi import APIRouter
|
3
|
-
|
4
|
-
from project.api.schema.common.out import ErrorCommonSO
|
5
|
-
from project.api.schema.v1.out import HealthcheckV1SO
|
6
|
-
|
7
|
-
api_router = APIRouter()
|
8
|
-
|
9
|
-
|
10
|
-
@api_router.get(
|
11
|
-
"",
|
12
|
-
name="Healthcheck",
|
13
|
-
status_code=fastapi.status.HTTP_200_OK,
|
14
|
-
response_model=HealthcheckV1SO | ErrorCommonSO,
|
15
|
-
)
|
16
|
-
async def _(
|
17
|
-
*,
|
18
|
-
request: fastapi.requests.Request,
|
19
|
-
response: fastapi.responses.Response,
|
20
|
-
):
|
21
|
-
return HealthcheckV1SO(is_ok=True)
|
@@ -1,59 +0,0 @@
|
|
1
|
-
from fastapi import APIRouter
|
2
|
-
|
3
|
-
from project.api.router.v1 import healthcheck, get_errors_info, now_utc_datetime, clear_log_file, get_log_file, \
|
4
|
-
get_arpakitlib_project_template_info, reinit_sqlalchemy_db, check_auth, raise_fake_error
|
5
|
-
|
6
|
-
main_v1_api_router = APIRouter()
|
7
|
-
|
8
|
-
main_v1_api_router.include_router(
|
9
|
-
router=healthcheck.api_router,
|
10
|
-
prefix="/healthcheck",
|
11
|
-
tags=["Healthcheck"]
|
12
|
-
)
|
13
|
-
|
14
|
-
main_v1_api_router.include_router(
|
15
|
-
router=get_arpakitlib_project_template_info.api_router,
|
16
|
-
prefix="/get_arpakitlib_project_template_info",
|
17
|
-
tags=["arpakitlib project template info"]
|
18
|
-
)
|
19
|
-
|
20
|
-
main_v1_api_router.include_router(
|
21
|
-
router=get_errors_info.api_router,
|
22
|
-
prefix="/get_errors_info",
|
23
|
-
tags=["Errors info"]
|
24
|
-
)
|
25
|
-
|
26
|
-
main_v1_api_router.include_router(
|
27
|
-
router=check_auth.api_router,
|
28
|
-
prefix="/check_auth",
|
29
|
-
tags=["Check auth"]
|
30
|
-
)
|
31
|
-
|
32
|
-
main_v1_api_router.include_router(
|
33
|
-
router=raise_fake_error.api_router,
|
34
|
-
prefix="/raise_fake_error",
|
35
|
-
tags=["Fake error"]
|
36
|
-
)
|
37
|
-
|
38
|
-
main_v1_api_router.include_router(
|
39
|
-
router=now_utc_datetime.api_router,
|
40
|
-
prefix="/now_utc_datetime",
|
41
|
-
tags=["Now UTC datetime"]
|
42
|
-
)
|
43
|
-
|
44
|
-
main_v1_api_router.include_router(
|
45
|
-
router=get_log_file.api_router,
|
46
|
-
prefix="/get_log_file",
|
47
|
-
tags=["Log file"]
|
48
|
-
)
|
49
|
-
main_v1_api_router.include_router(
|
50
|
-
router=clear_log_file.api_router,
|
51
|
-
prefix="/clear_log_file",
|
52
|
-
tags=["Log file"]
|
53
|
-
)
|
54
|
-
|
55
|
-
main_v1_api_router.include_router(
|
56
|
-
router=reinit_sqlalchemy_db.api_router,
|
57
|
-
prefix="/reinit_sqlalchemy_db",
|
58
|
-
tags=["Reinit SQLAlchemy db"]
|
59
|
-
)
|
@@ -1,44 +0,0 @@
|
|
1
|
-
import fastapi
|
2
|
-
import starlette.exceptions
|
3
|
-
from fastapi import APIRouter, Depends
|
4
|
-
|
5
|
-
from project.api.auth import APIAuthData, api_auth, correct_api_keys_from_settings__validate_api_key_func
|
6
|
-
from project.api.schema.common.out import ErrorCommonSO
|
7
|
-
|
8
|
-
api_router = APIRouter()
|
9
|
-
|
10
|
-
|
11
|
-
@api_router.get(
|
12
|
-
"",
|
13
|
-
name="Raise fake error",
|
14
|
-
response_model=ErrorCommonSO,
|
15
|
-
status_code=fastapi.status.HTTP_500_INTERNAL_SERVER_ERROR
|
16
|
-
)
|
17
|
-
async def _(
|
18
|
-
*,
|
19
|
-
request: fastapi.requests.Request,
|
20
|
-
response: fastapi.responses.Response,
|
21
|
-
n: int | None = None,
|
22
|
-
api_auth_data: APIAuthData = Depends(api_auth(
|
23
|
-
require_api_key_string=True,
|
24
|
-
require_token_string=False,
|
25
|
-
validate_api_key_func=correct_api_keys_from_settings__validate_api_key_func(),
|
26
|
-
validate_token_func=None,
|
27
|
-
require_correct_api_key=True,
|
28
|
-
require_correct_token=False,
|
29
|
-
))
|
30
|
-
):
|
31
|
-
if n == 1:
|
32
|
-
raise fastapi.HTTPException(
|
33
|
-
detail={"n": n},
|
34
|
-
status_code=fastapi.status.HTTP_500_INTERNAL_SERVER_ERROR
|
35
|
-
)
|
36
|
-
elif n == 2:
|
37
|
-
raise starlette.exceptions.HTTPException(
|
38
|
-
detail=f"fake_error, n={n}",
|
39
|
-
status_code=fastapi.status.HTTP_500_INTERNAL_SERVER_ERROR
|
40
|
-
)
|
41
|
-
elif n == 3:
|
42
|
-
raise ValueError(f"fake error n={n}")
|
43
|
-
else:
|
44
|
-
raise Exception(f"fake error, n={n}")
|
@@ -1,33 +0,0 @@
|
|
1
|
-
import fastapi
|
2
|
-
from fastapi import APIRouter
|
3
|
-
|
4
|
-
from project.api.auth import APIAuthData, api_auth
|
5
|
-
from project.api.schema.common.out import ErrorCommonSO, RawDataCommonSO
|
6
|
-
from project.core.settings import ModeTypes
|
7
|
-
from project.sqlalchemy_db_.sqlalchemy_db import get_cached_sqlalchemy_db
|
8
|
-
|
9
|
-
api_router = APIRouter()
|
10
|
-
|
11
|
-
|
12
|
-
@api_router.get(
|
13
|
-
"",
|
14
|
-
name="Reinit SQLAlchemy db",
|
15
|
-
status_code=fastapi.status.HTTP_200_OK,
|
16
|
-
response_model=RawDataCommonSO | ErrorCommonSO,
|
17
|
-
)
|
18
|
-
async def _(
|
19
|
-
*,
|
20
|
-
request: fastapi.requests.Request,
|
21
|
-
response: fastapi.responses.Response,
|
22
|
-
api_auth_data: APIAuthData = fastapi.Depends(api_auth(
|
23
|
-
require_api_key_string=True,
|
24
|
-
require_token_string=False,
|
25
|
-
validate_api_key_func=None,
|
26
|
-
validate_token_func=None,
|
27
|
-
require_correct_api_key=False,
|
28
|
-
require_correct_token=False,
|
29
|
-
require_not_mode_type=ModeTypes.prod
|
30
|
-
))
|
31
|
-
):
|
32
|
-
get_cached_sqlalchemy_db().reinit()
|
33
|
-
return RawDataCommonSO(data={"sqlalchemy_db_was_reinited": True})
|
@@ -1,47 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
import datetime as dt
|
4
|
-
from typing import Any
|
5
|
-
|
6
|
-
from project.api.schema.base_schema import BaseSO
|
7
|
-
from project.sqlalchemy_db_.sqlalchemy_model import OperationDBM, StoryLogDBM
|
8
|
-
|
9
|
-
|
10
|
-
class BaseV1SO(BaseSO):
|
11
|
-
pass
|
12
|
-
|
13
|
-
|
14
|
-
class HealthcheckV1SO(BaseV1SO):
|
15
|
-
is_ok: bool = True
|
16
|
-
|
17
|
-
|
18
|
-
class _SimpleDBMV1SO(BaseV1SO):
|
19
|
-
id: int
|
20
|
-
long_id: str
|
21
|
-
creation_dt: dt.datetime
|
22
|
-
|
23
|
-
|
24
|
-
class StoryLogV1SO(_SimpleDBMV1SO):
|
25
|
-
level: str
|
26
|
-
type: str | None = None
|
27
|
-
title: str | None = None
|
28
|
-
data: dict[str, Any] = {}
|
29
|
-
|
30
|
-
@classmethod
|
31
|
-
def from_story_log_dbm(cls, *, story_log_dbm: StoryLogDBM) -> StoryLogV1SO:
|
32
|
-
return cls.model_validate(story_log_dbm.simple_dict_with_sd_properties())
|
33
|
-
|
34
|
-
|
35
|
-
class OperationV1SO(_SimpleDBMV1SO):
|
36
|
-
execution_start_dt: dt.datetime | None = None
|
37
|
-
execution_finish_dt: dt.datetime | None = None
|
38
|
-
status: str
|
39
|
-
type: str
|
40
|
-
input_data: dict[str, Any] = {}
|
41
|
-
output_data: dict[str, Any] = {}
|
42
|
-
error_data: dict[str, Any] = {}
|
43
|
-
duration_total_seconds: float | None = None
|
44
|
-
|
45
|
-
@classmethod
|
46
|
-
def from_operation_dbm(cls, *, operation_dbm: OperationDBM) -> OperationV1SO:
|
47
|
-
return cls.model_validate(operation_dbm.simple_dict_with_sd_properties())
|
@@ -1,95 +0,0 @@
|
|
1
|
-
from sqladmin import ModelView
|
2
|
-
|
3
|
-
from arpakitlib.ar_sqladmin_util import get_string_info_from_model_view
|
4
|
-
from project.sqlalchemy_db_.sqlalchemy_model import StoryLogDBM, OperationDBM
|
5
|
-
|
6
|
-
|
7
|
-
class SimpleMV(ModelView):
|
8
|
-
can_create = True
|
9
|
-
can_edit = True
|
10
|
-
can_delete = True
|
11
|
-
can_view_details = True
|
12
|
-
can_export = True
|
13
|
-
page_size = 50
|
14
|
-
page_size_options = [50, 100, 200]
|
15
|
-
save_as = True
|
16
|
-
save_as_continue = True
|
17
|
-
export_types = ["xlsx", "csv", "json"]
|
18
|
-
|
19
|
-
|
20
|
-
class StoryLogMV(SimpleMV, model=StoryLogDBM):
|
21
|
-
name = "StoryLog"
|
22
|
-
name_plural = "StoryLogs"
|
23
|
-
column_list = [
|
24
|
-
StoryLogDBM.id,
|
25
|
-
StoryLogDBM.long_id,
|
26
|
-
StoryLogDBM.creation_dt,
|
27
|
-
StoryLogDBM.level,
|
28
|
-
StoryLogDBM.type,
|
29
|
-
StoryLogDBM.title,
|
30
|
-
StoryLogDBM.data
|
31
|
-
]
|
32
|
-
form_columns = [
|
33
|
-
StoryLogDBM.level,
|
34
|
-
StoryLogDBM.type,
|
35
|
-
StoryLogDBM.title,
|
36
|
-
StoryLogDBM.data
|
37
|
-
]
|
38
|
-
column_default_sort = [
|
39
|
-
(StoryLogDBM.creation_dt, True)
|
40
|
-
]
|
41
|
-
column_searchable_list = [
|
42
|
-
StoryLogDBM.id,
|
43
|
-
StoryLogDBM.long_id,
|
44
|
-
StoryLogDBM.level,
|
45
|
-
StoryLogDBM.type,
|
46
|
-
StoryLogDBM.title,
|
47
|
-
StoryLogDBM.data
|
48
|
-
]
|
49
|
-
|
50
|
-
|
51
|
-
class OperationMV(SimpleMV, model=OperationDBM):
|
52
|
-
name = "Operation"
|
53
|
-
name_plural = "Operations"
|
54
|
-
column_list = [
|
55
|
-
OperationDBM.id,
|
56
|
-
OperationDBM.long_id,
|
57
|
-
OperationDBM.creation_dt,
|
58
|
-
OperationDBM.status,
|
59
|
-
OperationDBM.type,
|
60
|
-
OperationDBM.execution_start_dt,
|
61
|
-
OperationDBM.execution_finish_dt,
|
62
|
-
OperationDBM.input_data,
|
63
|
-
OperationDBM.output_data,
|
64
|
-
OperationDBM.error_data
|
65
|
-
]
|
66
|
-
form_columns = [
|
67
|
-
OperationDBM.status,
|
68
|
-
OperationDBM.type,
|
69
|
-
OperationDBM.execution_start_dt,
|
70
|
-
OperationDBM.execution_finish_dt,
|
71
|
-
OperationDBM.input_data,
|
72
|
-
OperationDBM.output_data,
|
73
|
-
OperationDBM.error_data
|
74
|
-
]
|
75
|
-
column_default_sort = [
|
76
|
-
(OperationDBM.creation_dt, True)
|
77
|
-
]
|
78
|
-
column_searchable_list = [
|
79
|
-
OperationDBM.id,
|
80
|
-
OperationDBM.long_id,
|
81
|
-
OperationDBM.status,
|
82
|
-
OperationDBM.type,
|
83
|
-
]
|
84
|
-
|
85
|
-
|
86
|
-
def get_simple_mv() -> type[SimpleMV]:
|
87
|
-
return SimpleMV
|
88
|
-
|
89
|
-
|
90
|
-
def import_sqladmin_model_views():
|
91
|
-
pass
|
92
|
-
|
93
|
-
|
94
|
-
if __name__ == '__main__':
|
95
|
-
print(get_string_info_from_model_view(class_=SimpleMV))
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|