arpakitlib 1.8.111__py3-none-any.whl → 1.8.112__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 (21) hide show
  1. arpakitlib/_arpakit_project_template_v_5/arpakitlib_project_template_info.json +1 -1
  2. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_operation.py +1 -5
  3. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_story_log.py +1 -5
  4. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_user.py +0 -5
  5. arpakitlib/_arpakit_project_template_v_5/project/core/easy_openai_api_client.py +2 -2
  6. arpakitlib/_arpakit_project_template_v_5/project/core/settings.py +12 -0
  7. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/api_key.py +1 -0
  8. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/story_log.py +0 -1
  9. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user.py +1 -2
  10. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user_token.py +1 -2
  11. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/verification_code.py +10 -1
  12. arpakitlib/_arpakit_project_template_v_5/project/test_data/make_test_data_1.py +18 -2
  13. arpakitlib/_arpakit_project_template_v_5/project/tg_bot_notifier/__init__.py +0 -0
  14. arpakitlib/_arpakit_project_template_v_5/project/tg_bot_notifier/blank.py +20 -0
  15. arpakitlib/_arpakit_project_template_v_5/project/tg_bot_notifier/tg_bot_notifier.py +24 -0
  16. arpakitlib/_arpakit_project_template_v_5/project/util/send_email.py +81 -0
  17. {arpakitlib-1.8.111.dist-info → arpakitlib-1.8.112.dist-info}/METADATA +1 -1
  18. {arpakitlib-1.8.111.dist-info → arpakitlib-1.8.112.dist-info}/RECORD +21 -17
  19. {arpakitlib-1.8.111.dist-info → arpakitlib-1.8.112.dist-info}/LICENSE +0 -0
  20. {arpakitlib-1.8.111.dist-info → arpakitlib-1.8.112.dist-info}/WHEEL +0 -0
  21. {arpakitlib-1.8.111.dist-info → arpakitlib-1.8.112.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "arpakitlib_project_template_version": "5",
3
- "arpakitlib_project_template_subversion": "26"
3
+ "arpakitlib_project_template_subversion": "27"
4
4
  }
@@ -34,12 +34,10 @@ async def _(
34
34
  ])),
35
35
  filter_id: int | None = fastapi.Query(default=None),
36
36
  filter_long_id: str | None = fastapi.Query(default=None),
37
- filter_slug: str | None = fastapi.Query(default=None),
38
37
  ):
39
38
  filter_long_id = make_none_if_blank(strip_if_not_none(filter_long_id))
40
- filter_slug = make_none_if_blank(strip_if_not_none(filter_slug))
41
39
 
42
- if filter_id is None and filter_long_id is None and filter_slug is None:
40
+ if filter_id is None and filter_long_id is None:
43
41
  return None
44
42
 
45
43
  query = sqlalchemy.select(OperationDBM)
@@ -47,8 +45,6 @@ async def _(
47
45
  query = query.filter(OperationDBM.id == filter_id)
48
46
  if filter_long_id is not None:
49
47
  query = query.filter(OperationDBM.long_id == filter_long_id)
50
- if filter_slug is not None:
51
- query = query.filter(OperationDBM.slug == filter_slug)
52
48
 
53
49
  async with get_cached_sqlalchemy_db().new_async_session() as async_session:
54
50
  result = await async_session.scalar(query)
@@ -34,12 +34,10 @@ async def _(
34
34
  ])),
35
35
  filter_id: int | None = fastapi.Query(default=None),
36
36
  filter_long_id: str | None = fastapi.Query(default=None),
37
- filter_slug: str | None = fastapi.Query(default=None),
38
37
  ):
39
38
  filter_long_id = make_none_if_blank(strip_if_not_none(filter_long_id))
40
- filter_slug = make_none_if_blank(strip_if_not_none(filter_slug))
41
39
 
42
- if filter_id is None and filter_long_id is None and filter_slug is None:
40
+ if filter_id is None and filter_long_id is None:
43
41
  return None
44
42
 
