arpakitlib 1.7.253__py3-none-any.whl → 1.7.255__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 (26) hide show
  1. arpakitlib/_arpakit_project_template/example.env +8 -1
  2. arpakitlib/_arpakit_project_template/src/api/create_api_app.py +7 -32
  3. arpakitlib/_arpakit_project_template/src/api/event.py +4 -6
  4. arpakitlib/_arpakit_project_template/src/api/util.py +44 -0
  5. arpakitlib/_arpakit_project_template/src/core/_show_settings.py +1 -0
  6. arpakitlib/_arpakit_project_template/src/json_db/__init__.py +0 -0
  7. arpakitlib/_arpakit_project_template/src/json_db/_drop_json_db.py +13 -0
  8. arpakitlib/_arpakit_project_template/src/json_db/_init_json_db.py +11 -0
  9. arpakitlib/_arpakit_project_template/src/json_db/_reinit_json_db.py +13 -0
  10. arpakitlib/_arpakit_project_template/src/json_db/_rm_all_records_in_json_db.py +13 -0
  11. arpakitlib/_arpakit_project_template/src/json_db/json_db.py +11 -0
  12. arpakitlib/_arpakit_project_template/src/json_db/util.py +17 -0
  13. arpakitlib/_arpakit_project_template/src/tg_bot/event.py +8 -2
  14. arpakitlib/_arpakit_project_template/src/tg_bot/start_tg_bot.py +1 -2
  15. arpakitlib/_arpakit_project_template/src/tg_bot/util.py +44 -0
  16. arpakitlib/ar_aiogram_util.py +5 -17
  17. arpakitlib/ar_fastapi_util.py +2 -2
  18. arpakitlib/ar_json_db_util.py +7 -5
  19. arpakitlib/ar_operation_execution_util.py +2 -0
  20. arpakitlib/ar_settings_util.py +50 -33
  21. arpakitlib/ar_sqlalchemy_util.py +6 -22
  22. {arpakitlib-1.7.253.dist-info → arpakitlib-1.7.255.dist-info}/METADATA +1 -1
  23. {arpakitlib-1.7.253.dist-info → arpakitlib-1.7.255.dist-info}/RECORD +26 -18
  24. {arpakitlib-1.7.253.dist-info → arpakitlib-1.7.255.dist-info}/LICENSE +0 -0
  25. {arpakitlib-1.7.253.dist-info → arpakitlib-1.7.255.dist-info}/WHEEL +0 -0
  26. {arpakitlib-1.7.253.dist-info → arpakitlib-1.7.255.dist-info}/entry_points.txt +0 -0
@@ -2,22 +2,29 @@
2
2
  # project_name=
3
3
  # sql_db_user=
4
4
  # sql_db_password=
5
+ # sql_db_host=
5
6
  # sql_db_port=
6
7
  # sql_db_database=
7
8
  # sync_sql_db_url=
8
9
  # async_sql_db_url=
9
10
  # sql_db_echo=
10
11
  # api_port=
11
- # api_init_sql_db_at_start=
12
+ # api_init_sql_db=
13
+ # api_init_json_db=
12
14
  # api_logging__api_func_before_in_handle_exception=
13
15
  # api_story_log__api_func_before_in_handle_exception=
14
16
  # api_correct_api_key=
15
17
  # api_correct_token=
16
18
  # api_enable_admin1=
19
+ # api_start_operation_executor_worker=
20
+ # api_start_scheduled_operation_creator_worker=
17
21
  # admin1_secret_key=
22
+ # tg_bot_init_sql_db=
23
+ # tg_bot_init_json_db=
18
24
  # var_dirpath=
19
25
  # log_filepath=
20
26
  # cache_dirpath=
21
27
  # media_dirpath=
22
28
  # dump_dirpath=
23
29
  # local_timezone=
30
+ # json_db_dirpath=
@@ -4,40 +4,15 @@ from arpakitlib.ar_fastapi_util import create_fastapi_app
4
4
  from src.api.create_handle_exception_ import create_handle_exception_
5
5
  from src.api.event import get_startup_api_events, get_shutdown_api_events
6
6
  from src.api.router.main_router import main_api_router
7
- from src.api.transmitted_api_data import TransmittedAPIData
7
+ from src.api.util import get_transmitted_api_data
8
8
  from src.core.const import ProjectPaths
9
- from src.core.settings import get_cached_settings
10
- from src.core.util import setup_logging, get_cached_media_file_storage_in_dir, get_cached_cache_file_storage_in_dir, \
11
- get_cached_dump_file_storage_in_dir
12
- from src.sql_db.util import get_cached_sqlalchemy_db
9
+ from src.core.util import setup_logging
13
10
 
14
11
 
15
12
  def create_api_app() -> FastAPI:
16
13
  setup_logging()
17
14
 
18
- settings = get_cached_settings()
19
-
20
- sqlalchemy_db = get_cached_sqlalchemy_db() if settings.sql_db_url is not None else None
21
-
22
- media_file_storage_in_dir = (
23
- get_cached_media_file_storage_in_dir() if settings.media_dirpath is not None else None
24
- )
25
-
26
- cache_file_storage_in_dir = (
27
- get_cached_cache_file_storage_in_dir() if settings.cache_dirpath is not None else None
28
- )
29
-
30
- dump_file_storage_in_dir = (
31
- get_cached_dump_file_storage_in_dir() if settings.dump_dirpath is not None else None
32
- )
33
-
34
- transmitted_api_data = TransmittedAPIData(
35
- settings=settings,
36
- sqlalchemy_db=sqlalchemy_db,
37
- media_file_storage_in_dir=media_file_storage_in_dir,
38
- cache_file_storage_in_dir=cache_file_storage_in_dir,
39
- dump_file_storage_in_dir=dump_file_storage_in_dir
40
- )
15
+ transmitted_api_data = get_transmitted_api_data()
41
16
 
42
17
  handle_exception_ = create_handle_exception_(transmitted_api_data=transmitted_api_data)
43
18
 
@@ -46,18 +21,18 @@ def create_api_app() -> FastAPI:
46
21
  shutdown_api_events = get_shutdown_api_events(transmitted_api_data=transmitted_api_data)
47
22
 
48
23
  api_app = create_fastapi_app(
49
- title=settings.project_name.strip(),
50
- description=settings.project_name.strip(),
24
+ title=transmitted_api_data.settings.project_name,
25
+ description=transmitted_api_data.settings.project_name,
51
26
  handle_exception_=handle_exception_,
52
27
  startup_api_events=startup_api_events,
53
28
  shutdown_api_events=shutdown_api_events,
54
29
  transmitted_api_data=transmitted_api_data,
55
30
  main_api_router=main_api_router,
56
- media_dirpath=settings.media_dirpath,
31
+ media_dirpath=transmitted_api_data.settings.media_dirpath,
57
32
  static_dirpath=ProjectPaths.static_dirpath
58
33
  )
59
34
 
