arpakitlib 1.8.100__py3-none-any.whl → 1.8.102__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 (18) hide show
  1. arpakitlib/_arpakit_project_template_v_5/arpakitlib_project_template_info.json +1 -1
  2. arpakitlib/_arpakit_project_template_v_5/command/start_api.py +7 -0
  3. arpakitlib/_arpakit_project_template_v_5/command/start_api_for_prod.py +7 -0
  4. arpakitlib/_arpakit_project_template_v_5/command/start_api_with_reload.py +7 -0
  5. arpakitlib/_arpakit_project_template_v_5/command/start_operation_executor_workers_mode_async_task.py +24 -0
  6. arpakitlib/_arpakit_project_template_v_5/command/{start_operation_executor_workers.py → start_operation_executor_workers_mode_thread.py} +1 -0
  7. arpakitlib/_arpakit_project_template_v_5/project/business_service/create_first_admin.py +37 -0
  8. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/__init__.py +1 -0
  9. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/story_log.py +10 -1
  10. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/verification_code.py +53 -0
  11. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/__init__.py +1 -0
  12. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user.py +8 -0
  13. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/verification_code.py +101 -0
  14. {arpakitlib-1.8.100.dist-info → arpakitlib-1.8.102.dist-info}/METADATA +1 -1
  15. {arpakitlib-1.8.100.dist-info → arpakitlib-1.8.102.dist-info}/RECORD +18 -14
  16. {arpakitlib-1.8.100.dist-info → arpakitlib-1.8.102.dist-info}/LICENSE +0 -0
  17. {arpakitlib-1.8.100.dist-info → arpakitlib-1.8.102.dist-info}/WHEEL +0 -0
  18. {arpakitlib-1.8.100.dist-info → arpakitlib-1.8.102.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": "21"
3
+ "arpakitlib_project_template_subversion": "23"
4
4
  }
@@ -1,11 +1,18 @@
1
1
  import uvicorn
2
2
 
3
+ from arpakitlib.ar_base_worker_util import safe_run_worker_in_background, SafeRunInBackgroundModes
3
4
  from project.core.settings import get_cached_settings
4
5
  from project.core.util import setup_logging
6
+ from project.operation_execution.scheduled_operation_creator_worker import create_scheduled_operation_creator_worker
5
7
 
6
8
 
7
9
  def __command():
8
10
  setup_logging()