45
43
  query = sqlalchemy.select(StoryLogDBM)
@@ -47,8 +45,6 @@ async def _(
47
45
  query = query.filter(StoryLogDBM.id == filter_id)
48
46
  if filter_long_id is not None:
49
47
  query = query.filter(StoryLogDBM.long_id == filter_long_id)
50
- if filter_slug is not None:
51
- query = query.filter(StoryLogDBM.slug == filter_slug)
52
48
 
53
49
  async with get_cached_sqlalchemy_db().new_async_session() as async_session:
54
50
  result = await async_session.scalar(query)
@@ -34,20 +34,17 @@ async def _(
34
34
  ])),
35
35
  filter_id: int | None = fastapi.Query(default=None),
36
36
  filter_long_id: str | None = fastapi.Query(default=None),
37
- filter_slug: str | None = fastapi.Query(default=None),
38
37
  filter_email: str | None = fastapi.Query(default=None),
39
38
  filter_username: str | None = fastapi.Query(default=None),
40
39
  filter_tg_id: int | None = fastapi.Query(default=None),
41
40
  ):
42
41
  filter_long_id = make_none_if_blank(strip_if_not_none(filter_long_id))
43
- filter_slug = make_none_if_blank(strip_if_not_none(filter_slug))
44
42
  filter_email = make_none_if_blank(strip_if_not_none(filter_email))
45
43
  filter_username = make_none_if_blank(strip_if_not_none(filter_username))
46
44
 
