arpakitlib 1.8.141__py3-none-any.whl → 1.8.142__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 (23) hide show
  1. arpakitlib/_arpakit_project_template_v_5/command/start_api.py +2 -19
  2. arpakitlib/_arpakit_project_template_v_5/command/start_api_for_prod.py +2 -19
  3. arpakitlib/_arpakit_project_template_v_5/example.env +14 -0
  4. arpakitlib/_arpakit_project_template_v_5/project/api/before_start_api.py +49 -0
  5. arpakitlib/_arpakit_project_template_v_5/project/api/event.py +0 -37
  6. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/main_router.py +22 -1
  7. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/make_test_data_2.py +35 -0
  8. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/make_test_data_3.py +35 -0
  9. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/make_test_data_4.py +35 -0
  10. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/make_test_data_5.py +35 -0
  11. arpakitlib/_arpakit_project_template_v_5/project/api/start_api.py +7 -12
  12. arpakitlib/_arpakit_project_template_v_5/project/core/settings.py +4 -0
  13. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/admin_authorize.py +33 -23
  14. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/api_key.py +0 -1
  15. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user.py +0 -1
  16. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user_token.py +0 -1
  17. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/verification_code.py +0 -1
  18. {arpakitlib-1.8.141.dist-info → arpakitlib-1.8.142.dist-info}/METADATA +1 -1
  19. {arpakitlib-1.8.141.dist-info → arpakitlib-1.8.142.dist-info}/RECORD +22 -18
  20. arpakitlib/_arpakit_project_template_v_5/command/start_api_with_reload.py +0 -26
  21. {arpakitlib-1.8.141.dist-info → arpakitlib-1.8.142.dist-info}/LICENSE +0 -0
  22. {arpakitlib-1.8.141.dist-info → arpakitlib-1.8.142.dist-info}/WHEEL +0 -0
  23. {arpakitlib-1.8.141.dist-info → arpakitlib-1.8.142.dist-info}/entry_points.txt +0 -0
@@ -1,25 +1,8 @@
1
- import uvicorn
2
-
3
- from arpakitlib.ar_base_worker_util import safe_run_worker_in_background, SafeRunInBackgroundModes
4
- from project.core.settings import get_cached_settings
5
- from project.core.util import setup_logging
6
- from project.operation_execution.scheduled_operation_creator_worker import create_scheduled_operation_creator_worker
1
+ from project.api.start_api import start_api
7
2
 
8
3
 
9
4
  def __command():
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
- )
16
- uvicorn.run(
17
- "project.api.asgi:app",
18
- port=get_cached_settings().api_port,
19
- host="localhost",
20
- workers=get_cached_settings().api_workers,
21
- reload=False
22
- )
5
+ start_api()
23
6
 
24
7
 
25
8
  if __name__ == '__main__':
@@ -1,25 +1,8 @@
1
- import uvicorn
2
-
3
- from arpakitlib.ar_base_worker_util import safe_run_worker_in_background, SafeRunInBackgroundModes
4
- from project.core.settings import get_cached_settings
5
- from project.core.util import setup_logging
6
- from project.operation_execution.scheduled_operation_creator_worker import create_scheduled_operation_creator_worker
1
+ from project.api.start_api import start_api
7
2
 
8
3
 
9
4
  def __command():
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
- )
16
- uvicorn.run(
17
- app="project.api.asgi:app",
18
- host="127.0.0.1",
19
- port=get_cached_settings().api_port,
20
- reload=False,
21
- workers=get_cached_settings().api_workers
22
- )
5
+ start_api()
23
6
 
24
7
 
25
8
  if __name__ == '__main__':
@@ -9,12 +9,17 @@
9
9
  # sqlalchemy_async_db_url=
10
10
  # sqlalchemy_db_echo=
11
11
  # api_port=
12
+ # api_host=
13
+ # api_reload=
12
14
  # api_init_sqlalchemy_db=
13
15
  # api_init_json_db=
14
16
  # api_correct_api_keys=
15
17
  # api_enable_sqladmin=
16
18
  # api_start_operation_executor_worker=
17
19
  # api_start_scheduled_operation_creator_worker=
20
+ # api_version=
21
+ # api_create_first_data=
22
+ # api_workers=
18
23
  # sqladmin_secret_key=
19
24
  # sqladmin_authorize_keys=
20
25
  # sqladmin_port=
@@ -33,6 +38,7 @@
33
38
  # tg_bot_start_scheduled_operation_creator_worker=
34
39
  # tg_bot_command_passwd=
35
40
  # tg_bot_admin_tg_ids=
41
+ # tg_bot_set_commands=
36
42
  # var_dirpath=
37
43
  # log_filepath=
38
44
  # cache_dirpath=
@@ -40,3 +46,11 @@
40
46
  # dump_dirpath=
41
47
  # json_db_dirpath=
42
48
  # local_timezone=
