arpakitlib 1.8.326__py3-none-any.whl → 1.8.328__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.
Files changed (31) hide show
  1. arpakitlib/_arpakit_project_template_v_5/project/api/raise_own_exception_if_exception_in_api_router.py +1 -1
  2. arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_3.py +1 -1
  3. arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_4.py +1 -1
  4. arpakitlib/ar_aiogram_as_tg_command_util.py +1 -1
  5. arpakitlib/ar_arpakitlib_cli_util.py +1 -1
  6. arpakitlib/ar_base_worker_util.py +1 -1
  7. arpakitlib/ar_blank_util.py +18 -19
  8. arpakitlib/ar_http_request_util.py +28 -10
  9. arpakitlib/ar_include_fastapi_routers_from_dir_util.py +1 -0
  10. arpakitlib/ar_list_util.py +2 -2
  11. arpakitlib/{ar_log_async_func_if_error.py → ar_log_async_func_if_error_util.py} +11 -3
  12. arpakitlib/ar_logging_util.py +0 -1
  13. arpakitlib/ar_openai_api_client_util.py +204 -0
  14. arpakitlib/{ar_raise_own_exception_if_exception.py → ar_raise_own_exception_if_exception_util.py} +1 -0
  15. arpakitlib/ar_sqlalchemy_util.py +2 -2
  16. arpakitlib/ar_yookassa_api_client_util.py +1 -0
  17. {arpakitlib-1.8.326.dist-info → arpakitlib-1.8.328.dist-info}/METADATA +1 -1
  18. {arpakitlib-1.8.326.dist-info → arpakitlib-1.8.328.dist-info}/RECORD +31 -30
  19. /arpakitlib/{ar_clone_pydantic_model_fields.py → ar_clone_pydantic_model_fields_util.py} +0 -0
  20. /arpakitlib/{ar_generate_simple_code.py → ar_generate_simple_code_util.py} +0 -0
  21. /arpakitlib/{ar_list_of_dicts_to_xlsx.py → ar_list_of_dicts_to_xlsx_util.py} +0 -0
  22. /arpakitlib/{ar_parse_command.py → ar_parse_command_util.py} +0 -0
  23. /arpakitlib/{ar_pydantic_schema_from_sqlalchemy_model.py → ar_pydantic_schema_from_sqlalchemy_model_util.py} +0 -0
  24. /arpakitlib/{ar_really_validate_email.py → ar_really_validate_email_util.py} +0 -0
  25. /arpakitlib/{ar_really_validate_url.py → ar_really_validate_url_util.py} +0 -0
  26. /arpakitlib/{ar_sqlalchemy_drop_check_constraints.py → ar_sqlalchemy_drop_check_constraints_util.py} +0 -0
  27. /arpakitlib/{ar_sqlalchemy_ensure_check_constraints.py → ar_sqlalchemy_ensure_check_constraints_util.py} +0 -0
  28. /arpakitlib/{ar_uppercase_env_keys.py → ar_uppercase_env_keys_util.py} +0 -0
  29. {arpakitlib-1.8.326.dist-info → arpakitlib-1.8.328.dist-info}/WHEEL +0 -0
  30. {arpakitlib-1.8.326.dist-info → arpakitlib-1.8.328.dist-info}/entry_points.txt +0 -0
  31. {arpakitlib-1.8.326.dist-info → arpakitlib-1.8.328.dist-info}/licenses/LICENSE +0 -0
@@ -1,7 +1,7 @@
1
1
  from typing import Any
2
2
 
3
3
  import fastapi
4
- from arpakitlib.ar_raise_own_exception_if_exception import raise_own_exception_if_exception
4
+ from arpakitlib.ar_raise_own_exception_if_exception_util import raise_own_exception_if_exception
5
5
 
6
6
  from project.api.api_exception import APIException
7
7
  from project.api.schema.out.common.error import ErrorCommonSO
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
 
3
- from arpakitlib.ar_pydantic_schema_from_sqlalchemy_model import pydantic_schema_from_sqlalchemy_model
3
+ from arpakitlib.ar_pydantic_schema_from_sqlalchemy_model_util import pydantic_schema_from_sqlalchemy_model
4
4
  from project.sqlalchemy_db_.sqlalchemy_model import UserDBM
5
5
 
6
6
 
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
 
3
- from arpakitlib.ar_pydantic_schema_from_sqlalchemy_model import _get_property_name_to_type_from_model_class
3
+ from arpakitlib.ar_pydantic_schema_from_sqlalchemy_model_util import _get_property_name_to_type_from_model_class
4
4
  from project.sqlalchemy_db_.sqlalchemy_model import UserDBM
5
5
 
6
6
 
@@ -10,7 +10,7 @@ from aiogram.filters import CommandObject
10
10
  from pydantic import BaseModel
11
11
 
12
12
  from arpakitlib.ar_need_type_util import parse_need_type, NeedTypes
13
- from arpakitlib.ar_parse_command import BadCommandFormat, parse_command
13
+ from arpakitlib.ar_parse_command_util import BadCommandFormat, parse_command
14
14
  from arpakitlib.ar_type_util import raise_for_types
15
15
 
16
16
  _ARPAKIT_LIB_MODULE_VERSION = "3.0"