60
- if settings.api_enable_admin1:
35
+ if transmitted_api_data.settings.api_enable_admin1:
61
36
  from src.admin1.add_admin_in_app import add_admin1_in_app
62
37
  add_admin1_in_app(app=api_app)
63
38
 
@@ -1,8 +1,6 @@
1
1
  from arpakitlib.ar_base_worker_util import safe_run_worker_in_background, SafeRunInBackgroundModes
2
2
  from arpakitlib.ar_fastapi_util import BaseStartupAPIEvent, BaseShutdownAPIEvent
3
3
  from arpakitlib.ar_operation_execution_util import OperationExecutorWorker, ScheduledOperationCreatorWorker
4
- from arpakitlib.ar_sqlalchemy_util import SQLAlchemyDb
5
- from arpakitlib.ar_type_util import raise_for_type
6
4
  from src.api.transmitted_api_data import TransmittedAPIData
7
5
  from src.operation_execution.operation_executor import OperationExecutor
8
6
  from src.operation_execution.scheduled_operations import SCHEDULED_OPERATIONS
@@ -28,12 +26,13 @@ class StartupAPIEvent(BaseStartupAPIEvent):
28
26
  if self.transmitted_api_data.dump_file_storage_in_dir is not None:
29
27
  self.transmitted_api_data.dump_file_storage_in_dir.init()
30
28
 
31
- if self.transmitted_api_data.settings.api_init_sql_db_at_start:
32
- raise_for_type(self.transmitted_api_data.sqlalchemy_db, SQLAlchemyDb)
29
+ if self.transmitted_api_data.settings.api_init_sql_db:
33
30
  self.transmitted_api_data.sqlalchemy_db.init()
34
31
 
32
+ if self.transmitted_api_data.settings.api_init_json_db:
33
+ self.transmitted_api_data.json_db.init()
34
+
35
35
  if self.transmitted_api_data.settings.api_start_operation_executor_worker: # TODO