49
+ # email_smtp_user=
50
+ # email_smtp_password=
51
+ # email_smtp_port=
52
+ # email_smtp_hostname=
53
+ # openai_api_key=
54
+ # openai_api_base_url=
55
+ # tg_bot_notifier_token=
56
+ # tg_bot_notifier_proxy_url=
@@ -0,0 +1,49 @@
1
+ import logging
2
+
3
+ from arpakitlib.ar_base_worker_util import safe_run_worker_in_background, SafeRunInBackgroundModes
4
+ from project.api.create_first_data import create_first_data_for_api
5
+ from project.core.cache_file_storage_in_dir import get_cached_cache_file_storage_in_dir
6
+ from project.core.dump_file_storage_in_dir import get_cached_dump_file_storage_in_dir
7
+ from project.core.media_file_storage_in_dir import get_cached_media_file_storage_in_dir
8
+ from project.core.settings import get_cached_settings
9
+ from project.json_db.json_db import get_cached_json_db
10
+ from project.operation_execution.scheduled_operation_creator_worker import create_scheduled_operation_creator_worker
11
+ from project.sqlalchemy_db_.sqlalchemy_db import get_cached_sqlalchemy_db
12
+
13
+ _logger = logging.getLogger(__name__)
14
+
15
+
16
+ def before_start_api():
17
+ _logger.info("start")
18
+
19
+ if get_cached_media_file_storage_in_dir() is not None:
20
+ get_cached_media_file_storage_in_dir().init()
21
+
22
+ if get_cached_cache_file_storage_in_dir() is not None:
23
+ get_cached_cache_file_storage_in_dir().init()
24
+
25
+ if get_cached_dump_file_storage_in_dir() is not None:
26
+ get_cached_dump_file_storage_in_dir().init()
27
+
28
+ if (
29
+ get_cached_sqlalchemy_db() is not None
30
+ and get_cached_settings().api_init_sqlalchemy_db
31
+ ):
32
+ get_cached_sqlalchemy_db().init()
33
+
34
+ if (
35
+ get_cached_json_db() is not None
36
+ and get_cached_settings().api_init_json_db
37
+ ):
38
+ get_cached_json_db().init()
39
+
40
+ if get_cached_sqlalchemy_db() is not None and get_cached_settings().api_create_first_data:
41
+ create_first_data_for_api()
42
+
43
+ if get_cached_settings().api_start_scheduled_operation_creator_worker:
44
+ _ = safe_run_worker_in_background(
45
+ worker=create_scheduled_operation_creator_worker(),
46
+ mode=SafeRunInBackgroundModes.thread
47
+ )
48
+
49
+ _logger.info("finish")
@@ -2,15 +2,8 @@ import logging
2
2
  from typing import Callable
3
3
 
4
4
  from arpakitlib.ar_base_worker_util import safe_run_worker_in_background, SafeRunInBackgroundModes
5
- from project.api.create_first_data import create_first_data_for_api
6
- from project.core.cache_file_storage_in_dir import get_cached_cache_file_storage_in_dir
7
- from project.core.dump_file_storage_in_dir import get_cached_dump_file_storage_in_dir
8
- from project.core.media_file_storage_in_dir import get_cached_media_file_storage_in_dir
9
5
  from project.core.settings import get_cached_settings
10
- from project.json_db.json_db import get_cached_json_db
11
6
  from project.operation_execution.operation_executor_worker import create_operation_executor_worker
12
- from project.operation_execution.scheduled_operation_creator_worker import create_scheduled_operation_creator_worker
13
- from project.sqlalchemy_db_.sqlalchemy_db import get_cached_sqlalchemy_db
14
7
 
15
8
  _logger = logging.getLogger(__name__)
16
9
 
@@ -21,42 +14,12 @@ _logger = logging.getLogger(__name__)
21
14
  async def async_startup_api_event():
22
15
  _logger.info("start")
23
16
 
24
- if get_cached_media_file_storage_in_dir() is not None:
25
- get_cached_media_file_storage_in_dir().init()
26
-
27
- if get_cached_cache_file_storage_in_dir() is not None:
28
- get_cached_cache_file_storage_in_dir().init()
29
-
30
- if get_cached_dump_file_storage_in_dir() is not None:
31
- get_cached_dump_file_storage_in_dir().init()
32
-
33
- if (
34
- get_cached_sqlalchemy_db() is not None
35
- and get_cached_settings().api_init_sqlalchemy_db
36
- ):
37
- get_cached_sqlalchemy_db().init()
38
-
39
- if (
40
- get_cached_json_db() is not None
41
- and get_cached_settings().api_init_json_db
42
- ):
43
- get_cached_json_db().init()
44
-
45
- if get_cached_sqlalchemy_db() is not None and get_cached_settings().api_create_first_data:
46
- create_first_data_for_api()
47
-
48
17
  if get_cached_settings().api_start_operation_executor_worker:
49
18
  _ = safe_run_worker_in_background(
50
19
  worker=create_operation_executor_worker(),
51
20
  mode=SafeRunInBackgroundModes.thread
52
21
  )
53
22
 
54
- if get_cached_settings().api_start_scheduled_operation_creator_worker:
55
- _ = safe_run_worker_in_background(
56
- worker=create_scheduled_operation_creator_worker(),
57
- mode=SafeRunInBackgroundModes.async_task
58
- )
59
-
60
23
  _logger.info("finish")
61
24
 
62
25
 
@@ -3,7 +3,8 @@ from fastapi import APIRouter
3
3
  from project.api.router.admin import get_auth_data, get_arpakitlib_project_template_info, raise_fake_error, \
4
4
  reinit_sqlalchemy_db, get_story_log, init_sqlalchemy_db, get_sqlalchemy_db_table_name_to_amount, \
5
5
  get_operation_allowed_statuses, get_operation, create_operation, get_operation_allowed_types, get_log_file, \
