arpakitlib 1.8.218__py3-none-any.whl → 1.8.220__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 (22) 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/schema/util/{schema_from_dbm.py → create_obj_schema_from_dbm.py} +2 -2
  3. arpakitlib/_arpakit_project_template_v_5/project/operation_execution/scheduled_operations.py +1 -1
  4. arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_3.py +5 -1
  5. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/__init__.py +0 -1
  6. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/api_key.py +6 -43
  7. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/operation.py +9 -64
  8. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/story_log.py +8 -48
  9. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user_token.py +8 -48
  10. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/verification_code.py +8 -59
  11. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/__init__.py +1 -1
  12. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/common.py +52 -5
  13. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/operation.py +36 -28
  14. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/story_log.py +2 -0
  15. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user_token.py +6 -0
  16. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/verification_code.py +6 -15
  17. arpakitlib/pydantic_schema_from_sqlalchemy_model.py +91 -0
  18. {arpakitlib-1.8.218.dist-info → arpakitlib-1.8.220.dist-info}/METADATA +1 -1
  19. {arpakitlib-1.8.218.dist-info → arpakitlib-1.8.220.dist-info}/RECORD +22 -21
  20. {arpakitlib-1.8.218.dist-info → arpakitlib-1.8.220.dist-info}/LICENSE +0 -0
  21. {arpakitlib-1.8.218.dist-info → arpakitlib-1.8.220.dist-info}/WHEEL +0 -0
  22. {arpakitlib-1.8.218.dist-info → arpakitlib-1.8.220.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": "54"
3
+ "arpakitlib_project_template_subversion": "55"
4
4
  }
@@ -4,7 +4,7 @@ from arpakitlib.ar_sqlalchemy_util import BaseDBM
4
4
  from pydantic import BaseModel
5
5
 
6
6
 
7
- def schema_from_dbm(*, schema: Type[BaseModel], dbm: BaseDBM, **kwargs) -> BaseModel:
7
+ def create_obj_schema_from_dbm(*, schema: Type[BaseModel], dbm: BaseDBM, **kwargs) -> BaseModel:
8
8
  return schema.model_validate(dbm.simple_dict(
9
9
  include_columns_and_sd_properties=schema.model_fields.keys()
10
- ))
10
+ ))
@@ -1,8 +1,8 @@
1
1
  from datetime import timedelta
2
2
  from typing import Any, Callable
3
3
 
4
- from pydantic import ConfigDict
5
4
  from pydantic import BaseModel
5
+ from pydantic import ConfigDict
6
6
 
7
7
  from project.operation_execution.util import every_timedelta_is_time_func
8
8
  from project.sqlalchemy_db_.sqlalchemy_model import OperationDBM
@@ -1,8 +1,12 @@
1
1
  import asyncio
2
2
 
3
+ from arpakitlib.pydantic_schema_from_sqlalchemy_model import pydantic_schema_from_sqlalchemy_model
4
+ from project.sqlalchemy_db_.sqlalchemy_model import UserDBM
5
+
3
6
 
4
7
  def __sandbox():
5
- pass
8
+ a = pydantic_schema_from_sqlalchemy_model(sqlalchemy_model=UserDBM, include_defaults=True)
9
+ print(a())
6
10
 
7
11
 
8
12
  async def __async_sandbox():
@@ -7,6 +7,5 @@ from project.sqladmin_.model_view.user import UserMV
7
7
  from project.sqladmin_.model_view.user_token import UserTokenMV
8
8
  from project.sqladmin_.model_view.verification_code import VerificationCodeMV
9
9
 
10
-
11
10
  if __name__ == '__main__':
12
11
  print(get_string_info_from_model_view(class_=SimpleMV))
@@ -1,54 +1,17 @@
1
1
  import sqlalchemy
2
2
 
3
3
  from project.sqladmin_.model_view.common import SimpleMV
4
- from project.sqladmin_.util.etc import format_datetime_, format_json_, format_json_for_preview_
5
4
  from project.sqlalchemy_db_.sqlalchemy_model import ApiKeyDBM
6
5
 
7
6
 
8
7
  class ApiKeyMV(SimpleMV, model=ApiKeyDBM):
9
- name = "ApiKey"
10
- name_plural = "ApiKeys"
8
+ name = ApiKeyDBM.get_cls_entity_name()
9
+ name_plural = ApiKeyDBM.get_cls_entity_name_plural()
11
10
  icon = "fa-solid fa-key"
12
- column_list = [
13
- ApiKeyDBM.id,
14
- ApiKeyDBM.long_id,
15
- ApiKeyDBM.slug,
16
- ApiKeyDBM.creation_dt,
17
- ApiKeyDBM.title,
18
- ApiKeyDBM.value,
19
- ApiKeyDBM.is_active,
20
- ApiKeyDBM.extra_data
21
- ]
22
- column_details_list = [
23
- ApiKeyDBM.id,
24
- ApiKeyDBM.long_id,
25
- ApiKeyDBM.slug,
26
- ApiKeyDBM.creation_dt,
27
- ApiKeyDBM.title,
28
- ApiKeyDBM.value,
29
- ApiKeyDBM.is_active,
30
- ApiKeyDBM.extra_data
31
- ]
32
- form_columns = [
33
- ApiKeyDBM.slug,
34
- ApiKeyDBM.title,
35
- ApiKeyDBM.value,
36
- ApiKeyDBM.is_active,
37
- ]
11
+ column_list = ApiKeyDBM.get_column_and_relationship_names_()
12
+ column_details_list = ApiKeyDBM.get_column_and_relationship_names_() + ApiKeyDBM.get_sd_property_names()
13
+ form_columns = ApiKeyDBM.get_column_and_relationship_names_(include_column_pk=False)
38
14
  column_sortable_list = sqlalchemy.inspect(ApiKeyDBM).columns