@@ -4,7 +4,7 @@ import sys
4
4
 
5
5
  from arpakitlib.ar_arpakit_project_template_util import init_arpakit_project_template
6
6
  from arpakitlib.ar_need_type_util import parse_need_type, NeedTypes
7
- from arpakitlib.ar_parse_command import parse_command
7
+ from arpakitlib.ar_parse_command_util import parse_command
8
8
 
9
9
  _ARPAKIT_LIB_MODULE_VERSION = "3.0"
10
10
 
@@ -26,7 +26,7 @@ class BaseWorker(ABC):
26
26
  startup_funcs: list[Any] | None = None,
27
27
  worker_name: str | None = None,
28
28
  data: dict[str, Any] | None = None,
29
- timeout_before_safe_run: timedelta | None= None,
29
+ timeout_before_safe_run: timedelta | None = None,
30
30
  **kwargs
31
31
  ):
32
32
  self.timeout_after_run = timeout_after_run
@@ -6,17 +6,17 @@ _ARPAKIT_LIB_MODULE_VERSION = "3.0"
6
6
 
7
7
  class BaseBlank:
8
8
  class Languages(Enumeration):
9
- rus = "ru" # Русский
10
- eng = "en" # Английский
11
- spa = "es" # Испанский
12
- deu = "de" # Немецкий
13
- fra = "fr" # Французский
14
- ita = "it" # Итальянский
15
- por = "pt" # Португальский
16
- jpn = "ja" # Японский
17
- kor = "ko" # Корейский
18
- zho = "zh" # Китайский
19
- ara = "ar" # Арабский
9
+ rus = "ru" # Русский
10
+ eng = "en" # Английский
11
+ spa = "es" # Испанский
12
+ deu = "de" # Немецкий
13
+ fra = "fr" # Французский
14
+ ita = "it" # Итальянский
15
+ por = "pt" # Португальский
16
+ jpn = "ja" # Японский
17
+ kor = "ko" # Корейский
18
+ zho = "zh" # Китайский
19
+ ara = "ar" # Арабский
20
20
 
21
21
  def __init__(self, *, lang: str = "ru", **kwargs):
22
22
  self.lang = lang.strip()
@@ -28,7 +28,7 @@ class BaseBlank:
28
28
 
29
29
  def hello_world(self) -> str:
30
30
  if self.compare_lang(self.Languages.rus):
31
- return "Привет, мир!" # Русский
31
+ return "Привет, мир!" # Русский
32
32
 
33
33
  if self.compare_lang(self.Languages.eng):
34
34
  return "Hello, world!" # Английский
@@ -37,29 +37,28 @@ class BaseBlank:
37
37
  return "¡Hola, mundo!" # Испанский
38
38
 
39
39
  if self.compare_lang(self.Languages.deu):
40
- return "Hallo, Welt!" # Немецкий
40
+ return "Hallo, Welt!" # Немецкий
41
41
 
42
42
  if self.compare_lang(self.Languages.fra):
43
43
  return "Bonjour, le monde!" # Французский
44
44
 
45
45
  if self.compare_lang(self.Languages.ita):
46
- return "Ciao, mondo!" # Итальянский
46
+ return "Ciao, mondo!" # Итальянский
47
47
 
48
48
  if self.compare_lang(self.Languages.por):
49
- return "Olá, mundo!" # Португальский
49
+ return "Olá, mundo!" # Португальский
50
50
 
51
51
  if self.compare_lang(self.Languages.jpn):
52
52
  return "こんにちは、世界!" # Японский
53
53
 
54
54
  if self.compare_lang(self.Languages.kor):
55
- return "안녕, 세상!" # Корейский
55
+ return "안녕, 세상!" # Корейский
56
56
 
57
57
  if self.compare_lang(self.Languages.zho):
58
- return "你好,世界!" # Китайский
58
+ return "你好,世界!" # Китайский
59
59
 
60
60
  if self.compare_lang(self.Languages.ara):
61
- return "مرحبا بالعالم!" # Арабский
61
+ return "مرحبا بالعالم!" # Арабский
62
62
 
63
63
  # если язык не найден
64
64
  return "Hello, world!"
65
-
@@ -27,12 +27,18 @@ def sync_make_http_request(
27
27
  max_tries_: int = 9,
28
28
  proxy_url_: str | None = None,
29
29
  raise_for_status_: bool = False,
30
- not_raise_for_statuses_: list[int] | None = None,
30
+ not_raise_for_statuses_: list[int] | set[int] | None = None,
31
31
  timeout_: timedelta | float = timedelta(seconds=15).total_seconds(),
32
32
  enable_logging_: bool = False,
33
33
  exception_class_: type[Exception] | None = None,
34
+ retry_delay_timeout: timedelta | int | None = timedelta(seconds=0.1),
34
35
  **kwargs
35
36
  ) -> requests.Response:
37
+ if isinstance(retry_delay_timeout, int):
38
+ retry_delay_timeout = timedelta(seconds=retry_delay_timeout)
39
+ if retry_delay_timeout is not None:
40
+ raise_for_type(retry_delay_timeout, timedelta)
41
+
36
42
  if isinstance(timeout_, float):