6
- clear_log_file, check_sqlalchemy_db, get_settings, get_user, make_test_data_1
6
+ clear_log_file, check_sqlalchemy_db, get_settings, get_user, make_test_data_1, make_test_data_5, make_test_data_4, \
7
+ make_test_data_3, make_test_data_2
7
8
 
8
9
  main_admin_api_router = APIRouter()
9
10
 
@@ -91,3 +92,23 @@ main_admin_api_router.include_router(
91
92
  router=make_test_data_1.api_router,
92
93
  prefix="/make_test_data_1"
93
94
  )
95
+
96
+ main_admin_api_router.include_router(
97
+ router=make_test_data_2.api_router,
98
+ prefix="/make_test_data_2"
99
+ )
100
+
101
+ main_admin_api_router.include_router(
102
+ router=make_test_data_3.api_router,
103
+ prefix="/make_test_data_3"
104
+ )
105
+
106
+ main_admin_api_router.include_router(
107
+ router=make_test_data_4.api_router,
108
+ prefix="/make_test_data_4"
109
+ )
110
+
111
+ main_admin_api_router.include_router(
112
+ router=make_test_data_5.api_router,
113
+ prefix="/make_test_data_5"
114
+ )
@@ -0,0 +1,35 @@
1
+ import fastapi
2
+ from fastapi import APIRouter
3
+
4
+ from project.api.authorize import require_api_key_dbm_api_authorize_middleware, APIAuthorizeData, \
5
+ require_user_token_dbm_api_authorize_middleware, api_authorize
6
+ from project.api.schema.out.common.error import ErrorCommonSO
7
+ from project.api.schema.out.common.ok import OkCommonSO
8
+ from project.sqlalchemy_db_.sqlalchemy_model import UserDBM
9
+ from project.test_data.make_test_data_2 import make_test_data_2
10
+
11
+ api_router = APIRouter()
12
+
13
+
14
+ @api_router.get(
15
+ path="",
16
+ name="Make test data 2",
17
+ status_code=fastapi.status.HTTP_200_OK,
18
+ response_model=OkCommonSO | ErrorCommonSO
19
+ )
20
+ def _(
21
+ *,
22
+ request: fastapi.requests.Request,
23
+ response: fastapi.responses.Response,
24
+ api_auth_data: APIAuthorizeData = fastapi.Depends(api_authorize(middlewares=[
25
+ require_api_key_dbm_api_authorize_middleware(
26
+ require_active=True
27
+ ),
28
+ require_user_token_dbm_api_authorize_middleware(
29
+ require_active_user_token=True,
30
+ require_user_roles=[UserDBM.Roles.admin]
31
+ )
32
+ ]))
33
+ ):
34
+ make_test_data_2()
35
+ return OkCommonSO()
@@ -0,0 +1,35 @@
1
+ import fastapi
2
+ from fastapi import APIRouter
3
+
4
+ from project.api.authorize import require_api_key_dbm_api_authorize_middleware, APIAuthorizeData, \
5
+ require_user_token_dbm_api_authorize_middleware, api_authorize
6
+ from project.api.schema.out.common.error import ErrorCommonSO
7
+ from project.api.schema.out.common.ok import OkCommonSO
8
+ from project.sqlalchemy_db_.sqlalchemy_model import UserDBM
9
+ from project.test_data.make_test_data_3 import make_test_data_3
10
+
11
+ api_router = APIRouter()
12
+
13
+
14
+ @api_router.get(
15
+ path="",
16
+ name="Make test data 3",
17
+ status_code=fastapi.status.HTTP_200_OK,
18
+ response_model=OkCommonSO | ErrorCommonSO
19
+ )
20
+ def _(
21
+ *,
22
+ request: fastapi.requests.Request,
23
+ response: fastapi.responses.Response,
24
+ api_auth_data: APIAuthorizeData = fastapi.Depends(api_authorize(middlewares=[
25
+ require_api_key_dbm_api_authorize_middleware(
26
+ require_active=True
27
+ ),
28
+ require_user_token_dbm_api_authorize_middleware(
29
+ require_active_user_token=True,
30
+ require_user_roles=[UserDBM.Roles.admin]
31
+ )
32
+ ]))
33
+ ):
34
+ make_test_data_3()
35
+ return OkCommonSO()
@@ -0,0 +1,35 @@
1
+ import fastapi
2
+ from fastapi import APIRouter
3
+
4
+ from project.api.authorize import require_api_key_dbm_api_authorize_middleware, APIAuthorizeData, \
5
+ require_user_token_dbm_api_authorize_middleware, api_authorize
6
+ from project.api.schema.out.common.error import ErrorCommonSO
7
+ from project.api.schema.out.common.ok import OkCommonSO
8
+ from project.sqlalchemy_db_.sqlalchemy_model import UserDBM
9
+ from project.test_data.make_test_data_4 import make_test_data_4
10
+
11
+ api_router = APIRouter()
12
+
13
+
14
+ @api_router.get(
15
+ path="",
16
+ name="Make test data 4",
17
+ status_code=fastapi.status.HTTP_200_OK,
18
+ response_model=OkCommonSO | ErrorCommonSO
19
+ )
20
+ def _(
21
+ *,
22
+ request: fastapi.requests.Request,
23
+ response: fastapi.responses.Response,
24
+ api_auth_data: APIAuthorizeData = fastapi.Depends(api_authorize(middlewares=[
25
+ require_api_key_dbm_api_authorize_middleware(
26
+ require_active=True
27
+ ),
28
+ require_user_token_dbm_api_authorize_middleware(
29
+ require_active_user_token=True,
30
+ require_user_roles=[UserDBM.Roles.admin]
31
+ )
32
+ ]))
33
+ ):
34
+ make_test_data_4()
35
+ return OkCommonSO()
@@ -0,0 +1,35 @@
1
+ import fastapi
2
+ from fastapi import APIRouter
3
+
4
+ from project.api.authorize import require_api_key_dbm_api_authorize_middleware, APIAuthorizeData, \
5
+ require_user_token_dbm_api_authorize_middleware, api_authorize
6
+ from project.api.schema.out.common.error import ErrorCommonSO
7
+ from project.api.schema.out.common.ok import OkCommonSO
8
+ from project.sqlalchemy_db_.sqlalchemy_model import UserDBM
9
+ from project.test_data.make_test_data_5 import make_test_data_5
10
+
11
+ api_router = APIRouter()
12
+
13
+
14
+ @api_router.get(
15
+ path="",
16
+ name="Make test data 5",
17
+ status_code=fastapi.status.HTTP_200_OK,
18
+ response_model=OkCommonSO | ErrorCommonSO
19
+ )
20
+ def _(
21
+ *,
22
+ request: fastapi.requests.Request,
23
+ response: fastapi.responses.Response,
24
+ api_auth_data: APIAuthorizeData = fastapi.Depends(api_authorize(middlewares=[
25
+ require_api_key_dbm_api_authorize_middleware(
26
+ require_active=True
27
+ ),
28
+ require_user_token_dbm_api_authorize_middleware(
29
+ require_active_user_token=True,
30
+ require_user_roles=[UserDBM.Roles.admin]
31
+ )
32
+ ]))
33
+ ):
34
+ make_test_data_5()
35
+ return OkCommonSO()
@@ -1,26 +1,21 @@
1
1
  import uvicorn