39
- column_default_sort = [
40
- (ApiKeyDBM.creation_dt, True)
41
- ]
42
- column_searchable_list = [
43
- ApiKeyDBM.id,
44
- ApiKeyDBM.long_id,
15
+ column_searchable_list = SimpleMV.get_default_column_searchable_list() + [
45
16
  ApiKeyDBM.value,
46
17
  ]
47
- column_formatters = {
48
- ApiKeyDBM.creation_dt: lambda m, _: format_datetime_(m.creation_dt),
49
- ApiKeyDBM.extra_data: lambda m, a: format_json_for_preview_(m.extra_data),
50
- }
51
- column_formatters_detail = {
52
- ApiKeyDBM.creation_dt: lambda m, _: format_datetime_(m.creation_dt),
53
- ApiKeyDBM.extra_data: lambda m, a: format_json_(m.extra_data),
54
- }
@@ -7,60 +7,12 @@ from project.sqlalchemy_db_.sqlalchemy_model import OperationDBM
7
7
 
8
8
 
9
9
  class OperationMV(SimpleMV, model=OperationDBM):
10
- name = "Operation"
11
- name_plural = "Operations"
10
+ name = OperationDBM.get_cls_entity_name()
11
+ name_plural = OperationDBM.get_cls_entity_name_plural()
12
12
  icon = "fa-solid fa-gears"
13
- column_list = [
14
- OperationDBM.id,
15
- OperationDBM.long_id,
16
- OperationDBM.slug,
17
- OperationDBM.creation_dt,
18
- OperationDBM.status,
19
- OperationDBM.type,
20
- OperationDBM.marker,
21
- OperationDBM.title,
22
- OperationDBM.execution_start_dt,
23
- OperationDBM.execution_finish_dt,
24
- OperationDBM.input_data,
25
- OperationDBM.output_data,
26
- OperationDBM.error_data,
27
- OperationDBM.extra_data,
28
-
29
- OperationDBM.duration.fget.__name__,
30
- OperationDBM.duration_as_str.fget.__name__
31
- ]
32
- column_details_list = [
33
- OperationDBM.id,
34
- OperationDBM.long_id,
35
- OperationDBM.slug,
36
- OperationDBM.creation_dt,
37
- OperationDBM.status,
38
- OperationDBM.type,
39
- OperationDBM.marker,
40
- OperationDBM.title,
41
- OperationDBM.execution_start_dt,
42
- OperationDBM.execution_finish_dt,
43
- OperationDBM.input_data,
44
- OperationDBM.output_data,
45
- OperationDBM.error_data,
46
- OperationDBM.extra_data,
47
-
48
- OperationDBM.duration.fget.__name__,
49
- OperationDBM.duration_as_str.fget.__name__
50
- ]
51
- form_columns = [
52
- OperationDBM.slug,
53
- OperationDBM.status,
54
- OperationDBM.type,
55
- OperationDBM.marker,
56
- OperationDBM.title,
57
- OperationDBM.execution_start_dt,
58
- OperationDBM.execution_finish_dt,
59
- OperationDBM.input_data,
60
- OperationDBM.output_data,
61
- OperationDBM.error_data,
62
- OperationDBM.extra_data
63
- ]
13
+ column_list = OperationDBM.get_column_and_relationship_names_()
14
+ column_details_list = OperationDBM.get_column_and_relationship_names_() + OperationDBM.get_sd_property_names()
15
+ form_columns = OperationDBM.get_column_and_relationship_names_(include_column_pk=False)
64
16
  form_overrides = {
65
17
  OperationDBM.status.key: SelectField,
66
18
  OperationDBM.type.key: SelectField
@@ -76,26 +28,19 @@ class OperationMV(SimpleMV, model=OperationDBM):
76
28
  }
77
29
  }
78
30
  column_sortable_list = sqlalchemy.inspect(OperationDBM).columns
79
- column_default_sort = [
80
- (OperationDBM.creation_dt, True)
81
- ]
82
- column_searchable_list = [
83
- OperationDBM.id,
84
- OperationDBM.long_id
85
- ]
86
31
  column_formatters = {
87
- OperationDBM.creation_dt: lambda m, _: format_datetime_(m.creation_dt),
32
+ **SimpleMV.get_default_column_formatters(),
88
33
  OperationDBM.execution_start_dt: lambda m, _: format_datetime_(m.execution_start_dt),
89
34
  OperationDBM.execution_finish_dt: lambda m, _: format_datetime_(m.execution_finish_dt),
90
35
  OperationDBM.input_data: lambda m, a: format_json_for_preview_(m.input_data),
91
36
  OperationDBM.output_data: lambda m, a: format_json_for_preview_(m.output_data),
92
37
  OperationDBM.error_data: lambda m, a: format_json_for_preview_(m.error_data),
93
- OperationDBM.extra_data: lambda m, a: format_json_for_preview_(m.extra_data),
94
38
  }
95
39
  column_formatters_detail = {
96
- OperationDBM.creation_dt: lambda m, _: format_datetime_(m.creation_dt),
40
+ **SimpleMV.get_default_column_formatters_detail(),
41
+ OperationDBM.execution_start_dt: lambda m, _: format_datetime_(m.execution_start_dt),
42
+ OperationDBM.execution_finish_dt: lambda m, _: format_datetime_(m.execution_finish_dt),
97
43
  OperationDBM.input_data: lambda m, a: format_json_(m.input_data),
98
44
  OperationDBM.output_data: lambda m, a: format_json_(m.output_data),
99
45
  OperationDBM.error_data: lambda m, a: format_json_(m.error_data),
100
- OperationDBM.extra_data: lambda m, a: format_json_(m.extra_data),
101
46
  }
@@ -2,68 +2,28 @@ import sqlalchemy
2
2
  from sqladmin.fields import SelectField
3
3
 
4
4
  from project.sqladmin_.model_view.common import SimpleMV
5
- from project.sqladmin_.util.etc import format_datetime_, format_json_for_preview_, format_json_
6
5
  from project.sqlalchemy_db_.sqlalchemy_model import StoryLogDBM
7
6
 
8
7
 
9
8
  class StoryLogMV(SimpleMV, model=StoryLogDBM):