11
+ if get_cached_settings().api_start_scheduled_operation_creator_worker:
12
+ _ = safe_run_worker_in_background(
13
+ worker=create_scheduled_operation_creator_worker(),
14
+ mode=SafeRunInBackgroundModes.thread
15
+ )
9
16
  uvicorn.run(
10
17
  "project.api.asgi:app",
11
18
  port=get_cached_settings().api_port,
@@ -1,11 +1,18 @@
1
1
  import uvicorn
2
2
 
3
+ from arpakitlib.ar_base_worker_util import safe_run_worker_in_background, SafeRunInBackgroundModes
3
4
  from project.core.settings import get_cached_settings
4
5
  from project.core.util import setup_logging
6
+ from project.operation_execution.scheduled_operation_creator_worker import create_scheduled_operation_creator_worker
5
7
 
6
8
 
7
9
  def __command():
8
10
  setup_logging()
11
+ if get_cached_settings().api_start_scheduled_operation_creator_worker:
12
+ _ = safe_run_worker_in_background(
13
+ worker=create_scheduled_operation_creator_worker(),
14
+ mode=SafeRunInBackgroundModes.thread
15
+ )
9
16
  uvicorn.run(
10
17
  app="project.api.asgi:app",
11
18
  host="127.0.0.1",
@@ -1,11 +1,18 @@
1
1
  import uvicorn
2
2
 
3
+ from arpakitlib.ar_base_worker_util import SafeRunInBackgroundModes, safe_run_worker_in_background
3
4
  from project.core.settings import get_cached_settings
4
5
  from project.core.util import setup_logging
6
+ from project.operation_execution.scheduled_operation_creator_worker import create_scheduled_operation_creator_worker
5
7
 
6
8
 
7
9
  def __command():
8
10
  setup_logging()
11
+ if get_cached_settings().api_start_scheduled_operation_creator_worker:
12
+ _ = safe_run_worker_in_background(
13
+ worker=create_scheduled_operation_creator_worker(),
14
+ mode=SafeRunInBackgroundModes.thread
15
+ )
9
16
  uvicorn.run(
10
17
  "project.api.asgi:app",
11
18
  port=get_cached_settings().api_port,
@@ -0,0 +1,24 @@
1
+ import asyncio
2
+
3
+ from arpakitlib.ar_base_worker_util import safe_run_workers_in_background, SafeRunInBackgroundModes
4
+ from project.core.util import setup_logging
5
+ from project.operation_execution.operation_executor_worker import OperationExecutorWorker
6
+ from project.sqlalchemy_db_.sqlalchemy_db import get_cached_sqlalchemy_db
7
+
8
+
9
+ async def __async_command():
10
+ setup_logging()
11
+ workers = []
12
+ for i in range(int(input("amount of workers: "))):
13
+ workers.append(OperationExecutorWorker(
14
+ sqlalchemy_db=get_cached_sqlalchemy_db(),
15
+ ))
16
+ async_tasks = safe_run_workers_in_background(
17
+ workers=workers,
18
+ mode=SafeRunInBackgroundModes.async_task
19
+ )
20
+ await asyncio.gather(*async_tasks)
21
+
22
+
23
+ if __name__ == '__main__':
24
+ asyncio.run(__async_command())
@@ -1,4 +1,5 @@
1
1
  from arpakitlib.ar_base_worker_util import safe_run_workers_in_background, SafeRunInBackgroundModes
2
+
2
3
  from project.core.util import setup_logging
3
4
  from project.operation_execution.operation_executor_worker import OperationExecutorWorker
4
5
  from project.sqlalchemy_db_.sqlalchemy_db import get_cached_sqlalchemy_db
@@ -0,0 +1,37 @@
1
+ import logging
2
+
3
+ from project.core.util import setup_logging
4
+ from project.sqlalchemy_db_.sqlalchemy_db import get_cached_sqlalchemy_db
5
+ from project.sqlalchemy_db_.sqlalchemy_model import UserDBM
6
+
7
+ _logger = logging.getLogger(__name__)
8
+
9
+
10
+ def create_first_admin():
11
+ with get_cached_sqlalchemy_db().new_session() as session:
12
+ user_dbm = (
13
+ session
14
+ .query(UserDBM)
15
+ .filter(UserDBM.roles.any(UserDBM.Roles.admin))
16
+ .first()
17
+ )
18
+ if user_dbm is not None:
19
+ _logger.info("first admin already exists")
20
+ return
21
+ user_dbm = UserDBM(
22
+ username="admin",
23
+ roles=[UserDBM.Roles.client, UserDBM.Roles.admin],
24
+ password="admin",
25
+ )
26
+ session.add(user_dbm)
27
+ session.commit()
28
+ _logger.info("first admin was created")
29
+
30
+
31
+ def command():
32
+ setup_logging()
33
+ create_first_admin()
34
+
35
+
36
+ if __name__ == '__main__':
37
+ command()
@@ -4,3 +4,4 @@ from project.sqladmin_.model_view.operation import OperationMV
4
4
  from project.sqladmin_.model_view.story_log import StoryLogMV
5
5
  from project.sqladmin_.model_view.user import UserMV
6
6
  from project.sqladmin_.model_view.user_token import UserTokenMV
7
+ from project.sqladmin_.model_view.verification_code import VerificationCodeMV
@@ -9,7 +9,16 @@ class StoryLogMV(SimpleMV, model=StoryLogDBM):
9
9
  name = "StoryLog"
10
10
  name_plural = "StoryLogs"
11
11
  icon = "fa-solid fa-history"
12
- column_list = sqlalchemy.inspect(StoryLogDBM).columns
12
+ column_list = [
13
+ StoryLogDBM.id,
14
+ StoryLogDBM.long_id,
15
+ StoryLogDBM.slug,
16
+ StoryLogDBM.creation_dt,
17
+ StoryLogDBM.level,
18
+ StoryLogDBM.type,
19
+ StoryLogDBM.title,
20
+ StoryLogDBM.extra_data
21
+ ]
13
22
  form_columns = [
14
23
  StoryLogDBM.slug,
15
24
  StoryLogDBM.level,
@@ -0,0 +1,53 @@
1
+ from __future__ import annotations
2
+
3
+ import sqlalchemy
4
+
5
+ from project.sqladmin_.model_view import SimpleMV
6
+ from project.sqladmin_.util.etc import format_datetime_, format_json_for_preview_, format_json_
7
+ from project.sqlalchemy_db_.sqlalchemy_model import VerificationCodeDBM
8
+
9
+
10
+ class VerificationCodeMV(SimpleMV, model=VerificationCodeDBM):
11
+ name = "VerificationCode"
12
+ name_plural = "VerificationCodes"
13
+ icon = "fa-solid fa-envelope"
14
+ column_list = [
15
+ VerificationCodeDBM.id,
16
+ VerificationCodeDBM.long_id,
17
+ VerificationCodeDBM.slug,
18
+ VerificationCodeDBM.creation_dt,
19
+ VerificationCodeDBM.type,
20
+ VerificationCodeDBM.value,
21
+ VerificationCodeDBM.recipient,
22
+ VerificationCodeDBM.user,
23
+ VerificationCodeDBM.is_active,
24
+ VerificationCodeDBM.extra_data
25
+ ]
26
+ form_columns = [
27
+ VerificationCodeDBM.slug,
28
+ VerificationCodeDBM.type,
29
+ VerificationCodeDBM.value,
30
+ VerificationCodeDBM.recipient,
31
+ VerificationCodeDBM.user,
32
+ VerificationCodeDBM.is_active,
33
+ VerificationCodeDBM.extra_data
34
+ ]
35
+ column_sortable_list = sqlalchemy.inspect(VerificationCodeDBM).columns
36
+ column_default_sort = [
37
+ (VerificationCodeDBM.creation_dt, True)
38
+ ]
39
+ column_searchable_list = [
40
+ VerificationCodeDBM.id,
41
+ VerificationCodeDBM.long_id,
42
+ VerificationCodeDBM.slug,
43
+ VerificationCodeDBM.value,
44
+ VerificationCodeDBM.recipient,
45
+ ]
46
+ column_formatters = {
47
+ VerificationCodeDBM.creation_dt: lambda m, _: format_datetime_(m.creation_dt),
48
+ VerificationCodeDBM.extra_data: lambda m, _: format_json_for_preview_(m.extra_data)
49
+ }
50
+ column_formatters_detail = {
51
+ VerificationCodeDBM.creation_dt: lambda m, _: format_datetime_(m.creation_dt),
52
+ VerificationCodeDBM.extra_data: lambda m, a: format_json_(m.extra_data),
53
+ }
@@ -6,6 +6,7 @@ from project.sqlalchemy_db_.sqlalchemy_model.operation import OperationDBM
6
6
  from project.sqlalchemy_db_.sqlalchemy_model.story_log import StoryLogDBM
7
7
  from project.sqlalchemy_db_.sqlalchemy_model.user import UserDBM
8
8
  from project.sqlalchemy_db_.sqlalchemy_model.user_token import UserTokenDBM
9
+ from project.sqlalchemy_db_.sqlalchemy_model.verification_code import VerificationCodeDBM
9
10
 
10
11
  if __name__ == '__main__':
11
12
  print(get_string_info_from_declarative_base(SimpleDBM))
@@ -15,6 +15,7 @@ from sqlalchemy.orm import Mapped, mapped_column, relationship, validates
15
15
 
16
16
  if TYPE_CHECKING:
17
17
  from project.sqlalchemy_db_.sqlalchemy_model.user_token import UserTokenDBM
18
+ from project.sqlalchemy_db_.sqlalchemy_model.verification_code import VerificationCodeDBM
18
19
 
19
20
 
20
21
  def generate_default_user_password() -> str:
@@ -87,6 +88,13 @@ class UserDBM(SimpleDBM):
87
88
  foreign_keys="UserTokenDBM.user_id",
88
89
  cascade="all, delete-orphan"
89
90
  )
91
+ verification_codes: Mapped[list[VerificationCodeDBM]] = relationship(
92
+ "VerificationCodeDBM",
93
+ uselist=True,
94
+ back_populates="user",
95
+ foreign_keys="VerificationCodeDBM.user_id",
96
+ cascade="all, delete-orphan"
97
+ )
90
98
 
91
99
  def __repr__(self) -> str:
92
100
  parts = [f"id={self.id}"]
@@ -0,0 +1,101 @@
1
+ from __future__ import annotations
2
+
3
+ from random import randint
4
+ from typing import TYPE_CHECKING
5
+
6
+ import sqlalchemy
7
+ from sqlalchemy.orm import Mapped, mapped_column, relationship, validates
8
+
9
+ from arpakitlib.ar_enumeration_util import Enumeration
10
+ from arpakitlib.ar_str_util import make_none_if_blank
11
+ from project.sqlalchemy_db_.sqlalchemy_model.common import SimpleDBM
12
+
13
+ if TYPE_CHECKING:
14
+ from project.sqlalchemy_db_.sqlalchemy_model.user import UserDBM
15
+
16
+
17
+ def generate_default_verification_code_value() -> str:
18
+ alphabet: list = list("JZSDQWRLGFZX" + "123456789")
19
+ return "".join(alphabet[randint(0, len(alphabet) - 1)] for _ in range(7))
20
+
21
+
22
+ class VerificationCodeDBM(SimpleDBM):
23
+ __tablename__ = "verification_code"
24
+
25
+ class Types(Enumeration):
26
+ register_or_authenticate = "register_or_authenticate"
27
+ reset_email = "reset_email"
28
+
29
+ type: Mapped[str] = mapped_column(
30
+ sqlalchemy.TEXT,
31
+ nullable=False,
32
+ index=True,
33
+ )
34
+ value: Mapped[str] = mapped_column(
35
+ sqlalchemy.TEXT,
36
+ nullable=False,
37
+ index=True,
38
+ insert_default=generate_default_verification_code_value,
39
+ server_default=sqlalchemy.func.gen_random_uuid(),
40
+ )
41
+ recipient: Mapped[str | None] = mapped_column(
42
+ sqlalchemy.TEXT,
43
+ nullable=True,
44
+ index=True,
45
+ )
46
+ user_id: Mapped[int | None] = mapped_column(
47
+ sqlalchemy.BIGINT,
48
+ sqlalchemy.ForeignKey("user.id", ondelete="CASCADE"),
49
+ nullable=True,
50
+ index=True,
51
+ )
52
+ is_active: Mapped[bool] = mapped_column(
53
+ sqlalchemy.BOOLEAN,
54
+ nullable=False,
55
+ index=True,
56
+ insert_default=True,
57
+ server_default="true"
58
+ )
59
+
60
+ # one to many
61
+ user: Mapped[UserDBM | None] = relationship(
62
+ "UserDBM",
63
+ uselist=False,
64
+ back_populates="verification_codes",
65
+ foreign_keys=[user_id]
66
+ )
67
+
68
+ def __repr__(self) -> str:
69
+ parts = [
70
+ f"id={self.id}",
71
+ f"type={self.type}"
72
+ ]
73
+ if self.recipient is not None:
74
+ parts.append(f"recipient={self.recipient}")
75
+ elif self.user_id is not None:
76
+ parts.append(f"user_id={self.user_id}")
77
+ return f"{self.entity_name} ({', '.join(parts)})"
78
+
79
+ @validates("type")
80
+ def _validate_type(self, key, value, *args, **kwargs):
81
+ if not isinstance(value, str):
82
+ raise ValueError(f"{key=}, {value=}, value is not str")
83
+ value = value.strip()
84
+ if not value:
85
+ raise ValueError(f"{key=}, {value=}, value is empty")
86
+ if value not in self.Types.values_list():
87
+ raise ValueError(f"{value} not in {self.Types.values_list()}")
88
+ return value
89
+
90
+ @validates("recipient")
91
+ def _validate_recipient(self, key, value, *args, **kwargs):
92
+ if value is None:
93
+ return None
94
+ if not isinstance(value, str):
95
+ raise ValueError(f"{key=}, {value=}, value is not str")
96
+ value = make_none_if_blank(value.strip())
97
+ return value
98
+
99
+ @property
100
+ def sdp_allowed_types(self) -> list[str]:
101
+ return self.Types.values_list()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: arpakitlib
3
- Version: 1.8.100
3
+ Version: 1.8.102
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=venTIy_RqpxyWRH5vD97JdtvE3PFVKeDXpib2U_2GEo,98
11
+ arpakitlib/_arpakit_project_template_v_5/arpakitlib_project_template_info.json,sha256=nA0stvcyYF7cr-ggkBiG3M0ZUSctM3U6PsIFUSFqX40,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
@@ -59,11 +59,12 @@ arpakitlib/_arpakit_project_template_v_5/command/set_tg_bot_commands.py,sha256=6
59
59
  arpakitlib/_arpakit_project_template_v_5/command/show_arpakitlib_project_template_info.py,sha256=EYpiZkzVKCoZa_iWbh2LnhqEV88HQgbhS84KVZFpIDo,204
60
60
  arpakitlib/_arpakit_project_template_v_5/command/show_settings.py,sha256=c07DRqJ08tPm2nFSLAxm_h1dNSQIbWT_hL65g869CWw,264
61
61
  arpakitlib/_arpakit_project_template_v_5/command/show_sqlalchemy_db_table_name_to_amount.py,sha256=4KCP-ud5tDKLdTxJLZTDnPzbbNwY33XIUR_qRXjbkH8,410
62
- arpakitlib/_arpakit_project_template_v_5/command/start_api.py,sha256=UoPkeKfSh1Ekq2Gxf3fv8aHrSVF_Xi4C14eBliXU6x0,364
63
- arpakitlib/_arpakit_project_template_v_5/command/start_api_for_prod.py,sha256=L1Qa5_YDH-YYs31WJIT0fcgj_vgeUopXKD9vzAL105E,368
64
- arpakitlib/_arpakit_project_template_v_5/command/start_api_with_reload.py,sha256=YVKe6uP4cs1ow4Bd2ptiDRcHv_eGHaABlp2SgfMI2oM,363
62
+ arpakitlib/_arpakit_project_template_v_5/command/start_api.py,sha256=fl-dkm2I3ModQXjGG6VrP6vUFciEcRW_ORFG3VX8jH8,821
63
+ arpakitlib/_arpakit_project_template_v_5/command/start_api_for_prod.py,sha256=T0Gqv3-Vrtx6x_3vRaFTvsyWwpZgfDnqtnQcZN3eqU8,825
64
+ arpakitlib/_arpakit_project_template_v_5/command/start_api_with_reload.py,sha256=d6iIQY4_qjcYBoYmkWXbPVVW5HD5IUb4FOvf4YrzObM,820
65
65
  arpakitlib/_arpakit_project_template_v_5/command/start_operation_executor_worker.py,sha256=X8dE5OcTEVKjbcXdU0QMstXbi8RyYWPzATHtbQHyBIs,413
66
- arpakitlib/_arpakit_project_template_v_5/command/start_operation_executor_workers.py,sha256=pVfnAwSKKupVHinwqXAkQOkjwZ-WCRuO7AUGjfAQhzs,717
66
+ arpakitlib/_arpakit_project_template_v_5/command/start_operation_executor_workers_mode_async_task.py,sha256=C5aoJmI9LB9d25g_ZTvRccwkWUglUdcCcPb-03HoA0s,793
67
+ arpakitlib/_arpakit_project_template_v_5/command/start_operation_executor_workers_mode_thread.py,sha256=QjInoDY7XGQZCs2A-Kh5Ul0P4CgcS9Tom6FfXcseeFs,718
67
68
  arpakitlib/_arpakit_project_template_v_5/command/start_scheduled_operation_creator_worker.py,sha256=NuimX6etxQ9EU0VYOWw43AGiuOsZf8a4wilAd3ZzmRY,329
68
69
  arpakitlib/_arpakit_project_template_v_5/command/start_sqladmin.py,sha256=g3kNKPR4X-PKpiSe4oFLHbZ-EJIwmWUOK6a5FABat_Y,375
69
70
  arpakitlib/_arpakit_project_template_v_5/command/start_sqladmin_for_prod.py,sha256=g3kNKPR4X-PKpiSe4oFLHbZ-EJIwmWUOK6a5FABat_Y,375
@@ -159,6 +160,7 @@ arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/user.py,
159
160
  arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/user_token.py,sha256=iiuZXu_zo3FJX0W5qyyMGasUx-_d32yjqc_2KY3xpUA,513
160
161
  arpakitlib/_arpakit_project_template_v_5/project/api/util.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
161
162
  arpakitlib/_arpakit_project_template_v_5/project/business_service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
163
+ arpakitlib/_arpakit_project_template_v_5/project/business_service/create_first_admin.py,sha256=2TzUxP8XY1ijTMXzpjfwelWgtqDmuX9_VmN915cvfkI,959
162
164
  arpakitlib/_arpakit_project_template_v_5/project/business_service/hello_world.py,sha256=lvWlVF6SlnC33swSCd-_QK6guxBg50myOd8cPS7hZrA,251
163
165
  arpakitlib/_arpakit_project_template_v_5/project/business_service/remove_operations.py,sha256=E2F8xonPeZovKKOHv-XDmsQUHvks8A6R89PVhF_pAQI,1780
164
166
  arpakitlib/_arpakit_project_template_v_5/project/celery_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -228,25 +230,27 @@ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/admin_authorize.py,sh
228
230
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/asgi.py,sha256=DRlRPkcOGXOccfP73oKEXolZTsc5VWdQgEG-qoW03ms,99
229
231
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/create_sqladmin_app.py,sha256=x5F8--5KA4cmTrb6kAAmp6fVd2TiqxPOzxqUkSEhSG4,1298
230
232
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/event.py,sha256=LjAUYNlsX9Sj_QLMzYuTQbbYYbIMHhbsSjTXt-G7lOE,849
231
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/__init__.py,sha256=MtEk37LR9xg5XltEbIAw1hh74BsS70I2G3C21QSbjVQ,357
233
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/__init__.py,sha256=dc_swzjkRDj85SWQ3cGGgsrp_cq5evUYQYUg0g7C5nw,435
232
234
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/api_key.py,sha256=SNk66VApMLgfOHB8grLDiYnm8KYZTmw7eoOdBmkZCfw,1193
233
235
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/common.py,sha256=US1tueTCPvAdse6TLT6yRLUHbvwGGagApYhFJzE_6Yc,576
234
236
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/operation.py,sha256=lIwqYRd2n-wPAKtDlPpNqNHAcSxJDMbtfh8upShqN1I,2112
235
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/story_log.py,sha256=yTBHnL8em7d96o-tL2OsKQEryDQfDYFeEUpkNTjfHQI,1236
237
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/story_log.py,sha256=8N9ahbCzNVczqgO_g0luRqP8luCv5bmCLoz66UYZ0mU,1427
236
238
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user.py,sha256=7pjzmIe-Nit2Bk3GL4H7sLem46UcHN1sLc5ZrWd3xQQ,1679
237
239
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user_token.py,sha256=q1kjGEkNvaMmbxnpMmR66qF1CdkIChC_SF3YVJnYsks,1529
240
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/verification_code.py,sha256=llFZ3KDtv0M-wAC77IGAiF9TM8fO83w1xlTWr_t-vHk,1900
238
241
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
239
242
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/util/etc.py,sha256=jm65ZB0K8e6WpgcL2Y6pxcIuQjioIyMtBIOOFbbWfgk,1070
240
243
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
241
244
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/const.py,sha256=dcvj5C9E2F2KCsGZPBBncQf_EvVJAC1qQgnyD8P4ZEw,6
242
245
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_db.py,sha256=1y3FaMFzm_5UM2poqtBve_UP_mh1vjs--krq6yO8PsA,742
243
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/__init__.py,sha256=btSjCQ7RJqomeXzYs9HePCu1dZHs0z6-RuboYKG89_8,598
246
+ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/__init__.py,sha256=zRK-ao92u6Q-NNTtsPycTVEjzRjK5BOXgsUZRtNblpM,688
244
247
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/api_key.py,sha256=4Y4zgKzty_7xqqJWg4DDiS0nbDXzQVtq2r6d0lunnTw,2025
245
248
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/common.py,sha256=_ddBled1XX6YR3LxoWmRlZjwMRHlBmQRBVg0vGcPe_8,3228
246
249
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/operation.py,sha256=VkaUFYgnpGfQbJP_APuCRwzzQRr7yGgnEbbNlsizwgU,5912
247
250
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/story_log.py,sha256=hqkXH7oV-BT8pRDzrDYWYseVFg2J6ca-WYyiucPOiH4,2395
248
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user.py,sha256=xBU_DPq7S_2gv15LOhiTttL5dZzPTbcjpSNU8yY9ZPo,6998
251
+ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user.py,sha256=S3WVBJVMXVh2ryoaiLTcMQ5tvShyagBdzUJg5vd-Af0,7345
249
252
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user_token.py,sha256=y97em7M2WfDV8Wm7GMrIejalk9NkCsZDGK-sETkXscM,1943
253
+ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/verification_code.py,sha256=13aDT9m2l9zaJXqHZi0MsoY--5BNWhbw0O9uQJAW16E,3136
250
254
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/util.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
251
255
  arpakitlib/_arpakit_project_template_v_5/project/test_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
252
256
  arpakitlib/_arpakit_project_template_v_5/project/test_data/make_test_api_keys.py,sha256=9F2bMfymaqx_Czh_tF945BKpKqNrVNjSIfCQl13Dkxw,911
@@ -386,8 +390,8 @@ arpakitlib/ar_ssh_runner_util.py,sha256=yvAwza480MkHKvLkDEsR7JNh2bYNs6P9rCVo4NA8
386
390
  arpakitlib/ar_str_util.py,sha256=CAv0wH8nP5Ja59S-hEdmNhNrM_Fwy935d0zntLpJkx8,4309
387
391
  arpakitlib/ar_type_util.py,sha256=Cs_tef-Fc5xeyAF54KgISCsP11NHyzIsglm4S3Xx7iM,4049
388
392
  arpakitlib/ar_yookassa_api_client_util.py,sha256=VozuZeCJjmLd1zj2BdC9WfiAQ3XYOrIMsdpNK-AUlm0,5347
389
- arpakitlib-1.8.100.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
390
- arpakitlib-1.8.100.dist-info/METADATA,sha256=kK50HqrbhbC_DqPELA0sk-mlRTDP3MPnD3b2SjyKMNQ,3471
391
- arpakitlib-1.8.100.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
392
- arpakitlib-1.8.100.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
393
- arpakitlib-1.8.100.dist-info/RECORD,,
393
+ arpakitlib-1.8.102.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
394
+ arpakitlib-1.8.102.dist-info/METADATA,sha256=LG55NcqdiGyBy4787OrZbegLHoI1fvjjMfLiIZsUVwM,3471
395
+ arpakitlib-1.8.102.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
396
+ arpakitlib-1.8.102.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
397
+ arpakitlib-1.8.102.dist-info/RECORD,,