arpakitlib 1.8.225__py3-none-any.whl → 1.8.227__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_5/arpakitlib_project_template_info.json +1 -1
- arpakitlib/_arpakit_project_template_v_5/project/api/start_api.py +4 -1
- arpakitlib/_arpakit_project_template_v_5/project/core/settings.py +6 -0
- arpakitlib/clone_pydantic_model_fields.py +3 -0
- arpakitlib/pydantic_schema_from_sqlalchemy_model.py +2 -0
- arpakitlib/raise_own_exception_if_exception.py +95 -0
- {arpakitlib-1.8.225.dist-info → arpakitlib-1.8.227.dist-info}/METADATA +1 -1
- {arpakitlib-1.8.225.dist-info → arpakitlib-1.8.227.dist-info}/RECORD +11 -10
- {arpakitlib-1.8.225.dist-info → arpakitlib-1.8.227.dist-info}/LICENSE +0 -0
- {arpakitlib-1.8.225.dist-info → arpakitlib-1.8.227.dist-info}/WHEEL +0 -0
- {arpakitlib-1.8.225.dist-info → arpakitlib-1.8.227.dist-info}/entry_points.txt +0 -0
@@ -13,7 +13,10 @@ def start_api():
|
|
13
13
|
port=get_cached_settings().api_port,
|
14
14
|
host=get_cached_settings().api_host,
|
15
15
|
workers=get_cached_settings().api_workers,
|
16
|
-
reload=get_cached_settings().api_reload
|
16
|
+
reload=get_cached_settings().api_reload,
|
17
|
+
timeout_keep_alive=get_cached_settings().api_uvicorn_timeout_keep_alive,
|
18
|
+
limit_concurrency=get_cached_settings().api_uvicorn_limit_concurrency,
|
19
|
+
backlog=get_cached_settings().api_uvicorn_backlog,
|
17
20
|
)
|
18
21
|
|
19
22
|
|
@@ -129,6 +129,12 @@ class Settings(SimpleSettings):
|
|
129
129
|
|
130
130
|
api_openapi_url: str = "/secret/openapi"
|
131
131
|
|
132
|
+
api_uvicorn_timeout_keep_alive: int = 3
|
133
|
+
|
134
|
+
api_uvicorn_limit_concurrency: int = 1000
|
135
|
+
|
136
|
+
api_uvicorn_backlog: int = 2048
|
137
|
+
|
132
138
|
sqladmin_secret_key: str | None = "85a9583cb91c4de7a78d7eb1e5306a04418c9c43014c447ea8ec8dd5deb4cf71"
|
133
139
|
|
134
140
|
sqladmin_authorize_keys: list[str] | None = ["1"]
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# arpakit
|
1
2
|
import datetime as dt
|
2
3
|
from typing import Any, Optional
|
3
4
|
|
@@ -10,6 +11,7 @@ from sqlalchemy.sql.sqltypes import (
|
|
10
11
|
DateTime, Date, Time,
|
11
12
|
Float, Numeric, DECIMAL, LargeBinary, JSON
|
12
13
|
)
|
14
|
+
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
13
15
|
|
14
16
|
_SQLA_TYPE_MAP = {
|
15
17
|
Boolean: bool,
|
@@ -0,0 +1,95 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import inspect
|
4
|
+
from functools import wraps
|
5
|
+
from typing import Any, Callable, Awaitable, Tuple, TypeVar, ParamSpec, cast
|
6
|
+
|
7
|
+
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
8
|
+
|
9
|
+
PARAMS_SPEC = ParamSpec("PARAMS_SPEC")
|
10
|
+
RESULT_SPEC = TypeVar("RESULT_SPEC")
|
11
|
+
|
12
|
+
|
13
|
+
def raise_own_exception_if_exception(
|
14
|
+
*,
|
15
|
+
catching_exceptions: type[BaseException] | Tuple[type[BaseException], ...] | None = Exception,
|
16
|
+
except_catching_exceptions: type[BaseException] | Tuple[type[BaseException], ...] | None = None,
|
17
|
+
own_exception: type[Exception],
|
18
|
+
kwargs_in_own_exception: dict[str, Any] | None = None,
|
19
|
+
) -> (
|
20
|
+
Callable[[Callable[PARAMS_SPEC, RESULT_SPEC] | Callable[PARAMS_SPEC, Awaitable[RESULT_SPEC]]],
|
21
|
+
Callable[PARAMS_SPEC, RESULT_SPEC] | Callable[PARAMS_SPEC, Awaitable[RESULT_SPEC]]]
|
22
|
+
):
|
23
|
+
"""
|
24
|
+
Ловит любые Exception и оборачивает в own_exception(**kwargs_).
|
25
|
+
Исключения из except_exceptions пропускает как есть.
|
26
|
+
Работает и для sync, и для async функций.
|
27
|
+
"""
|
28
|
+
|
29
|
+
# normalize catching_exceptions -> tuple[type, ...]
|
30
|
+
if catching_exceptions is None:
|
31
|
+
catching_exceptions = (Exception,)
|
32
|
+
elif isinstance(catching_exceptions, tuple):
|
33
|
+
catching_exceptions = catching_exceptions
|
34
|
+
else:
|
35
|
+
catching_exceptions = (catching_exceptions,)
|
36
|
+
|
37
|
+
# Нормализуем except_exceptions к кортежу типов
|
38
|
+
if except_catching_exceptions is None:
|
39
|
+
except_catching_exceptions = ()
|
40
|
+
elif isinstance(except_catching_exceptions, tuple):
|
41
|
+
except_catching_exceptions = except_catching_exceptions
|
42
|
+
elif except_catching_exceptions:
|
43
|
+
except_catching_exceptions = (except_catching_exceptions,)
|
44
|
+
else:
|
45
|
+
except_catching_exceptions = ()
|
46
|
+
|
47
|
+
kwargs_in_own_exception = dict(kwargs_in_own_exception or {})
|
48
|
+
kwargs_in_own_exception["catching_exceptions"] = catching_exceptions
|
49
|
+
kwargs_in_own_exception["except_catching_exceptions"] = except_catching_exceptions
|
50
|
+
kwargs_in_own_exception["own_exception"] = own_exception
|
51
|
+
|
52
|
+
# Если явно передали пустой набор для ловли — возвращаем функцию как есть
|
53
|
+
if not catching_exceptions:
|
54
|
+
def _passthrough_decorator(func):
|
55
|
+
return func
|
56
|
+
|
57
|
+
return _passthrough_decorator
|
58
|
+
|
59
|
+
def decorator(func: Callable[PARAMS_SPEC, RESULT_SPEC] | Callable[PARAMS_SPEC, Awaitable[RESULT_SPEC]]):
|
60
|
+
if inspect.iscoroutinefunction(func):
|
61
|
+
@wraps(func)
|
62
|
+
async def async_wrapper(*args: PARAMS_SPEC.args, **kwargs: PARAMS_SPEC.kwargs) -> RESULT_SPEC:
|
63
|
+
try:
|
64
|
+
return await cast(Callable[PARAMS_SPEC, Awaitable[RESULT_SPEC]], func)(*args, **kwargs)
|
65
|
+
except catching_exceptions as caught_exception: # ловим ТОЛЬКО нужные типы
|
66
|
+
if except_catching_exceptions and isinstance(caught_exception, except_catching_exceptions):
|
67
|
+
raise # пропускаем как есть
|
68
|
+
copied_kwargs_in_own_exception = kwargs_in_own_exception.copy()
|
69
|
+
copied_kwargs_in_own_exception["caught_exception"] = caught_exception
|
70
|
+
copied_kwargs_in_own_exception["caught_exception_str"] = str(caught_exception)
|
71
|
+
try:
|
72
|
+
raise own_exception(kwargs_=copied_kwargs_in_own_exception) from caught_exception
|
73
|
+
except TypeError:
|
74
|
+
raise own_exception() from caught_exception
|
75
|
+
|
76
|
+
return cast(Callable[PARAMS_SPEC, Awaitable[RESULT_SPEC]], async_wrapper)
|
77
|
+
|
78
|
+
@wraps(func)
|
79
|
+
def wrapper(*args: PARAMS_SPEC.args, **kwargs: PARAMS_SPEC.kwargs) -> RESULT_SPEC:
|
80
|
+
try:
|
81
|
+
return cast(Callable[PARAMS_SPEC, RESULT_SPEC], func)(*args, **kwargs)
|
82
|
+
except catching_exceptions as caught_exception:
|
83
|
+
if except_catching_exceptions and isinstance(caught_exception, except_catching_exceptions):
|
84
|
+
raise
|
85
|
+
copied_kwargs_in_own_exception = kwargs_in_own_exception.copy()
|
86
|
+
copied_kwargs_in_own_exception["caught_exception"] = caught_exception
|
87
|
+
copied_kwargs_in_own_exception["caught_exception_str"] = str(caught_exception)
|
88
|
+
try:
|
89
|
+
raise own_exception(kwargs_=copied_kwargs_in_own_exception) from caught_exception
|
90
|
+
except TypeError:
|
91
|
+
raise own_exception() from caught_exception
|
92
|
+
|
93
|
+
return cast(Callable[PARAMS_SPEC, RESULT_SPEC], wrapper)
|
94
|
+
|
95
|
+
return decorator
|
@@ -8,7 +8,7 @@ arpakitlib/_arpakit_project_template_v_5/alembic/env.py,sha256=Qesmnj5A2kB-Doeuf
|
|
8
8
|
arpakitlib/_arpakit_project_template_v_5/alembic/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
|
9
9
|
arpakitlib/_arpakit_project_template_v_5/alembic/versions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
arpakitlib/_arpakit_project_template_v_5/alembic.ini,sha256=8fuyeEvGBiPGbxEFy8ISBV3xX_fgVmuhEGpB10_B5Uo,3733
|
11
|
-
arpakitlib/_arpakit_project_template_v_5/arpakitlib_project_template_info.json,sha256=
|
11
|
+
arpakitlib/_arpakit_project_template_v_5/arpakitlib_project_template_info.json,sha256=C_MYSLufFOeakgn7AdJRDZ1Ju13vyaGZWfiG3z3c-4Y,98
|
12
12
|
arpakitlib/_arpakit_project_template_v_5/command/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
13
|
arpakitlib/_arpakit_project_template_v_5/command/alembic_history.sh,sha256=OMnDNtHIksGh9iavWnzbtxcudZW4vjdcISsBXvzZSPw,22
|
14
14
|
arpakitlib/_arpakit_project_template_v_5/command/alembic_revision_autogenerate.sh,sha256=yW2i-SBOtBx15Ya0poVQqKkJM5t2JZp06r9AEW-DmGE,46
|
@@ -169,7 +169,7 @@ arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/user.py,
|
|
169
169
|
arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/user_token.py,sha256=iiuZXu_zo3FJX0W5qyyMGasUx-_d32yjqc_2KY3xpUA,513
|
170
170
|
arpakitlib/_arpakit_project_template_v_5/project/api/schema/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
171
171
|
arpakitlib/_arpakit_project_template_v_5/project/api/schema/util/create_obj_schema_from_dbm.py,sha256=7HizltD9MyK1nltQQHAjy69TCOuFDkkgtFJDr7DjLxU,331
|
172
|
-
arpakitlib/_arpakit_project_template_v_5/project/api/start_api.py,sha256=
|
172
|
+
arpakitlib/_arpakit_project_template_v_5/project/api/start_api.py,sha256=9VOBnqXsbh0zh96EilNO2gSaUlol04aJO7EbvT1iTko,752
|
173
173
|
arpakitlib/_arpakit_project_template_v_5/project/api/util.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
174
174
|
arpakitlib/_arpakit_project_template_v_5/project/business_service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
175
175
|
arpakitlib/_arpakit_project_template_v_5/project/business_service/exception.py,sha256=HPs7trDBdXEb0B3LCzDIMJd1uSHPIWs7TI43ogWrONU,635
|
@@ -183,7 +183,7 @@ arpakitlib/_arpakit_project_template_v_5/project/core/dump_file_storage_in_dir.p
|
|
183
183
|
arpakitlib/_arpakit_project_template_v_5/project/core/easy_openai_api_client.py,sha256=ssQ8Ju6CBQeXSOa_lfLaqycSf0a-NIj6ucOhEsPseVc,1141
|
184
184
|
arpakitlib/_arpakit_project_template_v_5/project/core/jinja2_templates.py,sha256=jCNLaBauGC7YNvZdTLNHuPp7hmRGt94O23Skg6ewo7o,352
|
185
185
|
arpakitlib/_arpakit_project_template_v_5/project/core/media_file_storage_in_dir.py,sha256=fMofTsfJtA8pp5lEUhucEUu3PBsmj-elaRZzExDsdLI,623
|
186
|
-
arpakitlib/_arpakit_project_template_v_5/project/core/settings.py,sha256
|
186
|
+
arpakitlib/_arpakit_project_template_v_5/project/core/settings.py,sha256=-pxFzibJiQiOq9wId4UCfFa8T84J3PwioZBcYANKyf0,6915
|
187
187
|
arpakitlib/_arpakit_project_template_v_5/project/core/setup_logging.py,sha256=7VRejVMUNeR-MywrVw7B1RxVkIBHwVNQJFC4wlpBJco,1497
|
188
188
|
arpakitlib/_arpakit_project_template_v_5/project/core/util.py,sha256=iCwpuRqr6TfW0sKVH-3asQjhueJuad3ffq6sPI6ZUrs,347
|
189
189
|
arpakitlib/_arpakit_project_template_v_5/project/emailer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -415,10 +415,11 @@ arpakitlib/ar_sqlalchemy_util.py,sha256=aNHK7kT1VNSHmGx8m6KsaLOZ9ofO7pFa10rW4vZe
|
|
415
415
|
arpakitlib/ar_str_util.py,sha256=2lGpnXDf2h1cBZpVf5i1tX_HCv5iBd6IGnrCw4QWWlY,4350
|
416
416
|
arpakitlib/ar_type_util.py,sha256=Cs_tef-Fc5xeyAF54KgISCsP11NHyzIsglm4S3Xx7iM,4049
|
417
417
|
arpakitlib/ar_yookassa_api_client_util.py,sha256=VozuZeCJjmLd1zj2BdC9WfiAQ3XYOrIMsdpNK-AUlm0,5347
|
418
|
-
arpakitlib/clone_pydantic_model_fields.py,sha256=
|
419
|
-
arpakitlib/pydantic_schema_from_sqlalchemy_model.py,sha256=
|
420
|
-
arpakitlib
|
421
|
-
arpakitlib-1.8.
|
422
|
-
arpakitlib-1.8.
|
423
|
-
arpakitlib-1.8.
|
424
|
-
arpakitlib-1.8.
|
418
|
+
arpakitlib/clone_pydantic_model_fields.py,sha256=xxLwtvJzDf8EWMvBE4psWIj8c-cyeCxLRX76oCY_4zk,1214
|
419
|
+
arpakitlib/pydantic_schema_from_sqlalchemy_model.py,sha256=_5Y79kQ4lLIOL6_afIFVwxY1EXzTMpi-veRR-WkPFOs,2879
|
420
|
+
arpakitlib/raise_own_exception_if_exception.py,sha256=XfLYQzfStHJMlaqCOvRuXZBRzcUn2Cj2a-vKJ_hspf8,4686
|
421
|
+
arpakitlib-1.8.227.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
|
422
|
+
arpakitlib-1.8.227.dist-info/METADATA,sha256=FghQl3kN8IgyPeZmk49PuhjyYDJtDH509y9NBuuD8Ds,3741
|
423
|
+
arpakitlib-1.8.227.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
424
|
+
arpakitlib-1.8.227.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
|
425
|
+
arpakitlib-1.8.227.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|