2
2
 
3
- from arpakitlib.ar_base_worker_util import safe_run_worker_in_background, SafeRunInBackgroundModes
3
+ from project.api.before_start_api import before_start_api
4
4
  from project.core.settings import get_cached_settings
5
5
  from project.core.util import setup_logging
6
- from project.operation_execution.scheduled_operation_creator_worker import create_scheduled_operation_creator_worker
7
6
 
8
7
 
9
- def __command():
8
+ def start_api():
10
9
  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
- )
10
+ before_start_api()
16
11
  uvicorn.run(
17
12
  "project.api.asgi:app",
18
13
  port=get_cached_settings().api_port,
19
- host="localhost",
20
- workers=1,
21
- reload=False
14
+ host=get_cached_settings().api_host,
15
+ workers=get_cached_settings().api_workers,
16
+ reload=get_cached_settings().api_reload
22
17
  )
23
18
 
24
19
 
25
20
  if __name__ == '__main__':
26
- __command()
21
+ start_api()
@@ -80,6 +80,10 @@ class Settings(SimpleSettings):
80
80
 
81
81
  api_port: int | None = 8080
82
82
 
83
+ api_host: str | None = "localhost"
84
+
85
+ api_reload: bool = False
86
+
83
87
  api_init_sqlalchemy_db: bool = False
84
88
 
85
89
  api_init_json_db: bool = False
@@ -36,15 +36,22 @@ class SQLAdminAuth(AuthenticationBackend):
36
36
  is_password_correct := password in get_cached_settings().sqladmin_authorize_keys
37
37
  )
38
38
  ):
39
- if is_username_correct is True:
39
+ if is_username_correct:
40
40
  request.session.update({SQLADMIN_AUTHORIZE_KEY: username})
41
- elif is_password_correct is True:
41
+ elif is_password_correct:
42
42
  request.session.update({SQLADMIN_AUTHORIZE_KEY: password})
43
43
  return True
44
44
 
45
45
  if get_cached_sqlalchemy_db() is not None and (username is not None or password is not None):
46
46
  with get_cached_sqlalchemy_db().new_session() as session:
47
- query = session.query(UserTokenDBM).filter(UserTokenDBM.is_active == True)
47
+ query = session.query(UserTokenDBM)
48
+ query = query.join(
49
+ UserDBM
50
+ ).filter(
51
+ UserTokenDBM.is_active == True
52
+ ).filter(
53
+ UserDBM.is_active.is_(True)
54
+ )
48
55
  if username is not None:
49
56
  query = query.filter(UserTokenDBM.value == username)
50
57
  elif password is not None:
@@ -57,26 +64,29 @@ class SQLAdminAuth(AuthenticationBackend):
57
64
  return True
58
65
 
59
66
  if get_cached_sqlalchemy_db() is not None and (username is not None and password is not None):