36
- raise_for_type(self.transmitted_api_data.sqlalchemy_db, SQLAlchemyDb)
37
36
  _ = safe_run_worker_in_background(
38
37
  worker=OperationExecutorWorker(
39
38
  sqlalchemy_db=self.transmitted_api_data.sqlalchemy_db,
@@ -44,7 +43,6 @@ class StartupAPIEvent(BaseStartupAPIEvent):
44
43
  )
45
44
 
46
45
  if self.transmitted_api_data.settings.api_start_scheduled_operation_creator_worker: # TODO
47
- raise_for_type(self.transmitted_api_data.sqlalchemy_db, SQLAlchemyDb)
48
46
  _ = safe_run_worker_in_background(
49
47
  worker=ScheduledOperationCreatorWorker(
50
48
  sqlalchemy_db=self.transmitted_api_data.sqlalchemy_db,
@@ -0,0 +1,44 @@
1
+ from functools import lru_cache
2
+
3
+ from src.api.transmitted_api_data import TransmittedAPIData
4
+ from src.core.settings import get_cached_settings
5
+ from src.core.util import get_cached_media_file_storage_in_dir, get_cached_cache_file_storage_in_dir, \
6
+ get_cached_dump_file_storage_in_dir
7
+ from src.json_db.util import get_json_db
8
+ from src.sql_db.util import get_cached_sqlalchemy_db
9
+
10
+
11
+ def create_transmitted_api_data() -> TransmittedAPIData:
12
+ settings = get_cached_settings()
13
+
14
+ sqlalchemy_db = get_cached_sqlalchemy_db() if settings.sync_sql_db_url is not None else None
15
+
16
+ json_db = get_json_db() if settings.json_db_dirpath is not None else None
17
+
18
+ media_file_storage_in_dir = (
19
+ get_cached_media_file_storage_in_dir() if settings.media_dirpath is not None else None
20
+ )
21
+
22
+ cache_file_storage_in_dir = (
23
+ get_cached_cache_file_storage_in_dir() if settings.cache_dirpath is not None else None
24
+ )
25
+
26
+ dump_file_storage_in_dir = (
27
+ get_cached_dump_file_storage_in_dir() if settings.dump_dirpath is not None else None
28
+ )
29
+
30
+ transmitted_api_data = TransmittedAPIData(
31
+ sqlalchemy_db=sqlalchemy_db,
32
+ json_db=json_db,
33
+ media_file_storage_in_dir=media_file_storage_in_dir,
34
+ cache_file_storage_in_dir=cache_file_storage_in_dir,
35
+ dump_file_storage_in_dir=dump_file_storage_in_dir,
36
+ settings=settings
37
+ )
38
+
39
+ return transmitted_api_data
40
+
41
+
42
+ @lru_cache()
43
+ def get_transmitted_api_data() -> TransmittedAPIData:
44
+ return create_transmitted_api_data()
@@ -4,6 +4,7 @@ from src.core.settings import get_cached_settings
4
4
 
5
5
  def _check_settings():
6
6
  print(safely_transfer_obj_to_json_str(get_cached_settings().model_dump(mode="json")))
7
+ print(get_cached_settings().is_any_sql_db_url_set)
7
8
 
8
9
 
9
10
  if __name__ == '__main__':
@@ -0,0 +1,13 @@
1
+ from src.core.settings import get_cached_settings
2
+ from src.core.util import setup_logging
3
+ from src.json_db.util import get_json_db
4
+
5
+
6
+ def _init_json_db():
7
+ setup_logging()
8
+ get_cached_settings().raise_if_mode_type_prod()
9
+ get_json_db().drop()
10
+
11
+
12
+ if __name__ == '__main__':
13
+ _init_json_db()
@@ -0,0 +1,11 @@
1
+ from src.core.util import setup_logging
2
+ from src.json_db.util import get_json_db
3
+
4
+
5
+ def _init_json_db():
6
+ setup_logging()
7
+ get_json_db().init()
8
+
9
+
10
+ if __name__ == '__main__':
11
+ _init_json_db()
@@ -0,0 +1,13 @@
1
+ from src.core.settings import get_cached_settings
2
+ from src.core.util import setup_logging
3
+ from src.json_db.util import get_json_db
4
+
5
+
6
+ def _init_json_db():
7
+ setup_logging()
8
+ get_cached_settings().raise_if_mode_type_prod()
9
+ get_json_db().reinit()
10
+
11
+
12
+ if __name__ == '__main__':
13
+ _init_json_db()
@@ -0,0 +1,13 @@
1
+ from src.core.settings import get_cached_settings
2
+ from src.core.util import setup_logging
3
+ from src.json_db.util import get_json_db
4
+
5
+
6
+ def _init_json_db():
7
+ setup_logging()
8
+ get_cached_settings().raise_if_mode_type_prod()
9
+ get_json_db().rm_all_records()
10
+
11
+
12
+ if __name__ == '__main__':
13
+ _init_json_db()
@@ -0,0 +1,11 @@
1
+ import os
2
+
3
+ from arpakitlib.ar_json_db_util import BaseJSONDb
4
+
5
+
6
+ class JSONDb(BaseJSONDb):
7
+ def __init__(self, dirpath: str):
8
+ super().__init__()
9
+ self.story_log = self.create_json_db_file(
10
+ filepath=os.path.join(dirpath, "story_log.json"), use_memory=True, beautify_json=False
11
+ )
@@ -0,0 +1,17 @@
1
+ from functools import lru_cache
2
+
3
+ from src.core.settings import get_cached_settings
4
+ from src.json_db.json_db import JSONDb
5
+
6
+
7
+ def create_json_db() -> JSONDb:
8
+ return JSONDb(
9
+ dirpath=get_cached_settings().json_db_dirpath
10
+ )
11
+
12
+
13
+ @lru_cache()
14
+ def get_json_db() -> JSONDb:
15
+ return JSONDb(
16
+ dirpath=get_cached_settings().json_db_dirpath
17
+ )
@@ -9,7 +9,7 @@ class StartupTgBotEvent:
9
9
  self.transmitted_tg_bot_data = transmitted_tg_bot_data
10
10
 
11
11
  async def on_startup(self, *args, **kwargs):
12
- self._logger.info("on_startup start")
12
+ self._logger.info("start")
13
13
 
14
14
  if self.transmitted_tg_bot_data.media_file_storage_in_dir is not None:
15
15
  self.transmitted_tg_bot_data.media_file_storage_in_dir.init()
@@ -20,7 +20,13 @@ class StartupTgBotEvent:
20
20
  if self.transmitted_tg_bot_data.dump_file_storage_in_dir is not None:
21
21
  self.transmitted_tg_bot_data.dump_file_storage_in_dir.init()
22
22
 
23
- self._logger.info("on_startup was done")
23
+ if self.transmitted_tg_bot_data.settings.api_init_sql_db:
24
+ self.transmitted_tg_bot_data.sqlalchemy_db.init()
25
+
26
+ if self.transmitted_tg_bot_data.settings.api_init_json_db:
27
+ self.transmitted_tg_bot_data.json_db.init()
28
+
29
+ self._logger.info("finish")
24
30
 
25
31
 
26
32
  class ShutdownTgBotEvent:
@@ -1,11 +1,10 @@
1
- from src.core.settings import get_cached_settings
2
1
  from src.core.util import setup_logging
3
2
 
4
3
 
5
4
  def start_tg_bot():
6
5
  setup_logging()
7
6
 
8
- settings = get_cached_settings()
7
+ # ...
9
8
 
10
9
 
11
10
  if __name__ == '__main__':
@@ -0,0 +1,44 @@
1
+ from functools import lru_cache
2
+
3
+ from src.core.settings import get_cached_settings
4
+ from src.core.util import get_cached_media_file_storage_in_dir, get_cached_cache_file_storage_in_dir, \
5
+ get_cached_dump_file_storage_in_dir
6
+ from src.json_db.util import get_json_db
7
+ from src.sql_db.util import get_cached_sqlalchemy_db
8
+ from src.tg_bot.transmitted_tg_data import TransmittedTgData
9
+
10
+
11
+ def create_transmitted_tg_bot_data() -> TransmittedTgData:
12
+ settings = get_cached_settings()
13
+
14
+ sqlalchemy_db = get_cached_sqlalchemy_db() if settings.sync_sql_db_url is not None else None
15
+
16
+ json_db = get_json_db() if settings.json_db_dirpath is not None else None
17
+
18
+ media_file_storage_in_dir = (
19
+ get_cached_media_file_storage_in_dir() if settings.media_dirpath is not None else None
20
+ )
21
+
22
+ cache_file_storage_in_dir = (
23
+ get_cached_cache_file_storage_in_dir() if settings.cache_dirpath is not None else None
24
+ )
25
+
26
+ dump_file_storage_in_dir = (
27
+ get_cached_dump_file_storage_in_dir() if settings.dump_dirpath is not None else None
28
+ )
29
+
30
+ transmitted_api_data = TransmittedTgData(
31
+ sqlalchemy_db=sqlalchemy_db,
32
+ json_db=json_db,
33
+ media_file_storage_in_dir=media_file_storage_in_dir,
34
+ cache_file_storage_in_dir=cache_file_storage_in_dir,
35
+ dump_file_storage_in_dir=dump_file_storage_in_dir,
36
+ settings=settings
37
+ )
38
+
39
+ return transmitted_api_data
40
+
41
+
42
+ @lru_cache()
43
+ def get_transmitted_tg_bot_data() -> TransmittedTgData:
44
+ return create_transmitted_tg_bot_data()
@@ -4,7 +4,7 @@ import asyncio
4
4
  import logging
5
5
  from typing import Optional, Any, Union, Callable, Iterable
6
6
 
7
- from aiogram import types, Bot, Dispatcher
7
+ from aiogram import types, Bot
8
8
  from aiogram.client.default import DefaultBotProperties
9
9
  from aiogram.client.session.aiohttp import AiohttpSession
10
10
  from aiogram.enums import ChatType, ParseMode
@@ -14,10 +14,10 @@ from aiogram.filters.callback_data import CallbackData
14
14
  from pydantic import BaseModel, ConfigDict
15
15
 
16
16
  from arpakitlib.ar_file_storage_in_dir_util import FileStorageInDir
17
- from arpakitlib.ar_json_db_util import JSONDb
17
+ from arpakitlib.ar_json_db_util import BaseJSONDb
18
18
  from arpakitlib.ar_need_type_util import parse_need_type, NeedTypes
19
19
  from arpakitlib.ar_parse_command import BadCommandFormat, parse_command
20
- from arpakitlib.ar_settings_util import SimpleSettings, BaseSettings2
20
+ from arpakitlib.ar_settings_util import BaseSettings2
21
21
  from arpakitlib.ar_sqlalchemy_util import SQLAlchemyDb
22
22
  from arpakitlib.ar_type_util import raise_for_types, raise_for_type
23
23
 
@@ -325,7 +325,7 @@ class SimpleTransmittedTgBotData(BaseTransmittedTgBotData):
325
325
 
326
326
  class AdvancedTransmittedTgBotData(SimpleTransmittedTgBotData):
327
327
  sqlalchemy_db: SQLAlchemyDb | None = None
328
- json_db: JSONDb | None = None
328
+ json_db: BaseJSONDb | None = None
329
329
  media_file_storage_in_dir: FileStorageInDir | None = None
330
330
  cache_file_storage_in_dir: FileStorageInDir | None = None
331
331
  dump_file_storage_in_dir: FileStorageInDir | None = None
@@ -334,7 +334,7 @@ class AdvancedTransmittedTgBotData(SimpleTransmittedTgBotData):
334
334
  def create_aiogram_tg_bot(*, token: str, proxy_url_: str | None = None, **kwargs) -> Bot:
335
335
  kwargs["token"] = token
336
336
 
337
- if proxy_url_:
337
+ if proxy_url_ is not None:
338
338
  kwargs["session"] = AiohttpSession(proxy=proxy_url_)
339
339
 
340
340
  if kwargs.get("default") is None:
@@ -349,18 +349,6 @@ def create_aiogram_tg_bot(*, token: str, proxy_url_: str | None = None, **kwargs
349
349
  return tg_bot
350
350
 
351
351
 
352
- # def create_tg_bot_dispatcher(
353
- # *,
354
- # settings:
355
- # ):
356
- # tg_dp = Dispatcher(
357
- # storage=MemoryStorage(),
358
- # settings=get_settings(),
359
- # db=db,
360
- # transmitted_tg_bot_data=transmitted_tg_bot_data
361
- # )
362
-
363
-
364
352
  def __example():
365
353
  pass
366
354
 
@@ -31,7 +31,7 @@ from arpakitlib.ar_enumeration_util import Enumeration
31
31
  from arpakitlib.ar_exception_util import exception_to_traceback_str
32
32
  from arpakitlib.ar_file_storage_in_dir_util import FileStorageInDir
33
33
  from arpakitlib.ar_func_util import raise_if_not_async_func, is_async_object
34
- from arpakitlib.ar_json_db_util import JSONDb
34
+ from arpakitlib.ar_json_db_util import BaseJSONDb
35
35
  from arpakitlib.ar_json_util import safely_transfer_obj_to_json_str_to_json_obj, safely_transfer_obj_to_json_str
36
36
  from arpakitlib.ar_settings_util import BaseSettings2
37
37
  from arpakitlib.ar_sqlalchemy_model_util import StoryLogDBM, OperationDBM
@@ -538,7 +538,7 @@ class SimpleTransmittedAPIData(BaseTransmittedAPIData):
538
538
 
539
539
  class AdvancedTransmittedAPIData(SimpleTransmittedAPIData):
540
540
  sqlalchemy_db: SQLAlchemyDb | None = None
541
- json_db: JSONDb | None = None
541
+ json_db: BaseJSONDb | None = None
542
542
  media_file_storage_in_dir: FileStorageInDir | None = None
543
543
  cache_file_storage_in_dir: FileStorageInDir | None = None
544
544
  dump_file_storage_in_dir: FileStorageInDir | None = None
@@ -13,7 +13,7 @@ _ARPAKIT_LIB_MODULE_VERSION = "3.0"
13
13
 
14
14
  class JSONDbFile:
15
15
 
16
- def __init__(self, *, filepath: str, use_memory: bool = True, beautify_json: bool = True):
16
+ def __init__(self, *, filepath: str, use_memory: bool = True, beautify_json: bool = True, **kwargs):
17
17
  self._logger = logging.getLogger(self.__class__.__name__)
18
18
  raise_for_type(filepath, str)
19
19
  filepath = os.path.abspath(filepath.strip())
@@ -173,9 +173,9 @@ class JSONDbFile:
173
173
  os.remove(self.filepath)
174
174
 
175
175
 
176
- class JSONDb:
176
+ class BaseJSONDb:
177
177
 
178
- def __init__(self, json_db_files: Optional[list[JSONDbFile]] = None):
178
+ def __init__(self, json_db_files: list[JSONDbFile] | None = None, **kwargs):
179
179
  self._logger = logging.getLogger(self.__class__.__name__)
180
180
  if json_db_files is None:
181
181
  json_db_files = []
@@ -190,7 +190,9 @@ class JSONDb:
190
190
  def __len__(self) -> int:
191
191
  return len(self.json_db_files)
192
192
 
193
- def create_json_db_file(self, filepath: str, use_memory: bool = False, beautify_json: bool = False) -> JSONDbFile:
193
+ def create_json_db_file(
194
+ self, filepath: str, use_memory: bool = False, beautify_json: bool = False, **kwargs
195
+ ) -> JSONDbFile:
194
196
  json_db_file = JSONDbFile(filepath=filepath, use_memory=use_memory, beautify_json=beautify_json)
195
197
  self.json_db_files.append(json_db_file)
196
198
  return json_db_file
@@ -215,7 +217,7 @@ class JSONDb:
215
217
  json_db_file.rm_all_records()
216
218
 
217
219
  def copy_files_to_dir(self, to_dirpath: str) -> Self:
218
- json_db = JSONDb()
220
+ json_db = BaseJSONDb()
219
221
  for json_db_file in self.json_db_files:
220
222
  filepath = os.path.join(to_dirpath, json_db_file.filename)
221
223
  json_db_file.copy(filepath)
@@ -322,6 +322,7 @@ class OperationExecutorWorker(BaseWorker):
322
322
  timeout_after_err_in_run=timedelta(seconds=0.3),
323
323
  startup_funcs=startup_funcs,
324
324
  )
325
+ raise_for_type(sqlalchemy_db, SQLAlchemyDb)
325
326
  self.sqlalchemy_db = sqlalchemy_db
326
327
  if operation_executor is None:
327
328
  operation_executor = BaseOperationExecutor(sqlalchemy_db=sqlalchemy_db)
@@ -393,6 +394,7 @@ class ScheduledOperationCreatorWorker(BaseWorker):
393
394
  timeout_after_err_in_run=timedelta(seconds=0.3),
394
395
  startup_funcs=startup_funcs
395
396
  )
397
+ raise_for_type(sqlalchemy_db, SQLAlchemyDb)
396
398
  self.sqlalchemy_db = sqlalchemy_db
397
399
  if scheduled_operations is None:
398
400
  scheduled_operations = []
@@ -82,41 +82,22 @@ class SimpleSettings(BaseSettings2):
82
82
  class AdvancedSettings(SimpleSettings):
83
83
  project_name: str | None = None
84
84
 
85
- sql_db_user: str | None = None
85
+ @field_validator("project_name", mode="after")
86
+ def validate_project_name(cls, v: Any, validation_info: ValidationInfo, **kwargs) -> str | None:
87
+ if isinstance(v, str):
88
+ return v.strip()
89
+ return v
86
90
 
87
- @field_validator("sql_db_user", mode="after")
88
- def validate_sql_db_user(cls, v: Any, validation_info: ValidationInfo, **kwargs) -> str | None:
89
- if v is not None:
90
- return v
91
- res = validation_info.data.get("project_name")
92
- if res is not None:
93
- return res
94
- return res
91
+ sql_db_user: str | None = None
95
92
 
96
93
  sql_db_password: str | None = None
97
94
 
98
- @field_validator("sql_db_password", mode="after")
99
- def validate_sql_db_password(cls, v: Any, validation_info: ValidationInfo, **kwargs) -> str | None:
100
- if v is not None:
101
- return v
102
- res = validation_info.data.get("project_name")
103
- if res is not None:
104
- return res
105
- return res
95
+ sql_db_host: str | None = None
106
96
 
107
- sql_db_port: int | None = int("50506") if "50506".strip().isdigit() else None
97
+ sql_db_port: int | None = None
108
98
 
109
99
  sql_db_database: str | None = None
110
100
 
111
- @field_validator("sql_db_database", mode="after")
112
- def validate_sql_db_database(cls, v: Any, validation_info: ValidationInfo, **kwargs) -> str | None:
113
- if v is not None:
114
- return v
115
- res = validation_info.data.get("project_name")
116
- if res is not None:
117
- return res
118
- return res
119
-
120
101
  sync_sql_db_url: str | None = None
121
102
 
122
103
  @field_validator("sync_sql_db_url", mode="after")
@@ -128,6 +109,7 @@ class AdvancedSettings(SimpleSettings):
128
109
  base="postgresql",
129
110
  user=validation_info.data.get("sql_db_user"),
130
111
  password=validation_info.data.get("sql_db_password"),
112
+ host=validation_info.data.get("sql_db_host"),
131
113
  port=validation_info.data.get("sql_db_port"),
132
114
  database=validation_info.data.get("sql_db_database")
133
115
  )
@@ -143,10 +125,19 @@ class AdvancedSettings(SimpleSettings):
143
125
  base="postgresql+asyncpg",
144
126
  user=validation_info.data.get("sql_db_user"),
145
127
  password=validation_info.data.get("sql_db_password"),
128
+ host=validation_info.data.get("sql_db_host"),
146
129
  port=validation_info.data.get("sql_db_port"),
147
130
  database=validation_info.data.get("sql_db_database")
148
131
  )