10
- name = "StoryLog"
11
- name_plural = "StoryLogs"
12
- icon = "fa-solid fa-history"
13
- column_list = [
14
- StoryLogDBM.id,
15
- StoryLogDBM.long_id,
16
- StoryLogDBM.slug,
17
- StoryLogDBM.creation_dt,
18
- StoryLogDBM.level,
19
- StoryLogDBM.type,
20
- StoryLogDBM.title,
21
- StoryLogDBM.extra_data
22
- ]
23
- column_details_list = [
24
- StoryLogDBM.id,
25
- StoryLogDBM.long_id,
26
- StoryLogDBM.slug,
27
- StoryLogDBM.creation_dt,
28
- StoryLogDBM.level,
29
- StoryLogDBM.type,
30
- StoryLogDBM.title,
31
- StoryLogDBM.extra_data
32
- ]
33
- form_columns = [
34
- StoryLogDBM.slug,
35
- StoryLogDBM.level,
36
- StoryLogDBM.type,
37
- StoryLogDBM.title,
38
- StoryLogDBM.extra_data
39
- ]
9
+ name = StoryLogDBM.get_cls_entity_name()
10
+ name_plural = StoryLogDBM.get_cls_entity_name_plural()
11
+ icon = "fa-solid fa-book"
12
+ column_list = StoryLogDBM.get_column_and_relationship_names_()
13
+ column_details_list = StoryLogDBM.get_column_and_relationship_names_() + StoryLogDBM.get_sd_property_names()
14
+ form_columns = StoryLogDBM.get_column_and_relationship_names_(include_column_pk=False)
40
15
  form_overrides = {
41
16
  StoryLogDBM.level.key: SelectField,
42
17
  StoryLogDBM.type.key: SelectField,
43
18
  }
44
19
  form_args = {
45
20
  StoryLogDBM.level.key: {
46
- "choices": [(v, v) for v in StoryLogDBM.Levels.values_list()],
21
+ "choices": [(level, level) for level in StoryLogDBM.Levels.values_list()],
47
22
  "description": f"Choose {StoryLogDBM.level.key}"
48
23
  },
49
24
  StoryLogDBM.type.key: {
50
- "choices": [(v, v) for v in StoryLogDBM.Types.values_list()],
25
+ "choices": [(level, level) for level in StoryLogDBM.Types.values_list()],
51
26
  "description": f"Choose {StoryLogDBM.type.key}"
52
27
  }
53
28
  }
54
29
  column_sortable_list = sqlalchemy.inspect(StoryLogDBM).columns
55
- column_default_sort = [
56
- (StoryLogDBM.creation_dt, True)
57
- ]
58
- column_searchable_list = [
59
- StoryLogDBM.id,
60
- StoryLogDBM.long_id,
61
- ]
62
- column_formatters = {
63
- StoryLogDBM.creation_dt: lambda m, _: format_datetime_(m.creation_dt),
64
- StoryLogDBM.extra_data: lambda m, a: format_json_for_preview_(m.extra_data),
65
- }
66
- column_formatters_detail = {
67
- StoryLogDBM.creation_dt: lambda m, _: format_datetime_(m.creation_dt),
68
- StoryLogDBM.extra_data: lambda m, a: format_json_(m.extra_data),
69
- }
@@ -1,63 +1,23 @@
1
1
  import sqlalchemy
2
2
 
3
3
  from project.sqladmin_.model_view.common import SimpleMV
4
- from project.sqladmin_.util.etc import format_datetime_, format_json_for_preview_, format_json_
5
4
  from project.sqlalchemy_db_.sqlalchemy_model import UserTokenDBM, UserDBM
6
5
 
7
6
 
8
7
  class UserTokenMV(SimpleMV, model=UserTokenDBM):
9
- name = "UserToken"
10
- name_plural = "UserTokens"
11
- icon = "fa-solid fa-fingerprint"
12
- column_list = [
13
- UserTokenDBM.id,
14
- UserTokenDBM.long_id,
15
- UserTokenDBM.slug,
16
- UserTokenDBM.creation_dt,
17
- UserTokenDBM.value,
18
- UserTokenDBM.user,
19
- UserTokenDBM.is_active,
20
- UserTokenDBM.extra_data,
21
- ]
22
- column_details_list = [
23
- UserTokenDBM.id,
24
- UserTokenDBM.long_id,
25
- UserTokenDBM.slug,
26
- UserTokenDBM.creation_dt,
27
- UserTokenDBM.value,
28
- UserTokenDBM.user,
29
- UserTokenDBM.is_active,
30
- UserTokenDBM.extra_data,
31
- ]
32
- form_columns = [
33
- UserTokenDBM.slug,
34
- UserTokenDBM.creation_dt,
35
- UserTokenDBM.value,
36
- UserTokenDBM.user,
37
- UserTokenDBM.is_active,
38
- UserTokenDBM.extra_data
39
- ]
8
+ name = UserTokenDBM.get_cls_entity_name()
9
+ name_plural = UserTokenDBM.get_cls_entity_name_plural()
10
+ icon = "fa-solid fa-shield-halved"
11
+ column_list = UserTokenDBM.get_column_and_relationship_names_()
12
+ column_details_list = UserTokenDBM.get_column_and_relationship_names_() + UserTokenDBM.get_sd_property_names()
13
+ form_columns = UserTokenDBM.get_column_and_relationship_names_(include_column_pk=False)
40
14
  column_sortable_list = sqlalchemy.inspect(UserTokenDBM).columns