60
- query = session.query(UserDBM)
61
- query = query.filter(UserDBM.is_active == True)
62
- _or_conditions = [
63
- UserDBM.long_id == username,
64
- UserDBM.slug == username,
65
- UserDBM.email == username,
66
- UserDBM.username == username,
67
- ]
68
- if username.isdigit():
69
- _or_conditions.append(UserDBM.id == int(username))
70
- query = query.filter(sqlalchemy.or_(*_or_conditions))
71
- query = query.filter(UserDBM.password == password)
72
- user_dbm: UserDBM | None = query.one_or_none()
73
- if user_dbm is not None and user_dbm.compare_roles(UserDBM.Roles.admin):
74
- new_user_token_dbm = UserTokenDBM(user_id=user_dbm.id)
75
- session.add(new_user_token_dbm)
76
- session.commit()
77
- session.refresh(new_user_token_dbm)
78
- request.session.update({SQLADMIN_AUTHORIZE_KEY: new_user_token_dbm.value})
79
- return True
67
+ with get_cached_sqlalchemy_db().new_session() as session:
68
+ query = session.query(UserDBM)
69
+ query = query.filter(
70
+ UserDBM.is_active == True
71
+ )
72
+ _or_conditions = [
73
+ UserDBM.long_id == username,
74
+ UserDBM.slug == username,
75
+ UserDBM.email == username,
76
+ UserDBM.username == username,
77
+ ]
78
+ if username.isdigit():
79
+ _or_conditions.append(UserDBM.id == int(username))
80
+ query = query.filter(sqlalchemy.or_(*_or_conditions))
81
+ query = query.filter(UserDBM.password == password)
82
+ user_dbm: UserDBM | None = query.one_or_none()
83
+ if user_dbm is not None and user_dbm.compare_roles(UserDBM.Roles.admin):
84
+ new_user_token_dbm = UserTokenDBM(user_id=user_dbm.id)
85
+ session.add(new_user_token_dbm)
86
+ session.commit()
87
+ session.refresh(new_user_token_dbm)
88
+ request.session.update({SQLADMIN_AUTHORIZE_KEY: new_user_token_dbm.value})
89
+ return True
80
90
 
81
91
  return False
82
92
 
@@ -35,7 +35,6 @@ class ApiKeyDBM(SimpleDBM):
35
35
  nullable=False,
36
36
  unique=True,
37
37
  insert_default=generate_default_api_key_value,
38
- server_default=sqlalchemy.func.gen_random_uuid()
39
38
  )
40
39
  is_active: Mapped[bool] = mapped_column(
41
40
  sqlalchemy.Boolean,
@@ -73,7 +73,6 @@ class UserDBM(SimpleDBM):
73
73
  nullable=True,
74
74
  index=True,
75
75
  insert_default=generate_default_user_password,
76
- server_default=sqlalchemy.func.gen_random_uuid(),
77
76
  )
78
77
  tg_id: Mapped[int | None] = mapped_column(
79
78
  sqlalchemy.BIGINT,
@@ -29,7 +29,6 @@ class UserTokenDBM(SimpleDBM):
29
29
  nullable=False,
30
30
  unique=True,
31
31
  insert_default=generate_default_user_token_value,
32
- server_default=sqlalchemy.func.gen_random_uuid(),
33
32
  )
34
33
  user_id: Mapped[int] = mapped_column(
35
34
  sqlalchemy.BIGINT,
@@ -36,7 +36,6 @@ class VerificationCodeDBM(SimpleDBM):
36
36
  nullable=False,
37
37
  index=True,
38
38
  insert_default=generate_default_verification_code_value,
39
- server_default=sqlalchemy.func.gen_random_uuid(),
40
39
  )