149
132
 
133
+ @property
134
+ def is_any_sql_db_url_set(self) -> bool:
135
+ if self.sync_sql_db_url is not None:
136
+ return True
137
+ if self.async_sql_db_url is not None:
138
+ return True
139
+ return False
140
+
150
141
  sql_db_echo: bool = False
151
142
 
152
143
  api_port: int | None = None
@@ -158,21 +149,35 @@ class AdvancedSettings(SimpleSettings):
158
149
  return int(v)
159
150
  return None
160
151
 
161
- api_init_sql_db_at_start: bool = True
152
+ api_init_sql_db: bool = False
153
+
154
+ api_init_json_db: bool = False
162
155
 
163
156
  api_logging__api_func_before_in_handle_exception: bool = True
164
157
 
165
- api_story_log__api_func_before_in_handle_exception: bool = True
158
+ api_story_log__api_func_before_in_handle_exception: bool = False
166
159
 
167
- api_correct_api_key: str | None = "1"
160
+ api_correct_api_key: str | None = "test"
168
161
 
169
- api_correct_token: str | None = "1"
162
+ api_correct_token: str | None = "test"
170
163
 
171
- api_enable_admin1: bool = True
164
+ api_enable_admin1: bool = False
165
+
166
+ api_start_operation_executor_worker: bool = False
167
+
168
+ api_start_scheduled_operation_creator_worker: bool = False
172
169
 