37
43
  timeout_ = timedelta(seconds=timeout_)
38
44
  raise_for_type(timeout_, timedelta)
@@ -69,7 +75,7 @@ def sync_make_http_request(
69
75
  else:
70
76
  try:
71
77
  response.raise_for_status()
72
- except requests.HTTPError as raise_for_status_exception:
78
+ except requests.HTTPError:
73
79
  if enable_logging_:
74
80
  try:
75
81
  json_data = response.json()
@@ -86,7 +92,7 @@ def sync_make_http_request(
86
92
  )
87
93
  except Exception:
88
94
  pass
89
- raise raise_for_status_exception
95
+ raise
90
96
  if enable_logging_:
91
97
  _logger.info(f"good try http {method} {url} {params}")
92
98
  return response
@@ -99,8 +105,9 @@ def sync_make_http_request(
99
105
  if exception_class_ is not None:
100
106
  raise exception_class_(exception)
101
107
  else:
102
- raise exception
103
- sync_safe_sleep(timedelta(seconds=0.1).total_seconds())
108
+ raise
109
+ if retry_delay_timeout is not None:
110
+ sync_safe_sleep(retry_delay_timeout.total_seconds())
104
111
  continue
105
112
 
106
113
 
@@ -113,12 +120,22 @@ async def async_make_http_request(
113
120
  max_tries_: int = 9,
114
121
  proxy_url_: str | None = None,
115
122
  raise_for_status_: bool = False,
116
- not_raise_for_statuses_: list[int] | None = None,
123
+ not_raise_for_statuses_: list[int] | set[int] | None = None,
117
124
  timeout_: timedelta | None = timedelta(seconds=15),
118
125
  enable_logging_: bool = False,
119
126
  exception_class_: type[Exception] | None = None,
127
+ retry_delay_timeout: timedelta | int | None = timedelta(seconds=0.1),
120
128
  **kwargs
121
129
  ) -> aiohttp.ClientResponse:
130
+ if isinstance(retry_delay_timeout, int):
131
+ retry_delay_timeout = timedelta(seconds=retry_delay_timeout)
132
+ if retry_delay_timeout is not None:
133
+ raise_for_type(retry_delay_timeout, timedelta)
134
+
135
+ if isinstance(timeout_, float):
136
+ timeout_ = timedelta(seconds=timeout_)
137
+ raise_for_type(timeout_, timedelta)
138
+
122
139
  tries_counter = 0
123
140
 
124
141
  kwargs["method"] = method
@@ -153,7 +170,7 @@ async def async_make_http_request(
153
170
  else:
154
171
  try:
155
172
  response.raise_for_status()
156
- except aiohttp.ClientResponseError as raise_for_status_exception:
173
+ except aiohttp.ClientResponseError:
157
174
  if enable_logging_:
158
175
  try:
159
176
  json_data = await response.json()
@@ -170,7 +187,7 @@ async def async_make_http_request(
170
187
  )
171
188
  except Exception:
172
189
  pass
173
- raise raise_for_status_exception
190
+ raise
174
191
  await response.read()
175
192
  if enable_logging_:
176
193
  _logger.info(f"good try {method} {url} {params}")
@@ -184,8 +201,9 @@ async def async_make_http_request(
184
201
  if exception_class_ is not None:
185
202
  raise exception_class_(exception)
186
203
  else:
187
- raise exception
188
- await async_safe_sleep(timedelta(seconds=0.1).total_seconds())
204
+ raise
205
+ if retry_delay_timeout is not None:
206
+ await async_safe_sleep(retry_delay_timeout.total_seconds())
189
207
  continue
190
208
 
191
209
 
@@ -1,5 +1,6 @@
1
1
  import importlib.util
2
2
  import os
3
+
3
4
  from fastapi import APIRouter
4
5
 
5
6
 
@@ -59,8 +59,8 @@ def remove_from_lists_if_left(
59
59
 
60
60
  def __example():
61
61
  a = remove_from_list_if_left(
62
- list_=[1,2,2,2,2,2,3,3,3,3,3,3],
63
- values=[1,2,3]
62
+ list_=[1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3],
63
+ values=[1, 2, 3]
64
64
  )
65
65
  print(a)
66
66
 
@@ -4,14 +4,22 @@ _ARPAKIT_LIB_MODULE_VERSION = "3.0"
4
4
 
5
5
  import logging
6
6
 
7
- _logger = logging.getLogger()
8
7
 
8
+ async def log_async_func_if_error(
9
+ async_func,
10
+ logger: logging.Logger | None = None,
11
+ logger_name: str | None = None,
12
+ **kwargs
13
+ ):
14
+ if logger is None:
15
+ logger = logging.getLogger()
16
+ if logger is None and logger_name is not None:
17
+ logger = logging.getLogger(logger_name)
9
18
 
10
- async def log_async_func_if_error(async_func, **kwargs):
11
19
  try:
12
20
  await async_func(**kwargs)
13
21
  except Exception as exception:
14
- _logger.error(
22
+ logger.error(
15
23
  f"error in async_func, {async_func.__name__=}",
16
24
  exc_info=exception,
17
25
  extra={
@@ -2,7 +2,6 @@
2
2
 
3
3
  import logging
4
4
  import os
5
- from typing import Optional
6
5
 
7
6
  _ARPAKIT_LIB_MODULE_VERSION = "3.0"
8
7
 
@@ -0,0 +1,204 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import logging
5
+
6
+ import httpx
7
+ from arpakitlib.ar_base64_util import convert_file_to_base64_string
8
+ from openai import OpenAI, AsyncOpenAI
9
+ from openai.types.chat import ChatCompletion
10
+
11
+ """
12
+ https://platform.openai.com/docs/
13
+ """
14
+
15
+
16
+ class EasyOpenAIAPIClient:
17
+ def __init__(
18
+ self,
19
+ *,
20
+ open_ai: OpenAI,
21
+ async_open_ai: AsyncOpenAI
22
+ ):
23
+ self._logger = logging.getLogger(self.__class__.__name__)
24
+
25
+ self.open_ai = open_ai
26
+ self.async_open_ai = async_open_ai
27
+
28
+ @classmethod
29
+ def create_easily(
30
+ cls,
31
+ openai_api_key: str,
32
+ openai_api_base_url: str | None = "https://api.proxyapi.ru/openai/v1"
33
+ ) -> EasyOpenAIAPIClient:
34
+ return EasyOpenAIAPIClient(
35
+ open_ai=OpenAI(
36
+ api_key=openai_api_key,
37
+ base_url=openai_api_base_url,
38
+ timeout=httpx.Timeout(
39
+ timeout=300, # общий таймаут
40
+ connect=5, # таймаут подключения
41
+ read=300, # чтение ответа
42
+ write=60, # запись запроса
43
+ pool=10
44
+ )
45
+ ),
46
+ async_open_ai=AsyncOpenAI(
47
+ api_key=openai_api_key,
48
+ base_url=openai_api_base_url,
49
+ http_client=httpx.AsyncClient(
50
+ timeout=httpx.Timeout(
51
+ timeout=300,
52
+ connect=5,
53
+ read=300,
54
+ write=60,
55
+ pool=10
56
+ )
57
+ )
58
+ )
59
+ )
60
+
61
+ def check_conn(self):
62
+ self.open_ai.models.list()
63
+
64
+ def is_conn_good(self) -> bool:
65
+ try:
66
+ self.check_conn()
67
+ return True
68
+ except Exception as e:
69
+ self._logger.error(e)
70
+ return False
71
+
72
+ async def async_check_conn(self):
73
+ await self.async_open_ai.models.list()
74
+
75
+ async def async_is_conn_good(self) -> bool:
76
+ try:
77
+ await self.async_check_conn()
78
+ return True
79
+ except Exception as e:
80
+ self._logger.error(e)
81
+ return False
82
+
83
+ def simple_ask(
84
+ self,
85
+ *,
86
+ prompt: str | None = None,
87
+ text: str,
88
+ model: str = "gpt-4o",
89
+ image_links: str | list[str] | None = None,
90
+ image_filepaths: str | list[str] | None = None
91
+ ) -> ChatCompletion:
92
+ if isinstance(image_links, str):
93
+ image_links = [image_links]
94
+ if isinstance(image_filepaths, str):
95
+ image_filepaths = [image_filepaths]
96
+
97
+ messages = []
98
+
99
+ if prompt is not None:
100
+ messages.append({
101
+ "role": "system",
102
+ "content": prompt
103
+ })
104
+
105
+ content = [{"type": "text", "text": text}]
106
+
107
+ if image_links:
108
+ for link in image_links:
109
+ content.append({
110
+ "type": "image_url",
111
+ "image_url": {"url": link}
112
+ })
113
+
114
+ if image_filepaths:
115
+ for path in image_filepaths:
116
+ base64_url = convert_file_to_base64_string(filepath=path, raise_for_error=True)
117
+ content.append({
118
+ "type": "image_url",
119
+ "image_url": {"url": base64_url}
120
+ })
121
+
122
+ messages.append({
123
+ "role": "user",
124
+ "content": content
125
+ })
126
+
127
+ response: ChatCompletion = self.open_ai.chat.completions.create(
128
+ model=model,
129
+ messages=messages,
130
+ n=1,
131
+ temperature=0.1,
132
+ top_p=0.9,
133
+ max_tokens=1000
134
+ )
135
+
136
+ return response
137
+
138
+ async def async_simple_ask(
139
+ self,
140
+ *,
141
+ prompt: str | None = None,
142
+ text: str,
143
+ model: str = "gpt-4o",
144
+ image_links: str | list[str] | None = None,
145
+ image_filepaths: str | list[str] | None = None
146
+ ) -> ChatCompletion:
147
+ if isinstance(image_links, str):
148
+ image_links = [image_links]
149
+ if isinstance(image_filepaths, str):
150
+ image_filepaths = [image_filepaths]
151
+
152
+ messages = []
153
+
154
+ if prompt is not None:
155
+ messages.append({
156
+ "role": "system",
157
+ "content": prompt
158
+ })
159
+
160
+ content = [{"type": "text", "text": text}]
161
+
162
+ if image_links:
163
+ for link in image_links:
164
+ content.append({
165
+ "type": "image_url",
166
+ "image_url": {"url": link}
167
+ })
168
+
169
+ if image_filepaths:
170
+ for path in image_filepaths:
171
+ base64_url = convert_file_to_base64_string(filepath=path, raise_for_error=True)
172
+ content.append({
173
+ "type": "image_url",
174
+ "image_url": {"url": base64_url}
175
+ })
176
+
177
+ messages.append({
178
+ "role": "user",
179
+ "content": content
180
+ })
181
+
182
+ response: ChatCompletion = await self.async_open_ai.chat.completions.create(
183
+ model=model,
184
+ messages=messages,
185
+ n=1,
186
+ temperature=0.1,
187
+ top_p=0.9,
188
+ max_tokens=1000
189
+ )
190
+
191
+ return response
192
+
193
+
194
+ def __example():
195
+ pass
196
+
197
+
198
+ async def __async_example():
199
+ pass
200
+
201
+
202
+ if __name__ == '__main__':
203
+ __example()
204
+ asyncio.run(__async_example())
@@ -12,6 +12,7 @@ RESULT_SPEC = TypeVar("RESULT_SPEC")
12
12
 
13
13
  _logger = logging.getLogger(__name__)
14
14
 
15
+
15
16
  def raise_own_exception_if_exception(
16
17
  *,
17
18
  catching_exceptions: type[BaseException] | Tuple[type[BaseException], ...] | None = Exception,
@@ -273,11 +273,11 @@ class SQLAlchemyDb:
273
273
  self._logger.info("alembic tables data were removed")
274
274
 
275
275
  def ensure_check_constraints(self):
276
- from arpakitlib.ar_sqlalchemy_ensure_check_constraints import ensure_sqlalchemy_check_constraints
276
+ from arpakitlib.ar_sqlalchemy_ensure_check_constraints_util import ensure_sqlalchemy_check_constraints
277
277
  ensure_sqlalchemy_check_constraints(base_=self.base_dbm, engine=self.engine)
278
278
 
279
279
  def drop_check_constraints(self):
280
- from arpakitlib.ar_sqlalchemy_drop_check_constraints import drop_sqlalchemy_check_constraints
280
+ from arpakitlib.ar_sqlalchemy_drop_check_constraints_util import drop_sqlalchemy_check_constraints
281
281
  drop_sqlalchemy_check_constraints(base_=self.base_dbm, engine=self.engine)
282
282
 
283
283
  def drop_and_ensure_check_constraints(self):
@@ -8,6 +8,7 @@ from typing import Any
8
8
 
9
9
  import aiohttp
10
10
  import requests
11
+
11
12
  from arpakitlib.ar_dict_util import combine_dicts
12
13
  from arpakitlib.ar_enumeration_util import Enumeration
13
14
  from arpakitlib.ar_http_request_util import sync_make_http_request, async_make_http_request
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arpakitlib
3
- Version: 1.8.326
3
+ Version: 1.8.328
4
4
  Summary: arpakitlib
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
@@ -101,7 +101,7 @@ arpakitlib/_arpakit_project_template_v_5/project/api/middleware/__init__.py,sha2
101
101
  arpakitlib/_arpakit_project_template_v_5/project/api/middleware/add_api_middlewares.py,sha256=TrWn0yPDCn0yTlHqLf19ypGtRumNjDxm0sM60yVsqXE,468
102
102
  arpakitlib/_arpakit_project_template_v_5/project/api/middleware/limit_content_length.py,sha256=cEtGcJSh3e2EyuQCFqKzRcrl3qS6oIvpSv5UEbYsvR4,1622
103
103
  arpakitlib/_arpakit_project_template_v_5/project/api/openapi_ui.py,sha256=7yg9ZNu6BjTAregnfbRFpwvqa-gTIY6o6NCz5pmsbeo,976
104
- arpakitlib/_arpakit_project_template_v_5/project/api/raise_own_exception_if_exception_in_api_router.py,sha256=7zssLmFEfZ5WvC-ZW1bPyn_HrYNPjvK_Q9Ln1-xH3O4,1413
104
+ arpakitlib/_arpakit_project_template_v_5/project/api/raise_own_exception_if_exception_in_api_router.py,sha256=7qZ0MYvTxDYpzhZNdn48SE-W_TCR92Me8ait1_hC0sU,1418
105
105
  arpakitlib/_arpakit_project_template_v_5/project/api/response.py,sha256=xZMymP2BuQaRNVWLeIp3UgUUo-MFN8MJnsn9Al4vOb8,1028
106
106
  arpakitlib/_arpakit_project_template_v_5/project/api/router/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
107
107
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -236,8 +236,8 @@ arpakitlib/_arpakit_project_template_v_5/project/resource/templates/simple_email
236
236
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
237
237
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_1.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
238
238
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_2.py,sha256=ASf9gG8xIhMIW6yH218C_NF4WITND9UgTJ07FlR4o5Y,258
239
- arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_3.py,sha256=CIv4vQfBLhlIh92fiLhmyTXSZXjDovxTFZtUBDnWyFY,427
240
- arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_4.py,sha256=Oalf7__usi-AkxjoeKQgrbdvaK7Mevh6i92u0Upoq50,460
239
+ arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_3.py,sha256=njXCVlpFAFEte17iUG3wENbtZhvyhjeArD7118CtFpc,432
240
+ arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_4.py,sha256=Kn58VaZK4YUM4eGqrdc9mWrdGdSjj0XpQhRYNjfTuIQ,465
241
241
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_5.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
242
242
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_6.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
243
243
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_7.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
@@ -375,16 +375,16 @@ arpakitlib/_arpakit_project_template_v_5/project/util/arpakitlib_project_templat
375
375
  arpakitlib/_arpakit_project_template_v_5/project/util/etc.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
376
376
  arpakitlib/_arpakit_project_template_v_5/project/util/send_email_.py,sha256=AZ2PHRQh-l7H3WLxgxygEKD8c_WPguIq4weP2zqfF9I,4748
377
377
  arpakitlib/_arpakit_project_template_v_5/todo.txt,sha256=q132Jbx229ThY77S3YiN-Cj5AVm7k1VlJcMYIbZUHUY,3
378
- arpakitlib/ar_aiogram_as_tg_command_util.py,sha256=4bizX5Xg-E2-r2TXXGQGanJozsIWPVf5luO3vKUN8p8,8471
378
+ arpakitlib/ar_aiogram_as_tg_command_util.py,sha256=BDOP3lvZOmaQZNGiYl3uHW05FpntFaZocUMJ0wdVK3s,8476
379
379
  arpakitlib/ar_arpakit_lib_module_util.py,sha256=g9uWwTK2eEzmErqwYeVgXDYVMREN8m5CdmgEumAEQfw,5919
380
380
  arpakitlib/ar_arpakit_project_template_util.py,sha256=5-o6eTmh-2DqsIqmo63SXw7ttExhmuAehMNc4s0GdtU,3278
381
- arpakitlib/ar_arpakitlib_cli_util.py,sha256=RJGcfEZ_q74FJ4tqdXvt7xQpShTszOvKu1mbp3D8qzw,2599
381
+ arpakitlib/ar_arpakitlib_cli_util.py,sha256=ZQmbMlvie7cnqKa6nzgsWKmLxsiVe72XUhQ7Pjb8_4A,2604
382
382
  arpakitlib/ar_base64_util.py,sha256=udSSpeXMZx0JgQknl4hQgZ8kr1Ps_aQOloIXu4T9dMQ,1286
383
- arpakitlib/ar_base_worker_util.py,sha256=4XN29vkju1OBmvZj1MVjxGXVWQzcs9Sdd90JBj1QoFg,6336
384
- arpakitlib/ar_blank_util.py,sha256=qFUdY8usL_pRYamz8Rw1fW3fzNIgrLmpdYP8q-_PQvw,2281
383
+ arpakitlib/ar_base_worker_util.py,sha256=bzRq4oZISyH01J2uoyCabXvAyaTc6bfsyeZOras9cxI,6337
384
+ arpakitlib/ar_blank_util.py,sha256=JT85-ZXsY-Qa8WwWKc0T3JniWojmBR574c9gIStagwA,2197
385
385
  arpakitlib/ar_cache_file_util.py,sha256=Fo2pH-Zqm966KWFBHG_pbiySGZvhIFCYqy7k1weRfJ0,3476
386
386
  arpakitlib/ar_class_util.py,sha256=i76pQW_7k_S2m_DlQh6xNjtggv9Col3WSx9W_bwk98E,722
387
- arpakitlib/ar_clone_pydantic_model_fields.py,sha256=5i77NGEjnY2ppk_Ot179egQGNDvg7zre8NBl5Es1nkg,1453
387
+ arpakitlib/ar_clone_pydantic_model_fields_util.py,sha256=5i77NGEjnY2ppk_Ot179egQGNDvg7zre8NBl5Es1nkg,1453
388
388
  arpakitlib/ar_datetime_util.py,sha256=3Pw8ljsBKkkEUCmu1PsnJqNeG5bVLqtpsUGaztJF8jQ,1432
389
389
  arpakitlib/ar_dict_util.py,sha256=oet-9AJEjQZfG_EI82BuYW0jdW2NQxKjPXol_nfTXjw,447
390
390
  arpakitlib/ar_encrypt_decrypt_util.py,sha256=GhWnp7HHkbhwFVVCzO1H07m-5gryr4yjWsXjOaNQm1Y,520
@@ -394,42 +394,43 @@ arpakitlib/ar_file_storage_in_dir_util.py,sha256=Zh922S6-aIy0p_Fen8GTTrGpixpPQ6c
394
394
  arpakitlib/ar_file_util.py,sha256=GUdJYm1tUZnYpY-SIPRHAZBHGra8NKy1eYEI0D5AfhY,489
395
395
  arpakitlib/ar_func_util.py,sha256=lG0bx_DtxWN4skbUim0liRZ6WUyLVV8Qfk6iZNtCZOs,1042
396
396
  arpakitlib/ar_generate_connection_url_util.py,sha256=sU55IA0v3TZ5PzJgc01Q9cABIzF9BrgSXu4USxOIlVY,2665
397
- arpakitlib/ar_generate_simple_code.py,sha256=EkrebrTi7sArSRAuxvN5BPm_A0-dFSCZgdoJhx5kPhk,344
397
+ arpakitlib/ar_generate_simple_code_util.py,sha256=EkrebrTi7sArSRAuxvN5BPm_A0-dFSCZgdoJhx5kPhk,344
398
398
  arpakitlib/ar_hash_util.py,sha256=Iqy6KBAOLBQMFLWv676boI5sV7atT2B-fb7aCdHOmIQ,340
399
- arpakitlib/ar_http_request_util.py,sha256=PCUtGOQIvNScrLqD_9Z8LqT-7a-lP2y-Y-CH5vGdn7Q,7663
400
- arpakitlib/ar_include_fastapi_routers_from_dir_util.py,sha256=Umg16sPQC6R-T8FD7mlmqP1TbgH-_v2eDasrZJzImQM,1606
399
+ arpakitlib/ar_http_request_util.py,sha256=QoNQKiHHoH-cjdWCGzAmzLioxbHpFvta4c4PSF_BVzo,8349
400
+ arpakitlib/ar_include_fastapi_routers_from_dir_util.py,sha256=q-z3HTOqt671q-yFLwwg_WqnnpHPtMQbRYTGtN0P84k,1607
401
401
  arpakitlib/ar_ip_util.py,sha256=aEAa1Hvobh9DWX7cmBAPLqnXSTiKe2hRk-WJaiKMaI8,1009
402
402
  arpakitlib/ar_json_db_util.py,sha256=5nELpAY1_5_iTN4nMcutQtJQ5Nt52-xiKELxEH65RkY,7240
403
403
  arpakitlib/ar_json_util.py,sha256=jnVfpQ6QSDq8NgIlh_6ZzXDveOiybr7QSQkXutE7d2s,2676
404
404
  arpakitlib/ar_jwt_util.py,sha256=Rhm4ywoTAn6yOV8NLjDASfAtAtheROxxDP40G3XjnuQ,761
405
- arpakitlib/ar_list_of_dicts_to_xlsx.py,sha256=MyjEl4Jl4beLVZqLVQMMv0-XDtBD3Xh4Z_ZPDJeFu04,745
406
- arpakitlib/ar_list_util.py,sha256=xaUk2BnLvDMP5HDh_GFfH-nIXCg-f8NsrrUKXRcVUsU,1788
407
- arpakitlib/ar_log_async_func_if_error.py,sha256=qtr_eK9o1BrcA_7S9Ns7nVmOS81Yv6eMXHdasc4MftQ,495
408
- arpakitlib/ar_logging_util.py,sha256=Q9R4-Cx3TAn3VLcKyNFeKS3luYBouj-umR6_TSKmVYw,1336
405
+ arpakitlib/ar_list_of_dicts_to_xlsx_util.py,sha256=MyjEl4Jl4beLVZqLVQMMv0-XDtBD3Xh4Z_ZPDJeFu04,745
406
+ arpakitlib/ar_list_util.py,sha256=kPI8wiWgRkj6z0-YQG822pawN8zx_QrSmGj8tOMq6vc,1801
407
+ arpakitlib/ar_log_async_func_if_error_util.py,sha256=8qtcxRk6OqfwVsGE2wCpuIY7fjuQSQPl2eci4jZZ12I,727
408
+ arpakitlib/ar_logging_util.py,sha256=8TdaCWeSk4_GAmuWFO49l8JAVfLJCqUxgSpTYvlWvsk,1308
409
409
  arpakitlib/ar_mongodb_util.py,sha256=orRb81o9CzD9kkWbbNQCbSMTl2xLcctUDdx_FxirKww,3411
410
410
  arpakitlib/ar_need_type_util.py,sha256=XmY1kswz8j9oo5f9CxRu0_zgfvxWrXPYKOj6MM04sGk,2604
411
- arpakitlib/ar_parse_command.py,sha256=1WTdQoWVshoDZ1jDaKeTzajfqaYHP3FNO0-REyo1aMY,3003
411
+ arpakitlib/ar_openai_api_client_util.py,sha256=dIPHNrDRkclRa__qPj7glkv232C97tzAAFEFuXtvV1E,5569
412
+ arpakitlib/ar_parse_command_util.py,sha256=1WTdQoWVshoDZ1jDaKeTzajfqaYHP3FNO0-REyo1aMY,3003
412
413
  arpakitlib/ar_postgresql_util.py,sha256=1AuLjEaa1Lg4pzn-ukCVnDi35Eg1k91APRTqZhIJAdo,945
413
- arpakitlib/ar_pydantic_schema_from_sqlalchemy_model.py,sha256=SddmsEdRdVbmdZ5aSuwy6DfGYmYx_JO6lKzuEJeBAV8,10553
414
- arpakitlib/ar_raise_own_exception_if_exception.py,sha256=A6TuNSBk1pHaQ_qxnUmE2LgsNGA1IGqX26b1_HEA4Nc,5978
414
+ arpakitlib/ar_pydantic_schema_from_sqlalchemy_model_util.py,sha256=SddmsEdRdVbmdZ5aSuwy6DfGYmYx_JO6lKzuEJeBAV8,10553
415
+ arpakitlib/ar_raise_own_exception_if_exception_util.py,sha256=bZMEprKXzs9k5ERpG7fHhi7S22uDiphiJLVtAg98lN0,5979
415
416
  arpakitlib/ar_rat_func_util.py,sha256=Ca10o3RJwyx_DJLxjTxgHDO6NU3M6CWgUR4bif67OE4,2006
416
- arpakitlib/ar_really_validate_email.py,sha256=HBfhyiDB3INI6Iq6hR2WOMKA5wVWWRl0Qun-x__OZ9o,1201
417
- arpakitlib/ar_really_validate_url.py,sha256=aaSPVMbz2DSqlC2yk2g44-kTIiHlITfJwIG97L-Y93U,1309
417
+ arpakitlib/ar_really_validate_email_util.py,sha256=HBfhyiDB3INI6Iq6hR2WOMKA5wVWWRl0Qun-x__OZ9o,1201
418
+ arpakitlib/ar_really_validate_url_util.py,sha256=aaSPVMbz2DSqlC2yk2g44-kTIiHlITfJwIG97L-Y93U,1309
418
419
  arpakitlib/ar_retry_func_util.py,sha256=LB4FJRsu2cssnPw6X8bCEcaGpQsXhkLkgeU37w1t9fU,2250
419
420
  arpakitlib/ar_run_cmd_util.py,sha256=D_rPavKMmWkQtwvZFz-Io5Ak8eSODHkcFeLPzNVC68g,1072
420
421
  arpakitlib/ar_safe_func.py,sha256=JQNaM3q4Z6nUE8bDfzXNBGkWSXm0PZ-GMMvu6UWUIYk,2400
421
422
  arpakitlib/ar_settings_util.py,sha256=FeQQkuVrLVYkFAIg3Wy6ysyTt_sqLTX0REAe60gbM3k,2361
422
423
  arpakitlib/ar_sleep_util.py,sha256=ggaj7ML6QK_ADsHMcyu6GUmUpQ_9B9n-SKYH17h-9lM,1045
423
424
  arpakitlib/ar_sqladmin_util.py,sha256=SEoaowAPF3lhxPsNjwmOymNJ55Ty9rmzvsDm7gD5Ceo,861
424
- arpakitlib/ar_sqlalchemy_drop_check_constraints.py,sha256=uVktYLjNHrMPWQAq8eBpapShPKbLb3LrRBnnss3gaYY,3624
425
- arpakitlib/ar_sqlalchemy_ensure_check_constraints.py,sha256=gqZTPSCAPUMRiXcmv9xls5S8YkUAg-gwFIEvqQsJ_JM,5437
426
- arpakitlib/ar_sqlalchemy_util.py,sha256=8sHbUS9BgM13iTFrqxLuCpGYmLXPQMx4aqQb-aY8HrM,16040
425
+ arpakitlib/ar_sqlalchemy_drop_check_constraints_util.py,sha256=uVktYLjNHrMPWQAq8eBpapShPKbLb3LrRBnnss3gaYY,3624
426
+ arpakitlib/ar_sqlalchemy_ensure_check_constraints_util.py,sha256=gqZTPSCAPUMRiXcmv9xls5S8YkUAg-gwFIEvqQsJ_JM,5437
427
+ arpakitlib/ar_sqlalchemy_util.py,sha256=hnwZW7v8FOjzYCkaoumkZYrtDkAv2gev9ZWH6it8H5k,16050
427
428
  arpakitlib/ar_str_util.py,sha256=6KlLL-SB8gzK-6gwQEd3zuYbRvtjd9HFpJ9-xHbkH6U,4355
428
429
  arpakitlib/ar_type_util.py,sha256=Cs_tef-Fc5xeyAF54KgISCsP11NHyzIsglm4S3Xx7iM,4049
429
- arpakitlib/ar_uppercase_env_keys.py,sha256=BsUCJhfchBIav0AE54_tVgYcE4p1JYoWdPGCHWZnROA,2790
430
- arpakitlib/ar_yookassa_api_client_util.py,sha256=Mst07IblAJmU98HfOfJqT_RRfnuGrIB1UOQunGGWO8I,5264
431
- arpakitlib-1.8.326.dist-info/METADATA,sha256=G_G4IUXDYld3qHeF8I_e7jqFm6ICAp-Hr7ZunkHA8Cw,3804
432
- arpakitlib-1.8.326.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
433
- arpakitlib-1.8.326.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
434
- arpakitlib-1.8.326.dist-info/licenses/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
435
- arpakitlib-1.8.326.dist-info/RECORD,,
430
+ arpakitlib/ar_uppercase_env_keys_util.py,sha256=BsUCJhfchBIav0AE54_tVgYcE4p1JYoWdPGCHWZnROA,2790
431
+ arpakitlib/ar_yookassa_api_client_util.py,sha256=7DL_0GyIOTuSNBHUO3qWxAXMKlBRHjKgcA6ttst8k1A,5265
432
+ arpakitlib-1.8.328.dist-info/METADATA,sha256=89Z-J3Lhic6uYoQgkP8PN0m5uTDxjwlUMK6Y6UaL24A,3804
433
+ arpakitlib-1.8.328.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
434
+ arpakitlib-1.8.328.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
435
+ arpakitlib-1.8.328.dist-info/licenses/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
436
+ arpakitlib-1.8.328.dist-info/RECORD,,