41
40
  recipient: Mapped[str | None] = mapped_column(
42
41
  sqlalchemy.TEXT,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: arpakitlib
3
- Version: 1.8.141
3
+ Version: 1.8.142
4
4
  Summary: arpakitlib
5
5
  License: Apache-2.0
6
6
  Keywords: arpakitlib,arpakit,arpakit-company,arpakitcompany,arpakit_company
@@ -59,9 +59,8 @@ 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=AoemyIrxS49kp34jsuJHKTa4Cvyycl17woXwk8oy9nU,209
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=4PyPtyeXfn9jpcLGdrLA8LOyOg3Rwbt5XGhSSusoOuE,853
63
- arpakitlib/_arpakit_project_template_v_5/command/start_api_for_prod.py,sha256=WpSCku-yvDNz3NFSo58HXyzL5xVOc9K6QBxawnkmqc0,857
64
- arpakitlib/_arpakit_project_template_v_5/command/start_api_with_reload.py,sha256=d6iIQY4_qjcYBoYmkWXbPVVW5HD5IUb4FOvf4YrzObM,820
62
+ arpakitlib/_arpakit_project_template_v_5/command/start_api.py,sha256=EPRfugVhXqa4UcLGvaSINExPKT_fquUeTCQt6QVUkDE,124
63
+ arpakitlib/_arpakit_project_template_v_5/command/start_api_for_prod.py,sha256=EPRfugVhXqa4UcLGvaSINExPKT_fquUeTCQt6QVUkDE,124
65
64
  arpakitlib/_arpakit_project_template_v_5/command/start_operation_executor_worker.py,sha256=X8dE5OcTEVKjbcXdU0QMstXbi8RyYWPzATHtbQHyBIs,413
66
65
  arpakitlib/_arpakit_project_template_v_5/command/start_operation_executor_workers_mode_async_task.py,sha256=C5aoJmI9LB9d25g_ZTvRccwkWUglUdcCcPb-03HoA0s,793
67
66
  arpakitlib/_arpakit_project_template_v_5/command/start_operation_executor_workers_mode_thread.py,sha256=QjInoDY7XGQZCs2A-Kh5Ul0P4CgcS9Tom6FfXcseeFs,718
@@ -71,7 +70,7 @@ arpakitlib/_arpakit_project_template_v_5/command/start_sqladmin_for_prod.py,sha2
71
70
  arpakitlib/_arpakit_project_template_v_5/command/start_sqladmin_with_reload.py,sha256=KmbadM6bmsQfP23xTn8aBzlvCQ1J2rLAuFk0_RCChjs,374
72
71
  arpakitlib/_arpakit_project_template_v_5/command/start_tg_bot.py,sha256=AJ1AxfdpbayBhScy6yAPVkSWnHJjzOTHxEewwGKaJMQ,200
73
72
  arpakitlib/_arpakit_project_template_v_5/command/start_tg_bot_for_prod.py,sha256=AJ1AxfdpbayBhScy6yAPVkSWnHJjzOTHxEewwGKaJMQ,200
74
- arpakitlib/_arpakit_project_template_v_5/example.env,sha256=CjtUXd8TjfjQH4u77j1fBKkGQH1td7sa59-MSMzXW7U,1019
73
+ arpakitlib/_arpakit_project_template_v_5/example.env,sha256=mYKEwpCt77K48wzHElzKeclCbVBq3C0J4mhLqMsQYiE,1302
75
74
  arpakitlib/_arpakit_project_template_v_5/note/note_1.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
75
  arpakitlib/_arpakit_project_template_v_5/note/note_2.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
76
  arpakitlib/_arpakit_project_template_v_5/note/note_3.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -83,6 +82,7 @@ arpakitlib/_arpakit_project_template_v_5/project/additional_model/common.py,sha2
83
82
  arpakitlib/_arpakit_project_template_v_5/project/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
84
83
  arpakitlib/_arpakit_project_template_v_5/project/api/asgi.py,sha256=ES3YGwNxWUHVyD6e2ii6QkvTyB-vlVmr8_PhfVIXQ4Y,78
85
84
  arpakitlib/_arpakit_project_template_v_5/project/api/authorize.py,sha256=puOmx2OSV2ExcLqtAD1zmvfY0zbLqLxkytF5xLZTnQg,15424
85
+ arpakitlib/_arpakit_project_template_v_5/project/api/before_start_api.py,sha256=a7eiV8oaWk9qYzlNNnY8BYY8VlnQAZ0w8TwuC2u6v_c,1902
86
86
  arpakitlib/_arpakit_project_template_v_5/project/api/blank/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
87
  arpakitlib/_arpakit_project_template_v_5/project/api/blank/admin.py,sha256=ii1zLHjvB7OVLQKFOhp4lpodXcwAmtwDdrM1iaafQfg,100
88
88
  arpakitlib/_arpakit_project_template_v_5/project/api/blank/client.py,sha256=rvJKtAB26Qy2pKVSHSMUM_70oI4v8Yr6Vmpr6r4EzNk,101
@@ -90,7 +90,7 @@ arpakitlib/_arpakit_project_template_v_5/project/api/blank/common.py,sha256=ug1F
90
90
  arpakitlib/_arpakit_project_template_v_5/project/api/const.py,sha256=J9bqaRRiIc3RLn6SJTvdfDvFrSsM_Ixii9t2M8dA5Jc,433
91
91
  arpakitlib/_arpakit_project_template_v_5/project/api/create_api_app.py,sha256=-04wCrUWh2ceFijMM8XFHJHLjOvmRcETbedidc4_IAc,2912
92
92
  arpakitlib/_arpakit_project_template_v_5/project/api/create_first_data.py,sha256=sc98-xW74QbhFCT6AW5-fUJVd8RLRxClAOEW5-ec9T0,1815
93
- arpakitlib/_arpakit_project_template_v_5/project/api/event.py,sha256=sJ9-GgBdIruJW2Kj7cU-BcqRyD8IItWFQrmGKndZ4nw,2614
93
+ arpakitlib/_arpakit_project_template_v_5/project/api/event.py,sha256=P8gV2Bq6LeLH0JDN9Z3O401PMbyNr2n-tme2gPvT-m4,996
94
94
  arpakitlib/_arpakit_project_template_v_5/project/api/exception.py,sha256=cNZaI2DacGLl8Hyn1qIfFpVjvQzOQjwXWsVW4auBrCo,1280
95
95
  arpakitlib/_arpakit_project_template_v_5/project/api/exception_handler.py,sha256=TEzkCNOg_TAELRTZgLtblVagSaHf-vego_oH5FNCbcs,11179
96
96
  arpakitlib/_arpakit_project_template_v_5/project/api/openapi_ui.py,sha256=PLhH-W6zDViO-75AGCs8Vq3IoyHChdqwBYAqLvdQN0U,904
@@ -111,8 +111,12 @@ arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_sqlalchemy
111
111
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_story_log.py,sha256=sK0FvNzoG-pE5rD2Q62t6yK5Bx1Y2JZA_04sOk14loQ,2033
112
112
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_user.py,sha256=lBTR7eyjVbf0I8yG1yTovlrz2H4h-6O3wggQLsMPdsw,2763
113
113
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/init_sqlalchemy_db.py,sha256=HUDaDeyb5ldpiEaA2mJIsAuGF6H-XupGvKfxjrkxMTE,1333
114
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/main_router.py,sha256=pu5-H9JlXhsVrY4a2ajbgeTbPo9ijIGSiq7J1Q77QT0,2479
114
+ arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/main_router.py,sha256=oDf4EnvYhJR3ZI_Kl-V1kuTbPZqSKJFODfnqgPtiW6U,3005
115
115
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/make_test_data_1.py,sha256=tITqtXW2C7od04_ECQudR_5kupVoKrYVnUVU2YcZp-g,1178
116
+ arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/make_test_data_2.py,sha256=w003vLYnCUmM5GMaPDFGYcKd04OUf6rvonAQSEToZ5c,1178
117
+ arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/make_test_data_3.py,sha256=P0IF-awERehfABlE68O1GjxTYVaBEUl-s5tQL2tQ-Qg,1178
118
+ arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/make_test_data_4.py,sha256=u0VDTCQoMl17jmtGM4f2uDFf52F6Aq7B_d8fbUK83hE,1178
119
+ arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/make_test_data_5.py,sha256=5hEvMeTj7Bu_JT1alRHBFjyOfdEaZeMwk_Smrpqd-So,1178
116
120
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/raise_fake_error.py,sha256=kMr06QR39XVUoVwUuwJHoQmaWHvlfi2j53ZCMX3CU48,1048
117
121
  arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/reinit_sqlalchemy_db.py,sha256=kTa_RSZgPKbDfdFHzhAJroddWOUDRK4YTJN2WVnKu-Q,1343
118
122
  arpakitlib/_arpakit_project_template_v_5/project/api/router/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -159,7 +163,7 @@ arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/api_key.
159
163
  arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/common.py,sha256=y-p4QJhvKnFL1I6ud3m_nzE0xtreT3CNApPkkkLAbG0,541
160
164
  arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/user.py,sha256=AvYwqaowd1V_6VQjrIGxt8SwqNEgmirLcHbtSHPwWmQ,1080
161
165
  arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/user_token.py,sha256=iiuZXu_zo3FJX0W5qyyMGasUx-_d32yjqc_2KY3xpUA,513
162
- arpakitlib/_arpakit_project_template_v_5/project/api/start_api.py,sha256=fl-dkm2I3ModQXjGG6VrP6vUFciEcRW_ORFG3VX8jH8,821
166
+ arpakitlib/_arpakit_project_template_v_5/project/api/start_api.py,sha256=3caGU5XPwMZTOkwT4MwmKxy7CaeYI82r5VT2UuLzOA8,523
163
167
  arpakitlib/_arpakit_project_template_v_5/project/api/util.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
164
168
  arpakitlib/_arpakit_project_template_v_5/project/business_service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
165
169
  arpakitlib/_arpakit_project_template_v_5/project/business_service/hello_world.py,sha256=lvWlVF6SlnC33swSCd-_QK6guxBg50myOd8cPS7hZrA,251
@@ -172,7 +176,7 @@ arpakitlib/_arpakit_project_template_v_5/project/core/dump_file_storage_in_dir.p
172
176
  arpakitlib/_arpakit_project_template_v_5/project/core/easy_openai_api_client.py,sha256=G4J9s0gerNlnvl1LvaWSYy1gdvaMbxyz0ZP35U9nx_Q,1219
173
177
  arpakitlib/_arpakit_project_template_v_5/project/core/jinja2_templates.py,sha256=jCNLaBauGC7YNvZdTLNHuPp7hmRGt94O23Skg6ewo7o,352
174
178
  arpakitlib/_arpakit_project_template_v_5/project/core/media_file_storage_in_dir.py,sha256=fMofTsfJtA8pp5lEUhucEUu3PBsmj-elaRZzExDsdLI,623
175
- arpakitlib/_arpakit_project_template_v_5/project/core/settings.py,sha256=sKN8DEpsjp4hXiDF3pWeg9TcYNGGQKztF1Dpeop9E0M,6368
179
+ arpakitlib/_arpakit_project_template_v_5/project/core/settings.py,sha256=6h32Sqf4ruRk_kudSJN8ZrHodlJGVgiUAIy-3z5PkwE,6438
176
180
  arpakitlib/_arpakit_project_template_v_5/project/core/util.py,sha256=1ha9UrguVPsTSjoMHhVZVCD0_mNBfhIDGEvcG1nA4Zw,667
177
181
  arpakitlib/_arpakit_project_template_v_5/project/emailer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
178
182
  arpakitlib/_arpakit_project_template_v_5/project/emailer/send_email.py,sha256=lw-nUFtEYiGEChSZrfuXCtTkoY6fNT45M_Y6QfzOk90,2175
@@ -232,7 +236,7 @@ arpakitlib/_arpakit_project_template_v_5/project/site/router/__init__.py,sha256=
232
236
  arpakitlib/_arpakit_project_template_v_5/project/site/router/main_router.py,sha256=J5jNfgd-3OiWTtuubimEUz6wrOogupj9PkUdDmwz-2U,62
233
237
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
234
238
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/add_admin_in_app.py,sha256=JTXLf18DQVsZtoe6yFpZIVJI95rgJofnTe9YKyVwwhQ,851
235
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/admin_authorize.py,sha256=tmvYx5hFO2RqHmhKktpMRJaBuT6vDHBOsQujihO7sMw,4983
239
+ arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/admin_authorize.py,sha256=eIJ-oG8-piqSsnEPN3aJT_U5XOnxL7ZW3BCbLfVKS-E,5349
236
240
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/asgi.py,sha256=DRlRPkcOGXOccfP73oKEXolZTsc5VWdQgEG-qoW03ms,99
237
241
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/create_sqladmin_app.py,sha256=x5F8--5KA4cmTrb6kAAmp6fVd2TiqxPOzxqUkSEhSG4,1298
238
242
  arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/event.py,sha256=n8Bt78wyIqplxhbmSrwHf0rolV46QvXLOJ6UjAUNCZE,937
@@ -251,13 +255,13 @@ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/__init__.py,sha2
251
255
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/const.py,sha256=dcvj5C9E2F2KCsGZPBBncQf_EvVJAC1qQgnyD8P4ZEw,6
252
256
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_db.py,sha256=1y3FaMFzm_5UM2poqtBve_UP_mh1vjs--krq6yO8PsA,742
253
257
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/__init__.py,sha256=zRK-ao92u6Q-NNTtsPycTVEjzRjK5BOXgsUZRtNblpM,688
254
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/api_key.py,sha256=R-wAGtRtRS4CjW2DPJ9ZUyRnMqICWTaqyUTlhsAd7LY,2026
258
+ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/api_key.py,sha256=2X6VPkf1TKq-0319J0tL-rPMvgmkBCjim3Si1dZboMQ,1969
255
259
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/common.py,sha256=9j3QwBkaQSmsqXZbAYZDysGXP3xPPAHJfqIja5UnLcc,3229
256
260
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/operation.py,sha256=op5cSkTlHJyGjULgcSWE9-_PNinKSneHLxhG5DUkd9M,5913
257
261
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/story_log.py,sha256=wig_D6OZyYYGsqZEbmSK56qoAIOnOVnOEB_sRSZLSIU,2396
258
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user.py,sha256=bAyeFV9EU5J1R6POQieDSPpna9q_AMr-9oHq2SVHnSQ,7637
259
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user_token.py,sha256=UtSbQRlNJOnD7q-d_aZfMjQnPFnchGPf1fWGwsgCm5k,1944
260
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/verification_code.py,sha256=13aDT9m2l9zaJXqHZi0MsoY--5BNWhbw0O9uQJAW16E,3136
262
+ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user.py,sha256=-gmBWOAHJsUl-YY7U_2ZcKK5GV9dPHpvpdTRQnfbA_0,7579
263
+ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user_token.py,sha256=hX6nHvVvhg5YB3vCjsku4TDoY5Jk1FsuDu5elbcF7VE,1886
264
+ arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/verification_code.py,sha256=xrrNPXn5PeCnZ2VWVBdXDUft83EEYtc6b4pvs0oh1uw,3078
261
265
  arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/util.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
262
266
  arpakitlib/_arpakit_project_template_v_5/project/test_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
263
267
  arpakitlib/_arpakit_project_template_v_5/project/test_data/make_test_api_keys.py,sha256=9F2bMfymaqx_Czh_tF945BKpKqNrVNjSIfCQl13Dkxw,911
@@ -401,8 +405,8 @@ arpakitlib/ar_ssh_runner_util.py,sha256=yvAwza480MkHKvLkDEsR7JNh2bYNs6P9rCVo4NA8
401
405
  arpakitlib/ar_str_util.py,sha256=2lGpnXDf2h1cBZpVf5i1tX_HCv5iBd6IGnrCw4QWWlY,4350
402
406
  arpakitlib/ar_type_util.py,sha256=Cs_tef-Fc5xeyAF54KgISCsP11NHyzIsglm4S3Xx7iM,4049
403
407
  arpakitlib/ar_yookassa_api_client_util.py,sha256=VozuZeCJjmLd1zj2BdC9WfiAQ3XYOrIMsdpNK-AUlm0,5347
404
- arpakitlib-1.8.141.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
405
- arpakitlib-1.8.141.dist-info/METADATA,sha256=sLbIta5Bb-wgnbWZw8VYmbQxoTh2I94Cgko6tgHinJ4,3660
406
- arpakitlib-1.8.141.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
407
- arpakitlib-1.8.141.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
408
- arpakitlib-1.8.141.dist-info/RECORD,,
408
+ arpakitlib-1.8.142.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
409
+ arpakitlib-1.8.142.dist-info/METADATA,sha256=PpYL6TGdfuz4basK1qZQrqSMbue1wZtRc9eyGSQ8sRw,3660
410
+ arpakitlib-1.8.142.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
411
+ arpakitlib-1.8.142.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
412
+ arpakitlib-1.8.142.dist-info/RECORD,,
@@ -1,26 +0,0 @@
1
- import uvicorn
2
-
3
- from arpakitlib.ar_base_worker_util import SafeRunInBackgroundModes, safe_run_worker_in_background
4
- from project.core.settings import get_cached_settings
5
- from project.core.util import setup_logging
6
- from project.operation_execution.scheduled_operation_creator_worker import create_scheduled_operation_creator_worker
7
-
8
-
9
- def __command():
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
- )
16
- uvicorn.run(
17
- "project.api.asgi:app",
18
- port=get_cached_settings().api_port,
19
- host="localhost",
20
- workers=1,
21
- reload=True
22
- )
23
-
24
-
25
- if __name__ == '__main__':
26
- __command()