173
170
  admin1_secret_key: str | None = "85a9583cb91c4de7a78d7eb1e5306a04418c9c43014c447ea8ec8dd5deb4cf71"
174
171
 
175
- var_dirpath: str | None = "./var"
172
+ tg_bot_token: str | None = None
173
+
174
+ tg_bot_proxy_url: str | None = None
175
+
176
+ tg_bot_init_sql_db: bool = False
177
+
178
+ tg_bot_init_json_db: bool = False
179
+
180
+ var_dirpath: str | None = None
176
181
 
177
182
  log_filepath: str | None = None
178
183
 
@@ -224,6 +229,18 @@ class AdvancedSettings(SimpleSettings):
224
229
  def local_timezone_as_pytz(self) -> Any:
225
230
  return pytz.timezone(self.local_timezone)
226
231
 
232
+ json_db_dirpath: str | None = None
233
+
234
+ @field_validator("json_db_dirpath", mode="after")
235
+ def validate_json_db_dirpath(cls, v: Any, validation_info: ValidationInfo, **kwargs) -> str | None:
236
+ if v is not None:
237
+ return v
238
+ var_dirpath = validation_info.data.get("var_dirpath")
239
+ if var_dirpath is None:
240
+ return None
241
+ project_name = validation_info.data.get("project_name")
242
+ return os.path.join(var_dirpath, f"{project_name}_json_db")
243
+
227
244
 
228
245
  def __example():
229
246
  print(safely_transfer_obj_to_json_str(AdvancedSettings(var_dirpath="./var").model_dump(mode="json")))
@@ -29,47 +29,31 @@ def generate_sqlalchemy_url(
29
29
  base: str = "postgresql",
30
30
  user: str | None = None,
31
31
  password: str | None = None,
32
- host: str = "127.0.0.1",
33
- port: int | None = None,
32
+ host: str | None = "127.0.0.1",
33
+ port: int | None = 5432,
34
34
  database: str | None = None,
35
35
  **query_params
36
- ) -> str:
37
- """
38
- Генерация URL для SQLAlchemy.
39
-
40
- :param base: Базовая строка для подключения, например "postgresql+asyncpg" или "sqlite".
41
- :param user: Имя пользователя (необязательно).
42
- :param password: Пароль (необязательно).
43
- :param host: Хост (по умолчанию "127.0.0.1").
44
- :param port: Порт (необязательно).
45
- :param database: Имя базы данных или путь к файлу для SQLite (необязательно).
46
- :param query_params: Дополнительные параметры строки подключения.
47
- :return: Строка подключения для SQLAlchemy.
48
- """
49
- # Формируем часть с авторизацией
36
+ ) -> str | None:
37
+ if host is None or port is None:
38
+ return None
39
+
50
40
  auth_part = ""
51
41
  if user and password:
52
42
  auth_part = f"{quote_plus(user)}:{quote_plus(password)}@"
53
43
  elif user:
54
44
  auth_part = f"{quote_plus(user)}@"
55
45
 
56
- # Формируем часть с хостом и портом
57
- host_part = ""
58
46
  if base.startswith("sqlite"):
59
- # Для SQLite хост и порт не нужны
60
47
  host_part = ""
61
48
  else:
62
49
  host_part = f"{host}"
63
50
  if port:
64
51
  host_part += f":{port}"
65
52
 
66
- # Формируем часть с базой данных
67
53
  database_part = f"/{database}" if database else ""
68
54
  if base.startswith("sqlite") and database:
69
- # Для SQLite путь указывается как абсолютный
70
55
  database_part = f"/{database}"
71
56
 
72
- # Дополнительные параметры
73
57
  query_part = ""
74
58
  if query_params:
75
59
  query_items = [f"{key}={quote_plus(str(value))}" for key, value in query_params.items()]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: arpakitlib
3
- Version: 1.7.253
3
+ Version: 1.7.255
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/alembic/README,sha256=MVlc9TYmr57RbhXET6Qxg
8
8
  arpakitlib/_arpakit_project_template/alembic/env.py,sha256=GeYi-LT3-qhqv1HlGv8K6r4qvPN0J2Uzf2oADS5_kz8,2309