41
- column_default_sort = [
42
- (UserTokenDBM.creation_dt, True)
43
- ]
44
- column_searchable_list = [
45
- UserTokenDBM.id,
46
- UserTokenDBM.long_id,
15
+ column_searchable_list = SimpleMV.get_default_column_searchable_list() + [
47
16
  UserTokenDBM.value,
48
17
  ]
49
- column_formatters = {
50
- UserTokenDBM.creation_dt: lambda m, _: format_datetime_(m.creation_dt),
51
- UserTokenDBM.extra_data: lambda m, a: format_json_for_preview_(m.extra_data),
52
- }
53
- column_formatters_detail = {
54
- UserTokenDBM.creation_dt: lambda m, _: format_datetime_(m.creation_dt),
55
- UserTokenDBM.extra_data: lambda m, a: format_json_(m.extra_data),
56
- }
57
18
  form_ajax_refs = {
58
19
  UserTokenDBM.user.key: {
59
- "fields": [UserDBM.id.key, UserDBM.email.key, UserDBM.username.key],
60
- "placeholder": "Search by id or email",
20
+ "fields": [UserDBM.id.key],
61
21
  "minimum_input_length": 1,
62
22
  "page_size": 10,
63
23
  }
@@ -4,83 +4,32 @@ import sqlalchemy
4
4
  from sqladmin.fields import SelectField
5
5
 
6
6
  from project.sqladmin_.model_view import SimpleMV
7
- from project.sqladmin_.util.etc import format_datetime_, format_json_for_preview_, format_json_
8
7
  from project.sqlalchemy_db_.sqlalchemy_model import VerificationCodeDBM, UserDBM
9
8
 
10
9
 
11
10
  class VerificationCodeMV(SimpleMV, model=VerificationCodeDBM):
12
- name = "VerificationCode"
13
- name_plural = "VerificationCodes"
14
- icon = "fa-solid fa-envelope"
15
- column_list = [
16
- VerificationCodeDBM.id,
17
- VerificationCodeDBM.long_id,
18
- VerificationCodeDBM.slug,
19
- VerificationCodeDBM.creation_dt,
20
- VerificationCodeDBM.type,
21
- VerificationCodeDBM.value,
22
- VerificationCodeDBM.recipient,
23
- VerificationCodeDBM.user,
24
- VerificationCodeDBM.is_active,
25
- VerificationCodeDBM.detail_data,
26
- VerificationCodeDBM.extra_data
27
- ]
28
- column_details_list = [
29
- VerificationCodeDBM.id,
30
- VerificationCodeDBM.long_id,
31
- VerificationCodeDBM.slug,
32
- VerificationCodeDBM.creation_dt,
33
- VerificationCodeDBM.type,
34
- VerificationCodeDBM.value,
35
- VerificationCodeDBM.recipient,
36
- VerificationCodeDBM.user,
37
- VerificationCodeDBM.is_active,
38
- VerificationCodeDBM.detail_data,
39
- VerificationCodeDBM.extra_data
40
- ]
41
- form_columns = [
42
- VerificationCodeDBM.slug,
43
- VerificationCodeDBM.type,
44
- VerificationCodeDBM.value,
45
- VerificationCodeDBM.recipient,
46
- VerificationCodeDBM.user,
47
- VerificationCodeDBM.is_active,
48
- VerificationCodeDBM.detail_data,
49
- VerificationCodeDBM.extra_data
50
- ]
11
+ name = VerificationCodeDBM.get_cls_entity_name()
12
+ name_plural = VerificationCodeDBM.get_cls_entity_name_plural()
13
+ icon = "fa-solid fa-shield"
14
+ column_list = VerificationCodeDBM.get_column_and_relationship_names_()
15
+ column_details_list = VerificationCodeDBM.get_column_and_relationship_names_() + VerificationCodeDBM.get_sd_property_names()
16
+ form_columns = VerificationCodeDBM.get_column_and_relationship_names_(include_column_pk=False)
51
17
  form_overrides = {
52
18
  VerificationCodeDBM.type.key: SelectField
53
19
  }
54
20
  form_args = {
55
21
  VerificationCodeDBM.type.key: {
56
- "choices": [(v, v) for v in VerificationCodeDBM.Types.values_list()],
22
+ "choices": [(status, status) for status in VerificationCodeDBM.Types.values_list()],
57
23
  "description": f"Choose {VerificationCodeDBM.type.key}"
58
24
  }
59
25
  }
60
26
  column_sortable_list = sqlalchemy.inspect(VerificationCodeDBM).columns
61
- column_default_sort = [
62
- (VerificationCodeDBM.creation_dt, True)
63
- ]
64
- column_searchable_list = [
65
- VerificationCodeDBM.id,
66
- VerificationCodeDBM.long_id,
67
- VerificationCodeDBM.value,
27
+ column_searchable_list = SimpleMV.get_default_column_searchable_list() + [
68
28
  VerificationCodeDBM.recipient
69
29
  ]
70
- column_formatters = {
71
- VerificationCodeDBM.creation_dt: lambda m, _: format_datetime_(m.creation_dt),
72
- VerificationCodeDBM.detail_data: lambda m, _: format_json_for_preview_(m.detail_data),
73
- VerificationCodeDBM.extra_data: lambda m, _: format_json_for_preview_(m.extra_data)
74
- }
75
- column_formatters_detail = {
76
- VerificationCodeDBM.creation_dt: lambda m, _: format_datetime_(m.creation_dt),
77
- VerificationCodeDBM.detail_data: lambda m, _: format_json_for_preview_(m.detail_data),
78
- VerificationCodeDBM.extra_data: lambda m, a: format_json_(m.extra_data),
79
- }
80
30
  form_ajax_refs = {
81
31
  VerificationCodeDBM.user.key: {
82
32
  "fields": [UserDBM.id.key, UserDBM.email.key, UserDBM.username.key],
83
- "placeholder": "Search by id or email",
84
33
  "minimum_input_length": 1,
85
34
  "page_size": 10,
86
35
  }
@@ -1,4 +1,4 @@
1
- from arpakitlib.ar_sqlalchemy_util import get_string_info_from_declarative_base, get_string_info_from_declarative_base_2
1
+ from arpakitlib.ar_sqlalchemy_util import get_string_info_from_declarative_base_2
2
2
 
3
3
  from project.sqlalchemy_db_.sqlalchemy_model.api_key import ApiKeyDBM
4
4
  from project.sqlalchemy_db_.sqlalchemy_model.common import SimpleDBM
@@ -9,6 +9,7 @@ from sqlalchemy.orm import mapped_column, Mapped, validates
9
9
 
10
10
  from arpakitlib.ar_datetime_util import now_utc_dt
11
11
  from arpakitlib.ar_sqlalchemy_util import get_string_info_from_declarative_base, BaseDBM
12
+ from arpakitlib.ar_str_util import make_none_if_blank
12
13
 
13
14
 
14
15
  def generate_default_long_id() -> str:
@@ -45,6 +46,7 @@ class SimpleDBM(BaseDBM):
45
46
  uuid = "uuid"
46
47
  slug = "slug"
47
48
  creation_dt = "creation_dt"
49
+ private_comment = "private_comment"
48
50
  detail_data = "detail_data"
49
51
  extra_data = "extra_data"
50
52
 
@@ -53,7 +55,7 @@ class SimpleDBM(BaseDBM):
53
55
  nullable=False,
54
56
  primary_key=True,
55
57
  autoincrement=True,
56
- sort_order=-103,
58
+ sort_order=-104,
57
59
  )
58
60
  long_id: Mapped[str] = mapped_column(
59
61
  sqlalchemy.TEXT,
@@ -61,7 +63,7 @@ class SimpleDBM(BaseDBM):
61
63
  unique=True,
62
64
  insert_default=generate_default_long_id,
63
65
  server_default=func.gen_random_uuid(),
64
- sort_order=-102,
66
+ sort_order=-103,
65
67
  )
66
68
  uuid: Mapped[sqlalchemy.dialects.postgresql.UUID] = mapped_column(
67
69
  sqlalchemy.UUID(as_uuid=True),
@@ -85,7 +87,11 @@ class SimpleDBM(BaseDBM):
85
87
  server_default=func.now(),
86
88
  sort_order=-100,
87
89
  )
88
- extra_data: Mapped[dict[str, Any]] = mapped_column(
90
+ private_comment: Mapped[str | None] = mapped_column(
91
+ sqlalchemy.TEXT,
92
+ nullable=True,
93
+ )
94
+ detail_data: Mapped[dict[str, Any]] = mapped_column(
89
95
  sqlalchemy.JSON,
90
96
  nullable=False,
91
97
  index=False,
@@ -93,6 +99,14 @@ class SimpleDBM(BaseDBM):
93
99
  server_default="{}",
94
100
  sort_order=1000,
95
101
  )
102
+ extra_data: Mapped[dict[str, Any]] = mapped_column(
103
+ sqlalchemy.JSON,
104
+ nullable=False,
105
+ index=False,
106
+ insert_default={},
107
+ server_default="{}",
108
+ sort_order=1001,
109
+ )
96
110
 
97
111
  def __repr__(self) -> str:
98
112
  parts = [f"id={self.id}"]
@@ -100,6 +114,8 @@ class SimpleDBM(BaseDBM):
100
114
  parts.append(f"slug={self.slug}")
101
115
  return f"{self.entity_name} ({', '.join(parts)})"
102
116
 
117
+ # ---validators---
118
+
103
119
  @validates("slug")
104
120
  def _validate_slug(self, key, value, *args, **kwargs):
105
121
  if value is None:
@@ -111,6 +127,23 @@ class SimpleDBM(BaseDBM):
111
127
  raise ValueError(f"{key=}, {value=}, value contains spaces")
112
128
  return value
113
129
 
130
+ @validates("private_comment")
131
+ def _validate_private_comment(self, key, value, *args, **kwargs):
132
+ if value is None:
133
+ return None
134
+ if not isinstance(value, str):
135
+ raise ValueError(f"{key=}, {value=}, value is not str")
136
+ value = make_none_if_blank(value.strip())
137
+ return value
138
+
139
+ @validates("detail_data")
140
+ def _validate_detail_data(self, key, value, *args, **kwargs):
141
+ if value is None:
142
+ value = {}
143
+ if not isinstance(value, dict):
144
+ raise ValueError(f"{key=}, {value=}, value is not dict")
145
+ return value
146
+
114
147
  @validates("extra_data")
115
148
  def _validate_extra_data(self, key, value, *args, **kwargs):
116
149
  if value is None:
@@ -119,10 +152,16 @@ class SimpleDBM(BaseDBM):
119
152
  raise ValueError(f"{key=}, {value=}, value is not dict")
120
153
  return value
121
154
 
155
+ # ---more---
156
+
122
157
  @property
123
158
  def id_and_long_id(self) -> str:
124
159
  return f"{self.id}--{self.long_id}"
125
160
 
161
+ @property
162
+ def id_and_long_id_and_uuid(self) -> str:
163
+ return f"{self.id}--{self.long_id}--{str(self.uuid)}"
164
+
126
165
  @classmethod
127
166
  def get_cls_entity_name(cls) -> str:
128
167
  return cls.__name__.removesuffix("DBM")
@@ -145,13 +184,21 @@ class SimpleDBM(BaseDBM):
145
184
 
146
185
  # ---SDP---
147
186
 
187
+ @property
188
+ def sdp_entity_name(self) -> str:
189
+ return self.entity_name
190
+
191
+ @property
192
+ def sdp_entity_name_plural(self) -> str:
193
+ return self.entity_name_plural
194
+
148
195
  @property
149
196
  def sdp_id_and_long_id(self) -> str:
150
197
  return self.id_and_long_id
151
198
 
152
199
  @property
153
- def sdp_entity_name(self) -> str:
154
- return self.entity_name
200
+ def sdp_id_and_long_id_and_uuid(self) -> str:
201
+ return self.id_and_long_id_and_uuid
155
202
 
156
203
 
157
204
  def get_simple_dbm_class() -> type[SimpleDBM]:
@@ -30,7 +30,7 @@ class OperationDBM(SimpleDBM):
30
30
  raise_fake_error_ = "raise_fake_error"
31
31
 
32
32
  class Markers(Enumeration):
33
- nothing = "nothing"
33
+ pass
34
34
 
35
35
  status: Mapped[str] = mapped_column(
36
36
  sqlalchemy.TEXT,
@@ -180,48 +180,56 @@ class OperationDBM(SimpleDBM):
180
180
  return None
181
181
  return self.execution_finish_dt - self.execution_start_dt
182
182
 
183
+ # ---SDP---
184
+
183
185
  @property
184
- def duration_as_str(self) -> str | None:
185
- if self.duration is None:
186
- return None
187
- return str(self.duration)
186
+ def sdp_allowed_statuses(self) -> list[str]:
187
+ return self.Statuses.values_list()
188
188
 
189
189
  @property
190
- def duration_total_seconds(self) -> float | None:
191
- if self.duration is None:
192
- return None
193
- return self.duration.total_seconds()
190
+ def sdp_allowed_types(self) -> list[str]:
191
+ return self.Types.values_list()
194
192
 
195
- # ---SDP---
193
+ @property
194
+ def sdp_allowed_markers(self) -> list[str]:
195
+ return self.Markers.values_list()
196
+
197
+ @property
198
+ def sdp_has_input_data(self) -> bool:
199
+ return bool(self.input_data)
200
+
201
+ @property
202
+ def sdp_has_output_data(self) -> bool:
203
+ return bool(self.output_data)
204
+
205
+ @property
206
+ def sdp_has_error_data(self) -> bool:
207
+ return bool(self.error_data)
196
208
 
197
209
  @property
198
210
  def sdp_duration(self) -> timedelta | None:
199
- """
200
- При использовании у данной модели .simple_dict данное свойство будет представлено как поле.
201
- То есть префикс sdp_ и даёт этот бонус.
202
- """
203
211
  return self.duration
204
212
 
205
213
  @property
206
214
  def sdp_duration_as_str(self) -> str | None:
207
- """
208
- При использовании у данной модели .simple_dict данное свойство будет представлено как поле.
209
- То есть префикс sdp_ и даёт этот бонус.
210
- """
211
- return self.duration_as_str
215
+ if self.duration is None:
216
+ return None
217
+ return str(self.duration)
212
218
 
213
219
  @property
214
220
  def sdp_duration_total_seconds(self) -> float | None:
215
- """
216
- При использовании у данной модели .simple_dict данное свойство будет представлено как поле.
217
- То есть префикс sdp_ и даёт этот бонус.
218
- """
219
- return self.duration_total_seconds
221
+ if self.duration is None:
222
+ return None
223
+ return self.duration.total_seconds()
220
224
 
221
225
  @property
222
- def sdp_allowed_statuses(self) -> list[str]:
223
- return self.Statuses.values_list()
226
+ def sdp_duration_total_minutes(self) -> float | None:
227
+ if self.duration is None:
228
+ return None
229
+ return self.duration.total_seconds() / 60
224
230
 
225
231
  @property
226
- def sdp_allowed_types(self) -> list[str]:
227
- return self.Types.values_list()
232
+ def sdp_duration_total_hours(self) -> float | None:
233
+ if self.duration is None:
234
+ return None
235
+ return self.duration.total_seconds() / 60 / 60
@@ -75,6 +75,8 @@ class StoryLogDBM(SimpleDBM):
75
75
  value = make_none_if_blank(value.strip())
76
76
  return value
77
77
 
78
+ # ---more---
79
+
78
80
  # ---SDP---
79
81
 
80
82
  @property
@@ -60,6 +60,8 @@ class UserTokenDBM(SimpleDBM):
60
60
  ]
61
61
  return f"{self.entity_name} ({', '.join(parts)})"
62
62
 
63
+ # ---validators---
64
+
63
65
  @validates("value")
64
66
  def _validate_value(self, key, value, *args, **kwargs):
65
67
  if not isinstance(value, str):
@@ -68,3 +70,7 @@ class UserTokenDBM(SimpleDBM):
68
70
  if not value:
69
71
  raise ValueError(f"{key=}, {value=}, value is empty")
70
72
  return value
73
+
74
+ # ---more---
75
+
76
+ # ---SDP---
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from random import randint
4
- from typing import TYPE_CHECKING, Any
4
+ from typing import TYPE_CHECKING
5
5
 
6
6
  import sqlalchemy
7
7
  from sqlalchemy.orm import Mapped, mapped_column, relationship, validates
@@ -55,13 +55,6 @@ class VerificationCodeDBM(SimpleDBM):
55
55
  insert_default=True,
56
56
  server_default="true"
57
57
  )
58
- detail_data: Mapped[dict[str, Any]] = mapped_column(
59
- sqlalchemy.JSON,
60
- nullable=False,
61
- index=False,
62
- insert_default={},
63
- server_default="{}",
64
- )
65
58
 
66
59
  # one to many
67
60
  user: Mapped[UserDBM | None] = relationship(
@@ -82,6 +75,8 @@ class VerificationCodeDBM(SimpleDBM):
82
75
  parts.append(f"user_id={self.user_id}")
83
76
  return f"{self.entity_name} ({', '.join(parts)})"
84
77
 
78
+ # ---validators---
79
+
85
80
  @validates("type")
86
81
  def _validate_type(self, key, value, *args, **kwargs):
87
82
  if not isinstance(value, str):
@@ -102,13 +97,9 @@ class VerificationCodeDBM(SimpleDBM):
102
97
  value = make_none_if_blank(value.strip())
103
98
  return value
104
99
 
105
- @validates("detail_data")
106
- def _validate_detail_data(self, key, value, *args, **kwargs):
107
- if value is None:
108
- value = {}
109
- if not isinstance(value, dict):
110
- raise ValueError(f"{key=}, {value=}, value is not dict")
111
- return value
100
+ # ---more---
101
+
102
+ # ---SDP---
112
103
 
113
104
  @property
114
105
  def sdp_allowed_types(self) -> list[str]:
@@ -0,0 +1,91 @@
1
+ import datetime as dt
2
+ from typing import Any, Optional
3
+
4
+ from pydantic import BaseModel, Field
5
+ from sqlalchemy import inspect
6
+ from sqlalchemy.orm import ColumnProperty
7
+ from sqlalchemy.sql.sqltypes import (
8
+ Boolean, Integer, BigInteger, SmallInteger,
9
+ String, Text, Unicode, UnicodeText,
10
+ DateTime, Date, Time,
11
+ Float, Numeric, DECIMAL, LargeBinary, JSON
12
+ )
13
+
14
+ _SQLA_TYPE_MAP = {
15
+ Boolean: bool,
16
+ Integer: int,
17
+ BigInteger: int,
18
+ SmallInteger: int,
19
+ Float: float,
20
+ Numeric: float,
21
+ DECIMAL: float,
22
+ String: str,
23
+ Unicode: str,
24
+ Text: str,
25
+ UnicodeText: str,
26
+ LargeBinary: bytes,
27
+ JSON: dict,
28
+ DateTime: dt.datetime,
29
+ Date: dt.date,
30
+ Time: dt.time,
31
+ }
32
+
33
+
34
+ def _python_type_from_col(col) -> type | str:
35
+ try:
36
+ return col.type.python_type
37
+ except Exception:
38
+ for sa_t, py_t in _SQLA_TYPE_MAP.items():
39
+ if isinstance(col.type, sa_t):
40
+ return py_t
41
+ return Any
42
+
43
+
44
+ def pydantic_schema_from_sqlalchemy_model(
45
+ sqlalchemy_model: type,
46
+ *,
47
+ name: str | None = None,
48
+ base_model: type[BaseModel] = BaseModel,
49
+ include_defaults: bool = False,
50
+ exclude_column_names: list[str] | None = None,
51
+ ) -> type[BaseModel]:
52
+ """
53
+ Генерирует Pydantic-модель только из колонок SQLAlchemy-модели.
54
+ - include_defaults: добавлять ли default/server_default.
55
+ - exclude_column_names: список имён колонок, которые нужно пропустить.
56
+ """
57
+ mapper = inspect(sqlalchemy_model).mapper
58
+ model_name = name or f"{sqlalchemy_model.__name__}Schema"
59
+
60
+ annotations: dict[str, Any] = {}
61
+ attrs: dict[str, Any] = {}
62
+ exclude_column_names = set(exclude_column_names or [])
63
+
64
+ for prop in mapper.attrs:
65
+ if not isinstance(prop, ColumnProperty):
66
+ continue
67
+ if prop.key in exclude_column_names:
68
+ continue
69
+
70
+ col = prop.columns[0]
71
+ py_t = _python_type_from_col(col)
72
+
73
+ # Аннотация типа
74
+ if col.nullable:
75
+ annotations[prop.key] = Optional[py_t] # type: ignore[name-defined]
76
+ else:
77
+ annotations[prop.key] = py_t
78
+
79
+ # Если нужно — добавляем дефолт
80
+ if include_defaults:
81
+ default_value = None
82
+ if col.default is not None and col.default.is_scalar:
83
+ default_value = col.default.arg
84
+ elif col.server_default is not None and getattr(col.server_default.arg, "text", None):
85
+ default_value = col.server_default.arg.text
86
+
87
+ if default_value is not None:
88
+ attrs[prop.key] = Field(default=default_value)
89
+
90
+ attrs["__annotations__"] = annotations
91
+ return type(model_name, (base_model,), attrs)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: arpakitlib
3
- Version: 1.8.218
3
+ Version: 1.8.220
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=uk-Wu_6L9MZFmxQgc-PKw5-qdmdYS_Nra2I9KCu6ZQA,98
11
+ arpakitlib/_arpakit_project_template_v_5/arpakitlib_project_template_info.json,sha256=gZOXWHexAQHHW5DKdaqdCpdaJx-0obJc76fydlyb-wk,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
@@ -168,7 +168,7 @@ arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/common.p
168
168
  arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/user.py,sha256=AvYwqaowd1V_6VQjrIGxt8SwqNEgmirLcHbtSHPwWmQ,1080
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
- arpakitlib/_arpakit_project_template_v_5/project/api/schema/util/schema_from_dbm.py,sha256=nJ2YNRzcydXDJG8V5_MiI3ODi140D_itayjk-caJe0o,319
171
+ arpakitlib/_arpakit_project_template_v_5/project/api/schema/util/create_obj_schema_from_dbm.py,sha256=7HizltD9MyK1nltQQHAjy69TCOuFDkkgtFJDr7DjLxU,331
172
172
  arpakitlib/_arpakit_project_template_v_5/project/api/start_api.py,sha256=P5KMtYXujQUP2uAAKgUFyCxG99Fj2vfNf1ZEm8eFH80,532
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
@@ -197,7 +197,7 @@ arpakitlib/_arpakit_project_template_v_5/project/operation_execution/__init__.py
197
197
  arpakitlib/_arpakit_project_template_v_5/project/operation_execution/const.py,sha256=dcvj5C9E2F2KCsGZPBBncQf_EvVJAC1qQgnyD8P4ZEw,6
198
198
  arpakitlib/_arpakit_project_template_v_5/project/operation_execution/operation_executor_worker.py,sha256=ygGavnIOrOqjtTsi1nhZXKGwwtjTaHbNT9KWZaTDLI4,12967
199
199
  arpakitlib/_arpakit_project_template_v_5/project/operation_execution/scheduled_operation_creator_worker.py,sha256=WzZC6r0GVSwOpphsxqpRZIdeewK_wzi3YshjLOutYGA,4524
200
- arpakitlib/_arpakit_project_template_v_5/project/operation_execution/scheduled_operations.py,sha256=4Wo-tuC2AbeCYTa5_snMJ2EkXwASCe08vXNnM5feJos,1607
200
+ arpakitlib/_arpakit_project_template_v_5/project/operation_execution/scheduled_operations.py,sha256=zi1FOBBYV99hQHAF4mQZ4I93pN6Q8nm5RIhSjsEpXGc,1607
201
201
  arpakitlib/_arpakit_project_template_v_5/project/operation_execution/util.py,sha256=sqHF2AU5Y5IurYHcIH2bu3-JbS1amLO3GD13Zvy8epM,923
202
202
  arpakitlib/_arpakit_project_template_v_5/project/resource/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
203
203
  arpakitlib/_arpakit_project_template_v_5/project/resource/static/1,sha256=IIO7Wvjwlr2-LPSQ7Y8O35hcI6t0_s8zqITDxkYCO8I,11
@@ -229,7 +229,7 @@ arpakitlib/_arpakit_project_template_v_5/project/resource/templates/simple_email
229
229
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
230
230
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_1.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
231
231
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_2.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
232
- arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_3.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
232
+ arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_3.py,sha256=tcva9-NB0irswjg6RirZ9-pmckuZwoAr8-DUiPB2ASI,424
233
233
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_4.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
234
234
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_5.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
235
235
  arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_6.py,sha256=xKSp7tIBu3Ffp_kgJkwVtdam3BcoFZ44JPVHoRRaP0E,163
@@ -248,28 +248,28 @@ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/admin_authorize.py,sh
248
248
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/asgi.py,sha256=DRlRPkcOGXOccfP73oKEXolZTsc5VWdQgEG-qoW03ms,99
249
249
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/create_sqladmin_app.py,sha256=JGCHgqJJvAjpc8xnbXPqCeUiLeKO7eo6OA6uPYzzqlk,1308
250
250
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/event.py,sha256=LjAUYNlsX9Sj_QLMzYuTQbbYYbIMHhbsSjTXt-G7lOE,849
251
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/__init__.py,sha256=aKX6k2bEVvfXa9dATYts-sUoWgf4MV3H_PiiUceejr4,596
252
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/api_key.py,sha256=VTpepKLCKrPnftGD-8Ibp75S0dwUrLlUytRfcXDDcKg,1597
251
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/__init__.py,sha256=upngi5hsrv6f5M-_R0r_DfERl8jzTnZ6VOum71xiGcY,595
252
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/api_key.py,sha256=AfWtDIf0Z7GVEsnGw921u3VbkxhFIffR8u8MfspldSs,750
253
253
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/common.py,sha256=ajqXQft-RsyVCGGf23_8c38Wf-B6KDYWv4wAGR1qYm4,4475
254
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/operation.py,sha256=IqW9eh0u3-WFkE1oA3yjEboUW2F2zF4cKsp4_FNy2RE,3746
255
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/story_log.py,sha256=KTyvMty9bozjnC0bSDoTtK1H4LTFfbX_MwqP72Ip5D0,2194
254
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/operation.py,sha256=vf-j9QT_eHNevNy3Pbq6U2Wc7IADDM4tgdNwYd5nQ5A,2362
255
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/story_log.py,sha256=-GEfclV8sccXukxn9A1KDE1_CyBarA7EtGue8rgfn8w,1221
256
256
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user.py,sha256=AhK-2YocK1dM2wMxX_xF0qnsMiI5Pu0Arj5yfDe8Noo,2669
257
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user_token.py,sha256=pyeyDTg4rss8-67hIE3-SQlAvNfje6HazuaVnyFBpN8,2054
258
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/verification_code.py,sha256=CDJQvzdLLxE08XNWvII2r7YAy4fYbyr9FmY-9o4V2Qo,3208
257
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user_token.py,sha256=i3oqyAAtC7pYhuCGEiBxNeBjLQxAGVtiNwa3vrZE1v0,982
258
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/verification_code.py,sha256=adAuoDqOuvbzJfndZPwJ7y_uGcp6jequI9G9kzoDaDg,1490
259
259
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/start_sqladmin.py,sha256=jaAOq7Kf7HYziJslWbjqzr41kX4dJ9CXDPtMXj8rWok,384
260
260
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
261
261
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/util/etc.py,sha256=jm65ZB0K8e6WpgcL2Y6pxcIuQjioIyMtBIOOFbbWfgk,1070
262
262
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
263
263
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/const.py,sha256=dcvj5C9E2F2KCsGZPBBncQf_EvVJAC1qQgnyD8P4ZEw,6
264
264
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_db.py,sha256=1y3FaMFzm_5UM2poqtBve_UP_mh1vjs--krq6yO8PsA,742
265
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/__init__.py,sha256=7PQqeYThEBXRrXwJZjuH7yAFu25DVr_IneuMwEF3kUE,731
265
+ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/__init__.py,sha256=UkP3s2W_9Xk3ugOdgDXJFDDlJfuroBqrPusaDbwe4o8,692
266
266
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/api_key.py,sha256=2X6VPkf1TKq-0319J0tL-rPMvgmkBCjim3Si1dZboMQ,1969
267
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/common.py,sha256=ynp36o48B_HNMJSAc-mw40LzhoFLSXyOWw3JOPc8gKo,4446
268
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/operation.py,sha256=-7uzlux8B7wtqhSd4b_06M40yTDySPIngm3Cwun2lSA,7378
269
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/story_log.py,sha256=CiNec-x5_z0Pr5Mt-RZXJ1tKJMRn_TAKIaOioG4NK7U,2489
267
+ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/common.py,sha256=NsZbGGJvsn1IgfUQ9J4_6qBQyNBADDmt2Q8waRePD0c,5851
268
+ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/operation.py,sha256=6mDtD20H0bQEoSwReLPzaqNp6vLHgOQ7D1DD7KC7zIU,7111
269
+ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/story_log.py,sha256=Xou8XvEGQfLuEHH5RKdq6pXCZWMhmtyshQvvohT-Go8,2507
270
270
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user.py,sha256=22TE8y2Vm9byLLkIE6RVAMa29d9ILCVg1e1QYi4ONIQ,7898
271
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user_token.py,sha256=dCCiRZcOiUpqd-DZZ-A6tVM0PzJwa030KFOzPXNyM7A,1929
272
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/verification_code.py,sha256=3fNkUwWEdt6l3Snwr_ktMqzTeo2hm04hPlznCLr2izg,3548
271
+ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user_token.py,sha256=Yy4XZLHJqNEt_SlQOcVCDwHqxpuBwtOmyOfGKbYqKeo,1988
272
+ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/verification_code.py,sha256=xM5e9C8ELI1RJBAaSXZPn9Qpwl4DT2TgRvbYOxsKZsM,3137
273
273
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
274
274
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/util/execute_func_with_story_log.py,sha256=HrDlG8Y1gbMNVIuDHvCndXbnp8vxc8T8l-_XBVn7zR8,6091
275
275
  arpakitlib/_arpakit_project_template_v_5/project/test_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -416,8 +416,9 @@ arpakitlib/ar_str_util.py,sha256=2lGpnXDf2h1cBZpVf5i1tX_HCv5iBd6IGnrCw4QWWlY,435
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
418
  arpakitlib/clone_pydantic_model_fields.py,sha256=Gn9_AIjKknN1eIYK_xH_cMyff3hjOpfwRqs583-rnJs,1167
419
- arpakitlib-1.8.218.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
420
- arpakitlib-1.8.218.dist-info/METADATA,sha256=NlgCzO5BIIrf3lgE7zpMTs6MNYwh3YkxGtW7R1HQ1vA,3741
421
- arpakitlib-1.8.218.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
422
- arpakitlib-1.8.218.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
423
- arpakitlib-1.8.218.dist-info/RECORD,,
419
+ arpakitlib/pydantic_schema_from_sqlalchemy_model.py,sha256=bjLNfeJRZonvVl7pnczwL8OzxbIGawulp30K-xYY7yA,2833
420
+ arpakitlib-1.8.220.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
421
+ arpakitlib-1.8.220.dist-info/METADATA,sha256=CZDGfdCQIX96yHZbsEbkmS7rA4kbjdORbcNV8qfugN0,3741
422
+ arpakitlib-1.8.220.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
423
+ arpakitlib-1.8.220.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
424
+ arpakitlib-1.8.220.dist-info/RECORD,,