47
45
  if (
48
46
  filter_id is None
49
47
  and filter_long_id is None
50
- and filter_slug is None
51
48
  and filter_email is None
52
49
  and filter_username is None
53
50
  and filter_tg_id is None
@@ -59,8 +56,6 @@ async def _(
59
56
  query = query.filter(UserDBM.id == filter_id)
60
57
  if filter_long_id is not None:
61
58
  query = query.filter(UserDBM.long_id == filter_long_id)
62
- if filter_slug is not None:
63
- query = query.filter(UserDBM.slug == filter_slug)
64
59
  if filter_email is not None:
65
60
  query = query.filter(UserDBM.email == filter_email)
66
61
  if filter_username is not None:
@@ -2,10 +2,10 @@ import asyncio
2
2
  from functools import lru_cache
3
3
 
4
4
  import httpx
5
- from arpakitlib.ar_logging_util import setup_normal_logging
6
- from arpakitlib.ar_openai_api_client_util import EasyOpenAIAPIClient
7
5
  from openai import OpenAI, AsyncOpenAI
8
6
 
7
+ from arpakitlib.ar_logging_util import setup_normal_logging
8
+ from arpakitlib.ar_openai_api_client_util import EasyOpenAIAPIClient
9
9
  from project.core.settings import get_cached_settings
10
10
 
11
11
 
@@ -168,6 +168,14 @@ class Settings(SimpleSettings):
168
168
 
169
169
  local_timezone: str | None = None
170
170
 
171
+ email_smtp_user: str | None = None
172
+
173
+ email_smtp_password: str | None = None
174
+
175
+ email_smtp_port: int | None = 465
176
+
177
+ email_smtp_hostname: str | None = "smtp.yandex.ru"
178
+
171
179
  @property
172
180
  def local_timezone_as_pytz(self) -> Any:
173
181
  raise_for_type(self.local_timezone, str)
@@ -177,6 +185,10 @@ class Settings(SimpleSettings):
177
185
 
178
186
  openai_api_base_url: str | None = "https://api.proxyapi.ru/openai/v1"
179
187
 
188
+ tg_bot_notifier_token: str | None = None
189
+
190
+ tg_bot_notifier_proxy_url: str | None = None
191
+
180
192
 
181
193
  @lru_cache()
182
194
  def get_cached_settings() -> Settings:
@@ -41,6 +41,7 @@ class ApiKeyMV(SimpleMV, model=ApiKeyDBM):
41
41
  ]
42
42
  column_searchable_list = [
43
43
  ApiKeyDBM.id,
44
+ ApiKeyDBM.long_id,
44
45
  ApiKeyDBM.value,
45
46
  ]
46
47
  column_formatters = {
@@ -33,7 +33,6 @@ class StoryLogMV(SimpleMV, model=StoryLogDBM):
33
33
  column_searchable_list = [
34
34
  StoryLogDBM.id,
35
35
  StoryLogDBM.long_id,
36
- StoryLogDBM.slug,
37
36
  ]
38
37
  column_formatters = {
39
38
  StoryLogDBM.creation_dt: lambda m, _: format_datetime_(m.creation_dt),
@@ -43,7 +43,7 @@ class UserMV(SimpleMV, model=UserDBM):
43
43
  form_args = {
44
44
  UserDBM.roles.key: {
45
45
  "choices": [(role, role) for role in UserDBM.Roles.values_list()],
46
- "description": "Choose user roles"
46
+ "description": "Choose roles"
47
47
  }
48
48
  }
49
49
  column_sortable_list = sqlalchemy.inspect(UserDBM).columns
@@ -55,7 +55,6 @@ class UserMV(SimpleMV, model=UserDBM):
55
55
  UserDBM.long_id,
56
56
  UserDBM.email,
57
57
  UserDBM.username,
58
- UserDBM.password,
59
58
  UserDBM.tg_id
60
59
  ]
61
60
  column_formatters = {
@@ -34,7 +34,6 @@ class UserTokenMV(SimpleMV, model=UserTokenDBM):
34
34
  column_searchable_list = [
35
35
  UserTokenDBM.id,
36
36
  UserTokenDBM.long_id,
37
- UserTokenDBM.slug,
38
37
  UserTokenDBM.value,
39
38
  ]
40
39
  column_formatters = {
@@ -47,7 +46,7 @@ class UserTokenMV(SimpleMV, model=UserTokenDBM):
47
46
  }
48
47
  form_ajax_refs = {
49
48
  UserTokenDBM.user.key: {
50
- "fields": [UserDBM.id.key, UserDBM.email.key],
49
+ "fields": [UserDBM.id.key, UserDBM.email.key, UserDBM.username.key],
51
50
  "placeholder": "Search by id or email",
52
51
  "minimum_input_length": 1,
53
52
  "page_size": 10,
@@ -5,7 +5,7 @@ from sqladmin.fields import SelectField
5
5
 
6
6
  from project.sqladmin_.model_view import SimpleMV
7
7
  from project.sqladmin_.util.etc import format_datetime_, format_json_for_preview_, format_json_
8
- from project.sqlalchemy_db_.sqlalchemy_model import VerificationCodeDBM
8
+ from project.sqlalchemy_db_.sqlalchemy_model import VerificationCodeDBM, UserDBM
9
9
 
10
10
 
11
11
  class VerificationCodeMV(SimpleMV, model=VerificationCodeDBM):
@@ -48,6 +48,7 @@ class VerificationCodeMV(SimpleMV, model=VerificationCodeDBM):
48
48
  ]
49
49
  column_searchable_list = [
50
50
  VerificationCodeDBM.id,
51
+ VerificationCodeDBM.long_id,
51
52
  VerificationCodeDBM.value,
52
53
  VerificationCodeDBM.recipient
53
54
  ]
@@ -59,3 +60,11 @@ class VerificationCodeMV(SimpleMV, model=VerificationCodeDBM):
59
60
  VerificationCodeDBM.creation_dt: lambda m, _: format_datetime_(m.creation_dt),
60
61
  VerificationCodeDBM.extra_data: lambda m, a: format_json_(m.extra_data),
61
62
  }
63
+ form_ajax_refs = {
64
+ VerificationCodeDBM.user.key: {
65
+ "fields": [UserDBM.id.key, UserDBM.email.key, UserDBM.username.key],
66
+ "placeholder": "Search by id or email",
67
+ "minimum_input_length": 1,
68
+ "page_size": 10,
69
+ }
70
+ }
@@ -1,6 +1,7 @@
1
1
  import asyncio
2
2
  import logging
3
3
 
4
+ from arpakitlib.ar_datetime_util import now_utc_dt
4
5
  from project.core.settings import get_cached_settings
5
6
  from project.core.util import setup_logging
6
7
  from project.sqlalchemy_db_.sqlalchemy_db import get_cached_sqlalchemy_db
@@ -31,13 +32,28 @@ def make_test_data_1():
31
32
  is_active=True,
32
33
  is_verified=True,
33
34
  password="123",
34
- tg_id=269870432
35
+ tg_id=269870432,
36
+ tg_bot_last_action_dt=now_utc_dt(),
37
+ tg_data={
38
+ "id": 269870432,
39
+ "is_bot": False,
40
+ "first_name": "Арсен",
41
+ "last_name": "Arsen",
42
+ "username": "arpakit",
43
+ "language_code": "en",
44
+ "is_premium": True,
45
+ "added_to_attachment_menu": None,
46
+ "can_join_groups": None,
47
+ "can_read_all_group_messages": None,
48
+ "supports_inline_queries": None,
49
+ "can_connect_to_business": None
50
+ }
35
51
  )
36
52
  session.add(arpakit_user)
37
53
  session.commit()
38
54
  _logger.info(arpakit_user)
39
55
 
40
- for i in range(1000):
56
+ for i in range(100):
41
57
  user_token_dbm = UserTokenDBM(user_id=arpakit_user.id, value=str(i))
42
58
  session.add(user_token_dbm)
43
59
  _logger.info(user_token_dbm)
@@ -0,0 +1,20 @@
1
+ from functools import lru_cache
2
+
3
+ from arpakitlib.ar_blank_util import BaseBlank
4
+
5
+
6
+ class TgBotNotifierBlank(BaseBlank):
7
+ pass
8
+
9
+
10
+ @lru_cache()
11
+ def get_cached_rus_tg_bot_notifier_blank() -> TgBotNotifierBlank:
12
+ return TgBotNotifierBlank(lang=TgBotNotifierBlank.Languages.rus)
13
+
14
+
15
+ def __example():
16
+ print(get_cached_rus_tg_bot_notifier_blank().hello_world())
17
+
18
+
19
+ if __name__ == '__main__':
20
+ __example()
@@ -0,0 +1,24 @@
1
+ import aiogram
2
+ from aiogram.client.default import DefaultBotProperties
3
+ from aiogram.client.session.aiohttp import AiohttpSession
4
+ from aiogram.enums import ParseMode
5
+
6
+ from project.core.settings import get_cached_settings
7
+
8
+
9
+ def create_tg_bot_notifier() -> aiogram.Bot | None:
10
+ if get_cached_settings().tg_bot_notifier_token is None:
11
+ return None
12
+ session: AiohttpSession | None = None
13
+ if get_cached_settings().tg_bot_notifier_proxy_url:
14
+ session = AiohttpSession(proxy=get_cached_settings().tg_bot_notifier_proxy_url)
15
+ tg_bot = aiogram.Bot(
16
+ token=get_cached_settings().tg_bot_notifier_token,
17
+ default=DefaultBotProperties(
18
+ parse_mode=ParseMode.HTML,
19
+ disable_notification=False,
20
+ link_preview_is_disabled=True
21
+ ),
22
+ session=session
23
+ )
24
+ return tg_bot
@@ -0,0 +1,81 @@
1
+ import asyncio
2
+ import logging
3
+ import smtplib
4
+ from email.message import EmailMessage
5
+
6
+ import aiosmtplib
7
+
8
+ from project.core.settings import get_cached_settings
9
+ from project.core.util import setup_logging
10
+
11
+ _logger = logging.getLogger(__name__)
12
+
13
+
14
+ def send_email(
15
+ *, to_email: str, subject: str = "Hello world", html_content: str,
16
+ emulate: bool = False
17
+ ):
18
+ to_email = to_email.strip()
19
+
20
+ if emulate:
21
+ _logger.info(f"emulate email sending, {to_email=}, {subject=}, {html_content=}")
22
+ return
23
+
24
+ message = EmailMessage()
25
+ message["From"] = get_cached_settings().email_smtp_user
26
+ message["To"] = to_email
27
+ message["Subject"] = subject
28
+ message.add_alternative(html_content, subtype="html")
29
+
30
+ with smtplib.SMTP_SSL(
31
+ get_cached_settings().email_smtp_hostname,
32
+ get_cached_settings().email_smtp_port
33
+ ) as server:
34
+ server.login(
35
+ get_cached_settings().email_smtp_user,
36
+ get_cached_settings().email_smtp_password
37
+ )
38
+ server.send_message(message)
39
+
40
+ _logger.info(f"email was send, {to_email=}")
41
+
42
+
43
+ async def async_send_email(
44
+ *,
45
+ to_email: str, subject: str = "Hello world", html_content: str,
46
+ emulate: bool = False
47
+ ):
48
+ to_email = to_email.strip()
49
+
50
+ if emulate:
51
+ _logger.info(f"emulate email sending, {to_email=}, {subject=}, {html_content=}")
52
+ return
53
+
54
+ message = EmailMessage()
55
+ message["From"] = get_cached_settings().email_smtp_user
56
+ message["To"] = to_email
57
+ message["Subject"] = subject
58
+ message.add_alternative(html_content, subtype="html")
59
+
60
+ await aiosmtplib.send(
61
+ message,
62
+ hostname=get_cached_settings().email_smtp_hostname,
63
+ port=get_cached_settings().email_smtp_port,
64
+ username=get_cached_settings().email_smtp_user,
65
+ password=get_cached_settings().email_smtp_password,
66
+ use_tls=True
67
+ )
68
+
69
+ _logger.info(f"email was send, {to_email=}")
70
+
71
+
72
+ async def __async_example():
73
+ setup_logging()
74
+ send_email(
75
+ to_email="arpakit@gmail.com",
76
+ html_content="Hello world 2"
77
+ )
78
+
79
+
80
+ if __name__ == '__main__':
81
+ asyncio.run(__async_example())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: arpakitlib
3
- Version: 1.8.111
3
+ Version: 1.8.112
4
4
  Summary: arpakitlib
5
5
  License: Apache-2.0
6
6
  Keywords: arpakitlib,arpakit,arpakit-company,arpakitcompany,arpakit_company
@@ -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=o3UxTcbS0YBkewD0pMMAWC8bJGs-V6tzvpFhgw0useE,98
11
+ arpakitlib/_arpakit_project_template_v_5/arpakitlib_project_template_info.json,sha256=R-BkDM1StRfEarU7UEwPZaxaGv7vHvTAGteM3_evSUQ,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
@@ -102,13 +102,13 @@ arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/create_operati
102
102
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_arpakitlib_project_template_info.py,sha256=c4HAHSivR8viAlHVyTut4VaKNkYsYiabE833FsUl9Yk,1265
103
103
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_auth_data.py,sha256=Hpjkucwnb2LtytWpMMA2WMROY2cTLn0q_tnUFijk0so,1195
104
104
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_log_file.py,sha256=rzEPco45I-4FzrlbI3z5B-smhrHFIVIsDiHtTULoE4g,1162
105
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_operation.py,sha256=uo3QK4Rw8V0YjMbCeymC6JZF2-qkMay3ofZlxBC3-S0,2291
105
+ arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_operation.py,sha256=cOG0c2s6grwvlN4xxXNyRVY28yI9u1xOryRt0fNHcko,2040
106
106
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_operation_allowed_statuses.py,sha256=eN-1XHeeSkgSTmYLldV-8uAY8qEmdUVCfvY2A5IHtw0,1096
107
107
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_operation_allowed_types.py,sha256=R5d3lZCHQNadPzG77WbJbLFQwTwPFU3l7BLYUlIOA6c,1090
108
108
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_settings.py,sha256=UhTWDrBkZHqkbqanDMr6Q4vZibDBeCIrVNzAInzjR8o,1157
109
109
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_sqlalchemy_db_table_name_to_amount.py,sha256=H6D9gEhbSKEwKeYj2HAyk948-sPvhxRark_Iqq67Jzk,1201
110
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_story_log.py,sha256=XEVouJSYgEIa0y6ujwfv26tAd6M-tMixOQZCxFUnHec,2283
111
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_user.py,sha256=ChsorTfFI03PzJfvcKU4mSHMTXuIrphXgoZBft6nMy4,3021
110
+ arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_story_log.py,sha256=sK0FvNzoG-pE5rD2Q62t6yK5Bx1Y2JZA_04sOk14loQ,2033
111
+ arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_user.py,sha256=lBTR7eyjVbf0I8yG1yTovlrz2H4h-6O3wggQLsMPdsw,2763
112
112
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/init_sqlalchemy_db.py,sha256=HUDaDeyb5ldpiEaA2mJIsAuGF6H-XupGvKfxjrkxMTE,1333
113
113
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/main_router.py,sha256=pu5-H9JlXhsVrY4a2ajbgeTbPo9ijIGSiq7J1Q77QT0,2479
114
114
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/make_test_data_1.py,sha256=tITqtXW2C7od04_ECQudR_5kupVoKrYVnUVU2YcZp-g,1178
@@ -168,10 +168,10 @@ arpakitlib/_arpakit_project_template_v_5/project/core/__init__.py,sha256=47DEQpj
168
168
  arpakitlib/_arpakit_project_template_v_5/project/core/cache_file_storage_in_dir.py,sha256=0lKPKvrs30DlAZwNS5ydPsQ9ETFLBjZqEcNv8LoQVCU,623
169
169
  arpakitlib/_arpakit_project_template_v_5/project/core/const.py,sha256=hgiiPIYL9543-eEnNAhZWYgX7ZzLKjOqRD0skkROSOw,951
170
170
  arpakitlib/_arpakit_project_template_v_5/project/core/dump_file_storage_in_dir.py,sha256=u3-vStMGaseMsRLuJmQK04UDhaez9vw6o5jyHb1fwNg,617
171
- arpakitlib/_arpakit_project_template_v_5/project/core/easy_openai_api_client.py,sha256=NAwu0e7m4m2OVcZC0KBbgjiNxKmpIUofBzwTRbC1GBQ,1219
171
+ arpakitlib/_arpakit_project_template_v_5/project/core/easy_openai_api_client.py,sha256=G4J9s0gerNlnvl1LvaWSYy1gdvaMbxyz0ZP35U9nx_Q,1219
172
172
  arpakitlib/_arpakit_project_template_v_5/project/core/jinja2_templates.py,sha256=jCNLaBauGC7YNvZdTLNHuPp7hmRGt94O23Skg6ewo7o,352
173
173
  arpakitlib/_arpakit_project_template_v_5/project/core/media_file_storage_in_dir.py,sha256=fMofTsfJtA8pp5lEUhucEUu3PBsmj-elaRZzExDsdLI,623
174
- arpakitlib/_arpakit_project_template_v_5/project/core/settings.py,sha256=NlbGFZCR98hytoigP4E5TjazIUJt8NPSI0NZOmQ365A,5995
174
+ arpakitlib/_arpakit_project_template_v_5/project/core/settings.py,sha256=BO6AgjZcK2pwClQFjabtuBObY0bvQ6NWbrrqvT2Kc_c,6270
175
175
  arpakitlib/_arpakit_project_template_v_5/project/core/util.py,sha256=1ha9UrguVPsTSjoMHhVZVCD0_mNBfhIDGEvcG1nA4Zw,667
176
176
  arpakitlib/_arpakit_project_template_v_5/project/json_db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
177
177
  arpakitlib/_arpakit_project_template_v_5/project/json_db/json_db.py,sha256=tBML-z4Y7uY8f_0ggcxvlDNt15Sf93Jr_OUeHwWxqOA,724
@@ -232,13 +232,13 @@ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/asgi.py,sha256=DRlRPk
232
232
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/create_sqladmin_app.py,sha256=x5F8--5KA4cmTrb6kAAmp6fVd2TiqxPOzxqUkSEhSG4,1298
233
233
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/event.py,sha256=LjAUYNlsX9Sj_QLMzYuTQbbYYbIMHhbsSjTXt-G7lOE,849
234
234
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/__init__.py,sha256=dc_swzjkRDj85SWQ3cGGgsrp_cq5evUYQYUg0g7C5nw,435
235
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/api_key.py,sha256=VZKCG2GQworbmB_PPHPU10qMf5IThP0LN27k50XlHlg,1570
235
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/api_key.py,sha256=VTpepKLCKrPnftGD-8Ibp75S0dwUrLlUytRfcXDDcKg,1597
236
236
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/common.py,sha256=StdbfHZ92qAP-l2lnvAeyYCaZuMHKskHq1E19zJh6MA,2471
237
237
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/operation.py,sha256=4BFJEp_yIpZltfEjsBC__J_BfgIBYzOc6LeoWFxP1MI,2785
238
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/story_log.py,sha256=8N9ahbCzNVczqgO_g0luRqP8luCv5bmCLoz66UYZ0mU,1427
239
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user.py,sha256=-QxTreqrSZkIUDrTWkkTH8jI--tH7kXwpWq9TRn_1X4,1984
240
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user_token.py,sha256=gGhpfqwydZ5VA6vdvNblp3NQHqXZLd1K3OxcYVU1SoM,1789
241
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/verification_code.py,sha256=_uuBUTkV7cAhHxaBVYk8JSp5voATOc-Kgq36-nC_o-w,2159
238
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/story_log.py,sha256=INs2g2uy7CFlyVWUUXJOlEqawxNdWDdo00zy4Ly_RSM,1401
239
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user.py,sha256=npO1CSSycbgzgL7fWRuxIoB1zJySVqISP0ZKwjSm6y8,1953
240
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user_token.py,sha256=Q826LQIiK9J5JKKaAyB0xituMUxuMyyvFF-c1ekyAPM,1784
241
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/verification_code.py,sha256=AU0f9VzBxeBkVTSp2tpqracLYW5gsJIx69PrIYTn5H8,2485
242
242
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
243
243
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/util/etc.py,sha256=jm65ZB0K8e6WpgcL2Y6pxcIuQjioIyMtBIOOFbbWfgk,1070
244
244
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -255,7 +255,7 @@ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model
255
255
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/util.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
256
256
  arpakitlib/_arpakit_project_template_v_5/project/test_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
257
257
  arpakitlib/_arpakit_project_template_v_5/project/test_data/make_test_api_keys.py,sha256=9F2bMfymaqx_Czh_tF945BKpKqNrVNjSIfCQl13Dkxw,911
258
- arpakitlib/_arpakit_project_template_v_5/project/test_data/make_test_data_1.py,sha256=kXtfNYVweDuv1z8gED2Zr1oP1NW5eMbeR3D7HGoguEE,1574
258
+ arpakitlib/_arpakit_project_template_v_5/project/test_data/make_test_data_1.py,sha256=B6due_6egjIT_tC5Glg2kIR0tBUNdlRW2Oyy6j-ga2Q,2212
259
259
  arpakitlib/_arpakit_project_template_v_5/project/test_data/make_test_data_2.py,sha256=VcCvxRLA0XnLaQcsaoZkIVV8rTO3uMyLTYoEsdxKtYE,416
260
260
  arpakitlib/_arpakit_project_template_v_5/project/test_data/make_test_data_3.py,sha256=9QJTgM4qsJXPgFhfVueQ9vObXr_dAldzP_p8dPO42uA,416
261
261
  arpakitlib/_arpakit_project_template_v_5/project/test_data/make_test_data_4.py,sha256=OyU9601WACF7cCpPT33x6CpizNJeQIPDDFezIvEO01A,416
@@ -340,9 +340,13 @@ arpakitlib/_arpakit_project_template_v_5/project/tg_bot/util/__init__.py,sha256=
340
340
  arpakitlib/_arpakit_project_template_v_5/project/tg_bot/util/etc.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
341
341
  arpakitlib/_arpakit_project_template_v_5/project/tg_bot/util/notify_admins.py,sha256=ikjp5J0qgq6LGxh6iFcVIKtO3cUed3p39NwcFLcatVE,2096
342
342
  arpakitlib/_arpakit_project_template_v_5/project/tg_bot/util/set_tg_bot_commands.py,sha256=eTVOpwp8zn74QhLgmbLkxn3cH4xPzQN02euS-7UP-Eg,3489
343
+ arpakitlib/_arpakit_project_template_v_5/project/tg_bot_notifier/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
344
+ arpakitlib/_arpakit_project_template_v_5/project/tg_bot_notifier/blank.py,sha256=0rspOC-xS9qdQ58pAJI-tNTgbylQIXCrEr79MMgvU1k,406
345
+ arpakitlib/_arpakit_project_template_v_5/project/tg_bot_notifier/tg_bot_notifier.py,sha256=9JbalZDmR4a2cqPe9rB_KnUX7YibVC6S5wTHma9G7AI,843
343
346
  arpakitlib/_arpakit_project_template_v_5/project/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
344
347
  arpakitlib/_arpakit_project_template_v_5/project/util/arpakitlib_project_template_util.py,sha256=syA_IuszHVub0zm0sVdB4_7rPJXwXRW4JmQ4qHbjXPk,396
345
348
  arpakitlib/_arpakit_project_template_v_5/project/util/etc.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
349
+ arpakitlib/_arpakit_project_template_v_5/project/util/send_email.py,sha256=lw-nUFtEYiGEChSZrfuXCtTkoY6fNT45M_Y6QfzOk90,2175
346
350
  arpakitlib/_arpakit_project_template_v_5/todo.txt,sha256=q132Jbx229ThY77S3YiN-Cj5AVm7k1VlJcMYIbZUHUY,3
347
351
  arpakitlib/ar_additional_model_util.py,sha256=GFg-glLCxH9X95R2bhTJsscVwv37FgE1qbaAAyXrnIE,917
348
352
  arpakitlib/ar_aiogram_util.py,sha256=4bizX5Xg-E2-r2TXXGQGanJozsIWPVf5luO3vKUN8p8,8471
@@ -392,8 +396,8 @@ arpakitlib/ar_ssh_runner_util.py,sha256=yvAwza480MkHKvLkDEsR7JNh2bYNs6P9rCVo4NA8
392
396
  arpakitlib/ar_str_util.py,sha256=CAv0wH8nP5Ja59S-hEdmNhNrM_Fwy935d0zntLpJkx8,4309
393
397
  arpakitlib/ar_type_util.py,sha256=Cs_tef-Fc5xeyAF54KgISCsP11NHyzIsglm4S3Xx7iM,4049
394
398
  arpakitlib/ar_yookassa_api_client_util.py,sha256=VozuZeCJjmLd1zj2BdC9WfiAQ3XYOrIMsdpNK-AUlm0,5347
395
- arpakitlib-1.8.111.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
396
- arpakitlib-1.8.111.dist-info/METADATA,sha256=Mjct-ehVPyOyZIp4nDKE5oJWtPvFcdJ_X2JmNcy45uI,3566
397
- arpakitlib-1.8.111.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
398
- arpakitlib-1.8.111.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
399
- arpakitlib-1.8.111.dist-info/RECORD,,
399
+ arpakitlib-1.8.112.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
400
+ arpakitlib-1.8.112.dist-info/METADATA,sha256=rRtXEb7kPS7p60Eb4WtlFZf7YVi8W0ABiq-sGC4hRAc,3566
401
+ arpakitlib-1.8.112.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
402
+ arpakitlib-1.8.112.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
403
+ arpakitlib-1.8.112.dist-info/RECORD,,