9
9
  arpakitlib/_arpakit_project_template/alembic/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
10
10
  arpakitlib/_arpakit_project_template/alembic.ini,sha256=8fuyeEvGBiPGbxEFy8ISBV3xX_fgVmuhEGpB10_B5Uo,3733
11
- arpakitlib/_arpakit_project_template/example.env,sha256=IUDWwKPGCxqnMV3H_HhnG5LUhRk0M1MNOmPeJBhIMsU,482
11
+ arpakitlib/_arpakit_project_template/example.env,sha256=MUfcOsyT6Rszy9KHrrenj8rNSYH4KLf_Mo-PPlTdQ8Y,659
12
12
  arpakitlib/_arpakit_project_template/manage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  arpakitlib/_arpakit_project_template/manage/alembic_upgrade_head .sh,sha256=RIkhv5e5ERZHoxmTvvo_nCeDeVqeVIam7CjVoE9_E4k,38
14
14
  arpakitlib/_arpakit_project_template/manage/docker_ps.sh,sha256=uwm8vHgeuNLCOn0o9hgP_uc-PUkS9FwLyzZh6ItZ3do,15
@@ -65,9 +65,9 @@ arpakitlib/_arpakit_project_template/src/api/_start_api_without_reload.py,sha256
65
65
  arpakitlib/_arpakit_project_template/src/api/asgi.py,sha256=a5UBxOyNC8NG3E0ayhiDo3t5tPoB3WtOf2gbZJFWBAA,74
66
66
  arpakitlib/_arpakit_project_template/src/api/auth.py,sha256=Ul-4vt-DcgfearD12YF4-WSO_O6zvBTowQ64mtH3VTc,1569
67
67
  arpakitlib/_arpakit_project_template/src/api/const.py,sha256=7d4qD5hedqr7QxVzbfsA7E1bNZn2Pm2U8joXGtpANu0,287
68
- arpakitlib/_arpakit_project_template/src/api/create_api_app.py,sha256=oQrpmBXwRMquX1p8TFuYjqicSzAnhPTPRJNtCh0Gp0w,2494
68
+ arpakitlib/_arpakit_project_template/src/api/create_api_app.py,sha256=gyISI_loKbGkPndOm9bbGBpTV9us87Xisp89Q27EUH0,1551
69
69
  arpakitlib/_arpakit_project_template/src/api/create_handle_exception_.py,sha256=su4fToBIKWFtcdPFaYo2z1TFfpk3VfALpMlWH48HOr0,2247
70
- arpakitlib/_arpakit_project_template/src/api/event.py,sha256=nnTt9yAMHQvsJEY8qFsikPNxzYQpweUqYaWr4srG36U,3555
70
+ arpakitlib/_arpakit_project_template/src/api/event.py,sha256=ypwVgLEexeTwrJSwIe3EzB8ZMe9nP7lXfELE7hH0CnM,3312
71
71
  arpakitlib/_arpakit_project_template/src/api/router/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
72
  arpakitlib/_arpakit_project_template/src/api/router/main_router.py,sha256=Yv699WCJDcdiJMXFg1kPTvolqj-NAGoXfqe-vzbMzIU,228
73
73
  arpakitlib/_arpakit_project_template/src/api/router/v1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -78,16 +78,23 @@ arpakitlib/_arpakit_project_template/src/api/schema/v1/__init__.py,sha256=47DEQp
78
78
  arpakitlib/_arpakit_project_template/src/api/schema/v1/in_.py,sha256=dcvj5C9E2F2KCsGZPBBncQf_EvVJAC1qQgnyD8P4ZEw,6
79
79
  arpakitlib/_arpakit_project_template/src/api/schema/v1/out.py,sha256=dcvj5C9E2F2KCsGZPBBncQf_EvVJAC1qQgnyD8P4ZEw,6
80
80
  arpakitlib/_arpakit_project_template/src/api/transmitted_api_data.py,sha256=ITI-Fsnf7cG0e5c7u0G90Ex6NYzo-8YsqI5Z3JUgJx0,199
81
- arpakitlib/_arpakit_project_template/src/api/util.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
+ arpakitlib/_arpakit_project_template/src/api/util.py,sha256=8vCupzPJty1iDhhF3L_a6WkEN9k_QhyBZ68oTzv9o_o,1525
82
82
  arpakitlib/_arpakit_project_template/src/business_service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
83
  arpakitlib/_arpakit_project_template/src/business_service/hello_world.py,sha256=mEVxsTFsd5u_T88l4mtCfoPre9QixAmQvzQmM2J8Okc,247
84
84
  arpakitlib/_arpakit_project_template/src/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
85
  arpakitlib/_arpakit_project_template/src/core/_check_logging.py,sha256=APQp8jQa3vQwuEt6nayPdu6GmCPHvVdAvv63RaCdHTs,225
86
86
  arpakitlib/_arpakit_project_template/src/core/_generate_settings_env_example.py,sha256=SiEJe8AYQPOWicsaCwf9RdXp6UAmfkBdBT18AAInGb4,483
87
- arpakitlib/_arpakit_project_template/src/core/_show_settings.py,sha256=BQUcr-yj3cxz5GQo0jXe99wMoqHKrrrKD3-UovsJAt0,284
87
+ arpakitlib/_arpakit_project_template/src/core/_show_settings.py,sha256=yBj_44WWHagc-xXagqFrs6GRnlVd6BVxykZNXnJaTvg,339
88
88
  arpakitlib/_arpakit_project_template/src/core/const.py,sha256=e2Y0NIQHfzm3bmnbQnGy3Z5YKt6OYnIsRoqVY8oIV2E,1008
89
89
  arpakitlib/_arpakit_project_template/src/core/settings.py,sha256=1tQwIvYvwAxY7Dz1LY6-EvxkG3hfYSPTmwq_frC4xRM,655
90
90
  arpakitlib/_arpakit_project_template/src/core/util.py,sha256=mcikqcjljZa2qhYeoR1tR9JUSprrVSod8XcIK_PqS6o,1547
91
+ arpakitlib/_arpakit_project_template/src/json_db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
+ arpakitlib/_arpakit_project_template/src/json_db/_drop_json_db.py,sha256=PHv9_T2sd8DjyeQDIlb01_tw_eiUMiQzdUHH2xlel7M,300
93
+ arpakitlib/_arpakit_project_template/src/json_db/_init_json_db.py,sha256=R29pYLmtRmrZxdcCgFCxRFR4N6Nvyc54HpEB-qklgew,198
94
+ arpakitlib/_arpakit_project_template/src/json_db/_reinit_json_db.py,sha256=8uzocDpTiuJjqa-FK7n4j2k8Biamh8iXtVlG_EHw70k,302
95
+ arpakitlib/_arpakit_project_template/src/json_db/_rm_all_records_in_json_db.py,sha256=-p3mt4-DzAEWQFNyKlopzOQJL-K1rZQIVlFSFUtNrz4,310
96
+ arpakitlib/_arpakit_project_template/src/json_db/json_db.py,sha256=IiQGiu7t-TsviVHnyVp6bUcRWVM0GXAqj7KzwL1QjMI,314
97
+ arpakitlib/_arpakit_project_template/src/json_db/util.py,sha256=nUT3aM2R5FTWlUAmAAFfidLXAn-OZKGKCgUyHGhPxK8,358
91
98
  arpakitlib/_arpakit_project_template/src/just_script/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
99
  arpakitlib/_arpakit_project_template/src/just_script/example.py,sha256=Wr5DcSV_zpRFIMR7_ERrtAXzCoTHJEDU_AAT8BvaCi4,271
93
100
  arpakitlib/_arpakit_project_template/src/operation_execution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -126,7 +133,7 @@ arpakitlib/_arpakit_project_template/src/tg_bot/blank/__init__.py,sha256=47DEQpj
126
133
  arpakitlib/_arpakit_project_template/src/tg_bot/blank/blank.py,sha256=ylQGIhLV3CMEW9qmQ4jr9rcXi0B72qIhbRmx9VLBzHc,204
127
134
  arpakitlib/_arpakit_project_template/src/tg_bot/blank/util.py,sha256=zhMRY4BUA8XMhfo8R4Jri655w4fwl0uniGq48SjchrY,247
128
135
  arpakitlib/_arpakit_project_template/src/tg_bot/const.py,sha256=oz6kWH00rtu4WvAMnrR4CNgT8rVl-gyMqEqWuZwwyZM,578
129
- arpakitlib/_arpakit_project_template/src/tg_bot/event.py,sha256=YMwoBH8TQhdjoTQBrxoxOvJqHqlw1yYVE5ymDp2D_Ak,1260
136
+ arpakitlib/_arpakit_project_template/src/tg_bot/event.py,sha256=sgAy0eFEvVeYCizOK_T35N0hSbSeOZGtB1mwW9-6S6w,1489
130
137
  arpakitlib/_arpakit_project_template/src/tg_bot/filter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
131
138
  arpakitlib/_arpakit_project_template/src/tg_bot/filter/not_prod_mode.py,sha256=uzkYsquQ5UKD68lEqe0478rbKFQYXZhbLIbxW0QhI44,235
132
139
  arpakitlib/_arpakit_project_template/src/tg_bot/filter/prod_mode.py,sha256=8zqDSSm3cqWmdoarZOh0hIjSLFQS9szVXnkibSJev30,228
@@ -143,11 +150,12 @@ arpakitlib/_arpakit_project_template/src/tg_bot/middleware/__init__.py,sha256=47
143
150
  arpakitlib/_arpakit_project_template/src/tg_bot/router/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
144
151
  arpakitlib/_arpakit_project_template/src/tg_bot/router/error.py,sha256=5ktxguLc2pI7BUlJ9jgMp_VnH5gtOt1jzJZskKkmhzI,53
145
152
  arpakitlib/_arpakit_project_template/src/tg_bot/router/router.py,sha256=ZxfPNouuewz3uEW7jLxXdCuT7v-HVjl9YagrKbUMzwc,151
146
- arpakitlib/_arpakit_project_template/src/tg_bot/start_tg_bot.py,sha256=7JWCdhyRyYkwV198PjKl6YPqPl7qr-_1Z2tVItfPZlQ,218
153
+ arpakitlib/_arpakit_project_template/src/tg_bot/start_tg_bot.py,sha256=o9q4VhaCi8jkdAC6O8PUnp5F9Ljvz13Qr6KHFlmWkj4,141
147
154
  arpakitlib/_arpakit_project_template/src/tg_bot/transmitted_tg_data.py,sha256=mjElzmxXaY4fODCG-C-gRvQ0MfbftB0uwYro7G84w3U,201
155
+ arpakitlib/_arpakit_project_template/src/tg_bot/util.py,sha256=guMMaJMkU0DTueMUYnNbH3Kpkd4YqhJ_CxgAhUmCPZo,1532
148
156
  arpakitlib/_arpakit_project_template/src/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
149
157
  arpakitlib/ar_additional_model_util.py,sha256=GFg-glLCxH9X95R2bhTJsscVwv37FgE1qbaAAyXrnIE,917
150
- arpakitlib/ar_aiogram_util.py,sha256=hthpbt69CbDTAA3YbaPI3wfYU0aPWqunuV-TzUzv_Q8,12849
158
+ arpakitlib/ar_aiogram_util.py,sha256=fDrca_IT-REDQLVVAwFYPyPZtNWZrJxGKdT1H6gh5Pc,12590
151
159
  arpakitlib/ar_api_key_util.py,sha256=E84JlJXiDHtxLQmV8BNHvqNKu_G8-Dox0XxknYJQ37Q,422
152
160
  arpakitlib/ar_arpakit_lib_module_util.py,sha256=g9uWwTK2eEzmErqwYeVgXDYVMREN8m5CdmgEumAEQfw,5919
153
161
  arpakitlib/ar_arpakit_project_template_util.py,sha256=zJXIFlFrO_3Xvg3ZqIiY6UZjKSbiFr8SQ99YKyZ86BE,3241
@@ -186,14 +194,14 @@ arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.css,sha256=jzPZlgJTFwSdSphk9C
186
194
  arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.css.map,sha256=5wq8eXMLU6Zxb45orZPL1zAsBFJReFw6GjYqGpUX3hg,262650
187
195
  arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.js,sha256=ffrLZHHEQ_g84A-ul3yWa10Kk09waOAxHcQXPuZuavg,339292
188
196
  arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.js.map,sha256=9UhIW7MqCOZPAz1Sl1IKfZUuhWU0p-LJqrnjjJD9Xhc,1159454
189
- arpakitlib/ar_fastapi_util.py,sha256=U339X9DWRTb-lwTds-nH1ry1O_ufcYL1pm-9-CfawXw,29578
197
+ arpakitlib/ar_fastapi_util.py,sha256=o4-o5v0dCEYOq_qJSn7Fy0vRWFDoTf-BjxRm_Hz5wWM,29586
190
198
  arpakitlib/ar_file_storage_in_dir_util.py,sha256=D3e3rGuHoI6xqAA5mVvEpVVpOWY1jyjNsjj2UhyHRbE,3674
191
199
  arpakitlib/ar_file_util.py,sha256=GUdJYm1tUZnYpY-SIPRHAZBHGra8NKy1eYEI0D5AfhY,489
192
200
  arpakitlib/ar_func_util.py,sha256=bCuWbSMoFXBaMNhb89sevj2oaXRk4Jk6Qjot8OXMDT4,1319
193
201
  arpakitlib/ar_hash_util.py,sha256=Iqy6KBAOLBQMFLWv676boI5sV7atT2B-fb7aCdHOmIQ,340
194
202
  arpakitlib/ar_http_request_util.py,sha256=sXzpwtHKJJqoQhwMCIxcexDONqW6GAPBRCC0VmBj1tc,5052
195
203
  arpakitlib/ar_ip_util.py,sha256=aEAa1Hvobh9DWX7cmBAPLqnXSTiKe2hRk-WJaiKMaI8,1009
196
- arpakitlib/ar_json_db_util.py,sha256=CEyhIU4WuNmX5mqwBVYxUKSdpFelXvWmf_tJ1fuxMSE,7187
204
+ arpakitlib/ar_json_db_util.py,sha256=5nELpAY1_5_iTN4nMcutQtJQ5Nt52-xiKELxEH65RkY,7240
197
205
  arpakitlib/ar_json_util.py,sha256=wJOsN8N7Rs7r8cTgMDXrmFa1GOkcD-LghqFEYXc8zGA,1083
198
206
  arpakitlib/ar_jwt_util.py,sha256=Rhm4ywoTAn6yOV8NLjDASfAtAtheROxxDP40G3XjnuQ,761
199
207
  arpakitlib/ar_list_of_dicts_to_xlsx.py,sha256=MyjEl4Jl4beLVZqLVQMMv0-XDtBD3Xh4Z_ZPDJeFu04,745
@@ -202,18 +210,18 @@ arpakitlib/ar_logging_util.py,sha256=V4jypypFG1cj4nXae7JiBnRRfm02OTnZSEermx-wlDY
202
210
  arpakitlib/ar_mongodb_util.py,sha256=2ECkTnGAZ92qxioL-fmN6R4yZOSr3bXdXLWTzT1C3vk,4038
203
211
  arpakitlib/ar_need_type_util.py,sha256=GETiREPMEYhch-yU6T--Bdawlbb04Jp1Qy7cOsUlIeA,2228
204
212
  arpakitlib/ar_openai_api_client_util.py,sha256=_XmlApvHFMSyjvZydPa_kASIt9LsFrZmSC7YEzIG8Bg,1806
205
- arpakitlib/ar_operation_execution_util.py,sha256=OC_PqwGSoTsupcs2gSwIqxuw68udtYKnPKJBgezbOPY,17908
213
+ arpakitlib/ar_operation_execution_util.py,sha256=cBqxwVFsnG9d7vxR9bNBV9cYoX1kAhxA8jl_pta0neM,18012
206
214
  arpakitlib/ar_parse_command.py,sha256=-s61xcATIsfw1eV_iD3xi-grsitbGzSDoAFc5V0OFy4,3447
207
215
  arpakitlib/ar_postgresql_util.py,sha256=1AuLjEaa1Lg4pzn-ukCVnDi35Eg1k91APRTqZhIJAdo,945
208
216
  arpakitlib/ar_rat_func_util.py,sha256=xDO3gcmZZ0VsTF5zwqyfrkct8FWcKmyl1KUwfdA1s4k,2009
209
217
  arpakitlib/ar_retry_func_util.py,sha256=EQtXhn0RvMiyaes9HMDBgMh_WjMIaGwds01UrKKDaBM,2204
210
218
  arpakitlib/ar_run_cmd_util.py,sha256=D_rPavKMmWkQtwvZFz-Io5Ak8eSODHkcFeLPzNVC68g,1072
211
219
  arpakitlib/ar_schedule_uust_api_client_util.py,sha256=HhAIps0QS9ZsacPWhTrMkUUBxuqXBC2lcEzfLlxNs2g,6980
212
- arpakitlib/ar_settings_util.py,sha256=iNP_gBdQMb5YcBzOPxInBL-28EhFmwYDV3I2u2cVi2A,7503
220
+ arpakitlib/ar_settings_util.py,sha256=7Svyre79YPqyhI8mamGtqND3qcnRYuKF491LkktPv7Q,7876
213
221
  arpakitlib/ar_sleep_util.py,sha256=OaLtRaJQWMkGjfj_mW1RB2P4RaSWsAIH8LUoXqsH0zM,1061
214
222
  arpakitlib/ar_sqladmin_util.py,sha256=6Nv9VQssk9PB0piyuss__soYKdjVhdbIeXIv4AgUxmQ,2660
215
223
  arpakitlib/ar_sqlalchemy_model_util.py,sha256=270RNSiccC5l55o8EFerh1SawlEsD99BpgwANSQA0UM,6418
216
- arpakitlib/ar_sqlalchemy_util.py,sha256=IqylYuC7ds8rrmJXTzCEnJkE1MCj-cMDWuP-la0bS4A,8199
224
+ arpakitlib/ar_sqlalchemy_util.py,sha256=mKqnpz2Ea-wn5mSQW5AjBKczcIbVyBQedH_n0Nh9uRc,7098
217
225
  arpakitlib/ar_ssh_runner_util.py,sha256=e9deuUdBW7Eh0Exx2nTBhk57SaOZYaJaSjNk8q6dbJk,6804
218
226
  arpakitlib/ar_steam_payment_api_client_util.py,sha256=onvb3jt9bWfsCLbVLaApbN_-cqCu1CduVhM9GhG5yTA,250
219
227
  arpakitlib/ar_str_util.py,sha256=yU5gOwNXUQaH5b_tM5t6fXUn9oUcv5EQbVnq2wXXIpQ,3378
@@ -221,8 +229,8 @@ arpakitlib/ar_type_util.py,sha256=9C3ErtUVs0tAUqtK-foFzjJOykfBOntfCz2IogDOgfA,41
221
229
  arpakitlib/ar_wata_api_client.py,sha256=gdHOqDbuqxhTjVDtRW1DvkRJLdDofCrOq51GTctzLns,242
222
230
  arpakitlib/ar_yookassa_api_client_util.py,sha256=VozuZeCJjmLd1zj2BdC9WfiAQ3XYOrIMsdpNK-AUlm0,5347
223
231
  arpakitlib/ar_zabbix_api_client_util.py,sha256=Q-VR4MvoZ9aHwZeYZr9G3LwN-ANx1T5KFmF6pvPM-9M,6402
224
- arpakitlib-1.7.253.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
225
- arpakitlib-1.7.253.dist-info/METADATA,sha256=C2YyQ87MAPIH1AxNCWUAOr7d1LOw4uyanGfMEmzL-9M,3386
226
- arpakitlib-1.7.253.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
227
- arpakitlib-1.7.253.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
228
- arpakitlib-1.7.253.dist-info/RECORD,,
232
+ arpakitlib-1.7.255.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
233
+ arpakitlib-1.7.255.dist-info/METADATA,sha256=bqljhWjFG_GK1_aPoI66VlvhL2a1DsWL-C1EXuPjMTM,3386
234
+ arpakitlib-1.7.255.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
235
+ arpakitlib-1.7.255.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
236
+ arpakitlib-1.7.255.dist-info/RECORD,,