arpakitlib 1.7.257__py3-none-any.whl → 1.8.1__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 (294) hide show
  1. arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/README.md +1 -1
  2. arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/alembic/env.py +3 -3
  3. arpakitlib/_arpakit_project_template_v_1/api/asgi.py +3 -0
  4. arpakitlib/_arpakit_project_template_v_1/api/auth.py +235 -0
  5. arpakitlib/_arpakit_project_template_v_1/api/const.py +18 -0
  6. arpakitlib/_arpakit_project_template_v_1/api/create_api_app.py +71 -0
  7. arpakitlib/_arpakit_project_template_v_1/api/event.py +74 -0
  8. arpakitlib/_arpakit_project_template_v_1/api/exception.py +38 -0
  9. arpakitlib/_arpakit_project_template_v_1/api/exception_handler.py +308 -0
  10. arpakitlib/_arpakit_project_template_v_1/api/openapi_ui.py +28 -0
  11. arpakitlib/_arpakit_project_template_v_1/api/response.py +31 -0
  12. arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/api/router/main_router.py +4 -3
  13. arpakitlib/_arpakit_project_template_v_1/api/router/v1/arpakit_project_template.py +22 -0
  14. arpakitlib/_arpakit_project_template_v_1/api/router/v1/check_auth.py +30 -0
  15. arpakitlib/_arpakit_project_template_v_1/api/router/v1/clear_log_file.py +25 -0
  16. arpakitlib/_arpakit_project_template_v_1/api/router/v1/get_errors_info.py +24 -0
  17. arpakitlib/_arpakit_project_template_v_1/api/router/v1/get_log_file.py +23 -0
  18. arpakitlib/_arpakit_project_template_v_1/api/router/v1/healthcheck.py +21 -0
  19. arpakitlib/_arpakit_project_template_v_1/api/router/v1/main_router.py +67 -0
  20. arpakitlib/_arpakit_project_template_v_1/api/router/v1/now_utc_datetime.py +21 -0
  21. arpakitlib/_arpakit_project_template_v_1/api/router/v1/raise_fake_error.py +35 -0
  22. arpakitlib/_arpakit_project_template_v_1/api/schema/base_schema.py +26 -0
  23. arpakitlib/_arpakit_project_template_v_1/api/schema/common/in_.py +5 -0
  24. arpakitlib/_arpakit_project_template_v_1/api/schema/common/out.py +60 -0
  25. arpakitlib/_arpakit_project_template_v_1/api/schema/v1/in_.py +5 -0
  26. arpakitlib/_arpakit_project_template_v_1/api/schema/v1/out.py +47 -0
  27. arpakitlib/_arpakit_project_template_v_1/arpakitlib_project_template.json +3 -0
  28. arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/business_service/hello_world.py +1 -1
  29. arpakitlib/_arpakit_project_template_v_1/business_service/remove_operations.py +51 -0
  30. arpakitlib/_arpakit_project_template_v_1/command/alembic_history.sh +2 -0
  31. arpakitlib/_arpakit_project_template_v_1/command/alembic_revision_autogenerate.sh +2 -0
  32. arpakitlib/{_arpakit_project_template/manage/json_beautify.py → _arpakit_project_template_v_1/command/beautify_json.py} +2 -2
  33. arpakitlib/{_arpakit_project_template/src/core/_check_logging.py → _arpakit_project_template_v_1/command/check_logging.py} +3 -3
  34. arpakitlib/_arpakit_project_template_v_1/command/check_sqlalchemy_db.py +11 -0
  35. arpakitlib/_arpakit_project_template_v_1/command/drop_json_db.py +13 -0
  36. arpakitlib/_arpakit_project_template_v_1/command/drop_sqlalchemy_db.py +14 -0
  37. arpakitlib/{_arpakit_project_template/src/core/_generate_settings_env_example.py → _arpakit_project_template_v_1/command/generate_settings_env_example.py} +4 -4
  38. arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/hello_world.py +2 -2
  39. arpakitlib/_arpakit_project_template_v_1/command/init_json_db.py +11 -0
  40. arpakitlib/_arpakit_project_template_v_1/command/init_sqlalchemy_db.py +11 -0
  41. arpakitlib/_arpakit_project_template_v_1/command/reinit_json_db.py +13 -0
  42. arpakitlib/_arpakit_project_template_v_1/command/reinit_sqlalchemy_db.py +13 -0
  43. arpakitlib/_arpakit_project_template_v_1/command/remove_operations.py +13 -0
  44. arpakitlib/_arpakit_project_template_v_1/command/remove_story_logs.py +16 -0
  45. arpakitlib/_arpakit_project_template_v_1/command/rm_all_records_in_json_db.py +13 -0
  46. arpakitlib/{_arpakit_project_template/src/core/_show_settings.py → _arpakit_project_template_v_1/command/show_settings.py} +3 -3
  47. arpakitlib/{_arpakit_project_template/src/api/_start_api_with_reload.py → _arpakit_project_template_v_1/command/start_api_with_reload.py} +5 -5
  48. arpakitlib/{_arpakit_project_template/src/api/_start_api_without_reload.py → _arpakit_project_template_v_1/command/start_api_without_reload.py} +5 -5
  49. arpakitlib/_arpakit_project_template_v_1/command/start_async_operation_executor_worker.py +14 -0
  50. arpakitlib/_arpakit_project_template_v_1/command/start_async_scheduled_operation_creator_worker.py +14 -0
  51. arpakitlib/_arpakit_project_template_v_1/command/start_sync_operation_executor_worker.py +15 -0
  52. arpakitlib/_arpakit_project_template_v_1/command/start_sync_operation_executor_workers.py +22 -0
  53. arpakitlib/_arpakit_project_template_v_1/command/start_sync_scheduled_operation_creator_worker.py +12 -0
  54. arpakitlib/_arpakit_project_template_v_1/core/cache_file_storage_in_dir.py +23 -0
  55. arpakitlib/_arpakit_project_template_v_1/core/const.py +33 -0
  56. arpakitlib/_arpakit_project_template_v_1/core/dump_file_storage_in_dir.py +23 -0
  57. arpakitlib/_arpakit_project_template_v_1/core/jinja2_templates.py +14 -0
  58. arpakitlib/_arpakit_project_template_v_1/core/media_file_storage_in_dir.py +23 -0
  59. arpakitlib/_arpakit_project_template_v_1/core/settings.py +195 -0
  60. arpakitlib/_arpakit_project_template_v_1/core/util.py +29 -0
  61. arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/example.env +13 -7
  62. arpakitlib/_arpakit_project_template_v_1/json_db/json_db.py +28 -0
  63. arpakitlib/_arpakit_project_template_v_1/operation_execution/operation_executor_worker.py +256 -0
  64. arpakitlib/_arpakit_project_template_v_1/operation_execution/scheduled_operation_creator_worker.py +106 -0
  65. arpakitlib/_arpakit_project_template_v_1/operation_execution/scheduled_operations.py +49 -0
  66. arpakitlib/_arpakit_project_template_v_1/operation_execution/util.py +29 -0
  67. arpakitlib/_arpakit_project_template_v_1/resource/static/openapi-favicon.png +0 -0
  68. arpakitlib/_arpakit_project_template_v_1/resource/static/swagger-ui/index.html +19 -0
  69. arpakitlib/_arpakit_project_template_v_1/resource/static/swagger-ui/swagger-ui-bundle.js +2 -0
  70. arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-ui-es-bundle-core.js +1 -1
  71. arpakitlib/_arpakit_project_template_v_1/resource/static/swagger-ui/swagger-ui-es-bundle-core.js.map +1 -0
  72. arpakitlib/_arpakit_project_template_v_1/resource/static/swagger-ui/swagger-ui-es-bundle.js +2 -0
  73. arpakitlib/_arpakit_project_template_v_1/resource/static/swagger-ui/swagger-ui-standalone-preset.js +2 -0
  74. arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-ui.js +1 -1
  75. arpakitlib/_arpakit_project_template_v_1/resource/static/swagger-ui/swagger-ui.js.map +1 -0
  76. arpakitlib/_arpakit_project_template_v_1/sandbox/sandbox_1.py +14 -0
  77. arpakitlib/_arpakit_project_template_v_1/sandbox/sandbox_2.py +14 -0
  78. arpakitlib/_arpakit_project_template_v_1/sandbox/sandbox_3.py +14 -0
  79. arpakitlib/_arpakit_project_template_v_1/sandbox/sandbox_4.py +14 -0
  80. arpakitlib/_arpakit_project_template_v_1/sandbox/sandbox_5.py +14 -0
  81. arpakitlib/_arpakit_project_template_v_1/sandbox/sandbox_6.py +14 -0
  82. arpakitlib/_arpakit_project_template_v_1/sandbox/sandbox_7.py +14 -0
  83. arpakitlib/_arpakit_project_template_v_1/site/router/main_router.py +3 -0
  84. arpakitlib/_arpakit_project_template_v_1/sqladmin_/add_admin_in_app.py +24 -0
  85. arpakitlib/_arpakit_project_template_v_1/sqladmin_/admin_auth.py +54 -0
  86. arpakitlib/_arpakit_project_template_v_1/sqladmin_/model_view.py +95 -0
  87. arpakitlib/_arpakit_project_template_v_1/sqlalchemy_db/sqlalchemy_db.py +22 -0
  88. arpakitlib/_arpakit_project_template_v_1/sqlalchemy_db/sqlalchemy_model.py +129 -0
  89. arpakitlib/_arpakit_project_template_v_1/sqlalchemy_db/util.py +28 -0
  90. arpakitlib/{_arpakit_project_template/src/sandbox/sandbox_3.py → _arpakit_project_template_v_1/test_data/make_test_data_1.py} +8 -3
  91. arpakitlib/{_arpakit_project_template/src/sandbox/sandbox_4.py → _arpakit_project_template_v_1/test_data/make_test_data_2.py} +8 -3
  92. arpakitlib/{_arpakit_project_template/src/sandbox/sandbox_1.py → _arpakit_project_template_v_1/test_data/make_test_data_3.py} +8 -3
  93. arpakitlib/{_arpakit_project_template/src/sandbox/sandbox_2.py → _arpakit_project_template_v_1/test_data/make_test_data_4.py} +8 -3
  94. arpakitlib/_arpakit_project_template_v_1/test_data/make_test_data_5.py +22 -0
  95. arpakitlib/_arpakit_project_template_v_1/tg_bot/blank/blank.py +5 -0
  96. arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/tg_bot/blank/util.py +1 -1
  97. arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/tg_bot/const.py +6 -3
  98. arpakitlib/_arpakit_project_template_v_1/tg_bot/event.py +51 -0
  99. arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/tg_bot/filter/not_prod_mode.py +1 -1
  100. arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/tg_bot/filter/prod_mode.py +1 -1
  101. arpakitlib/_arpakit_project_template_v_1/tg_bot/kb/static_/__init__.py +0 -0
  102. arpakitlib/_arpakit_project_template_v_1/tg_bot/kb/static_/common.py +0 -0
  103. arpakitlib/_arpakit_project_template_v_1/tg_bot/middleware/__init__.py +0 -0
  104. arpakitlib/_arpakit_project_template_v_1/tg_bot/middleware/init_user.py +24 -0
  105. arpakitlib/_arpakit_project_template_v_1/tg_bot/middleware/middleware.py +12 -0
  106. arpakitlib/_arpakit_project_template_v_1/tg_bot/router/__init__.py +0 -0
  107. arpakitlib/_arpakit_project_template_v_1/tg_bot/router/arpakitlib_.py +10 -0
  108. arpakitlib/_arpakit_project_template_v_1/tg_bot/router/error.py +15 -0
  109. arpakitlib/_arpakit_project_template_v_1/tg_bot/router/healthcheck.py +10 -0
  110. arpakitlib/_arpakit_project_template_v_1/tg_bot/router/main_router.py +14 -0
  111. arpakitlib/_arpakit_project_template_v_1/tg_bot/start_tg_bot.py +34 -0
  112. arpakitlib/_arpakit_project_template_v_1/tg_bot/tg_bot.py +24 -0
  113. arpakitlib/_arpakit_project_template_v_1/tg_bot/tg_bot_dispatcher.py +19 -0
  114. arpakitlib/_arpakit_project_template_v_1/tg_bot/transmitted_tg_data.py +58 -0
  115. arpakitlib/_arpakit_project_template_v_1/tg_bot/util.py +0 -0
  116. arpakitlib/_arpakit_project_template_v_1/util/__init__.py +0 -0
  117. arpakitlib/_arpakit_project_template_v_1/util/read_arpakitlib_project_template_file.py +17 -0
  118. arpakitlib/ar_aiogram_util.py +41 -52
  119. arpakitlib/ar_arpakit_project_template_util.py +5 -11
  120. arpakitlib/ar_arpakitlib_cli_util.py +8 -2
  121. arpakitlib/ar_base_worker_util.py +35 -17
  122. arpakitlib/ar_class_util.py +11 -0
  123. arpakitlib/ar_func_util.py +19 -29
  124. arpakitlib/ar_http_request_util.py +10 -2
  125. arpakitlib/ar_rat_func_util.py +1 -1
  126. arpakitlib/ar_retry_func_util.py +4 -4
  127. arpakitlib/ar_schedule_uust_api_client_util.py +1 -1
  128. arpakitlib/ar_settings_util.py +3 -204
  129. arpakitlib/ar_sqladmin_util.py +7 -102
  130. arpakitlib/ar_sqlalchemy_util.py +65 -13
  131. arpakitlib/ar_type_util.py +0 -2
  132. {arpakitlib-1.7.257.dist-info → arpakitlib-1.8.1.dist-info}/METADATA +5 -3
  133. arpakitlib-1.8.1.dist-info/RECORD +261 -0
  134. {arpakitlib-1.7.257.dist-info → arpakitlib-1.8.1.dist-info}/WHEEL +1 -1
  135. arpakitlib/_arpakit_project_template/ARPAKITLIB +0 -1
  136. arpakitlib/_arpakit_project_template/manage/docker_ps.sh +0 -2
  137. arpakitlib/_arpakit_project_template/manage/git_branch.sh +0 -2
  138. arpakitlib/_arpakit_project_template/manage/poetry_add_plugin_export.sh +0 -2
  139. arpakitlib/_arpakit_project_template/manage/poetry_config_virtualenvs_in_project_true.sh +0 -2
  140. arpakitlib/_arpakit_project_template/manage/poetry_self_add_plugin_export.sh +0 -2
  141. arpakitlib/_arpakit_project_template/src/admin1/add_admin_in_app.py +0 -32
  142. arpakitlib/_arpakit_project_template/src/admin1/admin_auth.py +0 -29
  143. arpakitlib/_arpakit_project_template/src/admin1/model_view.py +0 -1
  144. arpakitlib/_arpakit_project_template/src/api/asgi.py +0 -3
  145. arpakitlib/_arpakit_project_template/src/api/auth.py +0 -53
  146. arpakitlib/_arpakit_project_template/src/api/const.py +0 -13
  147. arpakitlib/_arpakit_project_template/src/api/create_api_app.py +0 -43
  148. arpakitlib/_arpakit_project_template/src/api/create_handle_exception_.py +0 -59
  149. arpakitlib/_arpakit_project_template/src/api/event.py +0 -83
  150. arpakitlib/_arpakit_project_template/src/api/router/v1/get_api_error_info.py +0 -27
  151. arpakitlib/_arpakit_project_template/src/api/router/v1/main_router.py +0 -15
  152. arpakitlib/_arpakit_project_template/src/api/schema/v1/in_.py +0 -1
  153. arpakitlib/_arpakit_project_template/src/api/schema/v1/out.py +0 -1
  154. arpakitlib/_arpakit_project_template/src/api/transmitted_api_data.py +0 -7
  155. arpakitlib/_arpakit_project_template/src/api/util.py +0 -44
  156. arpakitlib/_arpakit_project_template/src/core/const.py +0 -41
  157. arpakitlib/_arpakit_project_template/src/core/settings.py +0 -21
  158. arpakitlib/_arpakit_project_template/src/core/util.py +0 -61
  159. arpakitlib/_arpakit_project_template/src/json_db/_drop_json_db.py +0 -13
  160. arpakitlib/_arpakit_project_template/src/json_db/_init_json_db.py +0 -11
  161. arpakitlib/_arpakit_project_template/src/json_db/_reinit_json_db.py +0 -13
  162. arpakitlib/_arpakit_project_template/src/json_db/_rm_all_records_in_json_db.py +0 -13
  163. arpakitlib/_arpakit_project_template/src/json_db/json_db.py +0 -11
  164. arpakitlib/_arpakit_project_template/src/json_db/util.py +0 -17
  165. arpakitlib/_arpakit_project_template/src/just_script/example.py +0 -16
  166. arpakitlib/_arpakit_project_template/src/operation_execution/_start_operation_executor_worker.py +0 -17
  167. arpakitlib/_arpakit_project_template/src/operation_execution/_start_scheduled_operation_creator_worker.py +0 -17
  168. arpakitlib/_arpakit_project_template/src/operation_execution/const.py +0 -9
  169. arpakitlib/_arpakit_project_template/src/operation_execution/operation_executor.py +0 -16
  170. arpakitlib/_arpakit_project_template/src/operation_execution/scheduled_operations.py +0 -29
  171. arpakitlib/_arpakit_project_template/src/operation_execution/util.py +0 -1
  172. arpakitlib/_arpakit_project_template/src/sandbox/sandbox_5.py +0 -17
  173. arpakitlib/_arpakit_project_template/src/sandbox/sandbox_6.py +0 -17
  174. arpakitlib/_arpakit_project_template/src/sandbox/sandbox_7.py +0 -17
  175. arpakitlib/_arpakit_project_template/src/sqlalchemy_db/_check_conn_sqlalchemy_db.py +0 -11
  176. arpakitlib/_arpakit_project_template/src/sqlalchemy_db/_drop_sqlalchemy_db.py +0 -13
  177. arpakitlib/_arpakit_project_template/src/sqlalchemy_db/_init_sqlalchemy_db.py +0 -11
  178. arpakitlib/_arpakit_project_template/src/sqlalchemy_db/_reinit_sqlalchemy_db.py +0 -13
  179. arpakitlib/_arpakit_project_template/src/sqlalchemy_db/_remove_operations.py +0 -15
  180. arpakitlib/_arpakit_project_template/src/sqlalchemy_db/_remove_story_logs.py +0 -16
  181. arpakitlib/_arpakit_project_template/src/sqlalchemy_db/sqlalchemy_model.py +0 -13
  182. arpakitlib/_arpakit_project_template/src/sqlalchemy_db/util.py +0 -27
  183. arpakitlib/_arpakit_project_template/src/test_data/make_test_data_1.py +0 -8
  184. arpakitlib/_arpakit_project_template/src/test_data/make_test_data_2.py +0 -8
  185. arpakitlib/_arpakit_project_template/src/test_data/make_test_data_3.py +0 -8
  186. arpakitlib/_arpakit_project_template/src/test_data/make_test_data_4.py +0 -8
  187. arpakitlib/_arpakit_project_template/src/test_data/make_test_data_5.py +0 -8
  188. arpakitlib/_arpakit_project_template/src/tg_bot/blank/blank.py +0 -10
  189. arpakitlib/_arpakit_project_template/src/tg_bot/event.py +0 -39
  190. arpakitlib/_arpakit_project_template/src/tg_bot/router/error.py +0 -3
  191. arpakitlib/_arpakit_project_template/src/tg_bot/router/router.py +0 -7
  192. arpakitlib/_arpakit_project_template/src/tg_bot/start_tg_bot.py +0 -11
  193. arpakitlib/_arpakit_project_template/src/tg_bot/transmitted_tg_data.py +0 -6
  194. arpakitlib/_arpakit_project_template/src/tg_bot/util.py +0 -44
  195. arpakitlib/ar_api_key_util.py +0 -21
  196. arpakitlib/ar_fastapi_static/swagger-ui/index.html +0 -19
  197. arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-bundle.js +0 -2
  198. arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-es-bundle-core.js.map +0 -1
  199. arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-es-bundle.js +0 -2
  200. arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-standalone-preset.js +0 -2
  201. arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.js.map +0 -1
  202. arpakitlib/ar_fastapi_util.py +0 -862
  203. arpakitlib/ar_operation_execution_util.py +0 -504
  204. arpakitlib/ar_sqlalchemy_model_util.py +0 -183
  205. arpakitlib-1.7.257.dist-info/RECORD +0 -236
  206. /arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/.gitignore +0 -0
  207. /arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/.python-version +0 -0
  208. /arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/LICENSE +0 -0
  209. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/additional_model}/__init__.py +0 -0
  210. /arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/additional_model/additional_model.py +0 -0
  211. /arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/alembic/README +0 -0
  212. /arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/alembic/script.py.mako +0 -0
  213. /arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/alembic.ini +0 -0
  214. /arpakitlib/{_arpakit_project_template/manage/note → _arpakit_project_template_v_1/api}/__init__.py +0 -0
  215. /arpakitlib/{_arpakit_project_template/resource → _arpakit_project_template_v_1/api/router}/__init__.py +0 -0
  216. /arpakitlib/{_arpakit_project_template/resource/static → _arpakit_project_template_v_1/api/router/v1}/__init__.py +0 -0
  217. /arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1/api/schema}/__init__.py +0 -0
  218. /arpakitlib/{_arpakit_project_template/src/additional_model → _arpakit_project_template_v_1/api/schema/common}/__init__.py +0 -0
  219. /arpakitlib/{_arpakit_project_template/src/admin1 → _arpakit_project_template_v_1/api/schema/v1}/__init__.py +0 -0
  220. /arpakitlib/{_arpakit_project_template/manage/note/note_1.txt → _arpakit_project_template_v_1/api/util.py} +0 -0
  221. /arpakitlib/{_arpakit_project_template/src/api → _arpakit_project_template_v_1/business_service}/__init__.py +0 -0
  222. /arpakitlib/{_arpakit_project_template/src/api/router → _arpakit_project_template_v_1/celery_}/__init__.py +0 -0
  223. /arpakitlib/{_arpakit_project_template/src/api/router/v1 → _arpakit_project_template_v_1/command}/__init__.py +0 -0
  224. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/alembic_upgrade_head .sh +0 -0
  225. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/docker_ps_a.sh +0 -0
  226. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/docker_rm_postgres.sh +0 -0
  227. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/docker_run_postgres.sh +0 -0
  228. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/docker_start_postgres.sh +0 -0
  229. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/docker_stop_postgres.sh +0 -0
  230. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_commit.sh +0 -0
  231. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_push_arpakit_company_github_1.sh +0 -0
  232. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_push_arpakit_company_gitlab_1.sh +0 -0
  233. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_push_arpakit_github_1.sh +0 -0
  234. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_push_arpakit_gitlab_1.sh +0 -0
  235. /arpakitlib/{_arpakit_project_template/manage/git_remote_v.sh → _arpakit_project_template_v_1/command/git_remote.sh} +0 -0
  236. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_set_arpakit_company_origin.sh +0 -0
  237. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_set_arpakit_origin.sh +0 -0
  238. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_status.sh +0 -0
  239. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_check.sh +0 -0
  240. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_clear_cache.sh +0 -0
  241. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_config.sh +0 -0
  242. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_install.sh +0 -0
  243. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_lock.sh +0 -0
  244. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_remove_and_add_arpakitlib.sh +0 -0
  245. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_show.sh +0 -0
  246. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_show_arpakitlib.sh +0 -0
  247. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_update.sh +0 -0
  248. /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_update_arpakitlib.sh +0 -0
  249. /arpakitlib/{_arpakit_project_template/src/api/schema → _arpakit_project_template_v_1/core}/__init__.py +0 -0
  250. /arpakitlib/{_arpakit_project_template/src/api/schema/v1 → _arpakit_project_template_v_1/json_db}/__init__.py +0 -0
  251. /arpakitlib/{_arpakit_project_template/src/business_service → _arpakit_project_template_v_1/note}/__init__.py +0 -0
  252. /arpakitlib/{_arpakit_project_template/manage/note/note_2.txt → _arpakit_project_template_v_1/note/note_1.txt} +0 -0
  253. /arpakitlib/{_arpakit_project_template/manage/note/note_3.txt → _arpakit_project_template_v_1/note/note_2.txt} +0 -0
  254. /arpakitlib/{_arpakit_project_template/manage/note/note_4.txt → _arpakit_project_template_v_1/note/note_3.txt} +0 -0
  255. /arpakitlib/{_arpakit_project_template/manage/note/note_5.txt → _arpakit_project_template_v_1/note/note_4.txt} +0 -0
  256. /arpakitlib/{_arpakit_project_template/src/core/__init__.py → _arpakit_project_template_v_1/note/note_5.txt} +0 -0
  257. /arpakitlib/{_arpakit_project_template/src/json_db → _arpakit_project_template_v_1/operation_execution}/__init__.py +0 -0
  258. /arpakitlib/{_arpakit_project_template/src/just_script/__init__.py → _arpakit_project_template_v_1/operation_execution/const.py} +0 -0
  259. /arpakitlib/{_arpakit_project_template/src/operation_execution → _arpakit_project_template_v_1/resource}/__init__.py +0 -0
  260. /arpakitlib/{_arpakit_project_template/resource/static/healthcheck → _arpakit_project_template_v_1/resource/static/1} +0 -0
  261. /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/healthcheck +0 -0
  262. /arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/resource/static/helloworld +0 -0
  263. /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/redoc/redoc.standalone.js +0 -0
  264. /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/favicon-16x16.png +0 -0
  265. /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/favicon-32x32.png +0 -0
  266. /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/index.css +0 -0
  267. /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/oauth2-redirect.html +0 -0
  268. /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-initializer.js +0 -0
  269. /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-ui-bundle.js.map +0 -0
  270. /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-ui-es-bundle.js.map +0 -0
  271. /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-ui-standalone-preset.js.map +0 -0
  272. /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-ui.css +0 -0
  273. /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-ui.css.map +0 -0
  274. /arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/sandbox/__init__.py +0 -0
  275. /arpakitlib/{_arpakit_project_template/src/sqlalchemy_db → _arpakit_project_template_v_1/site}/__init__.py +0 -0
  276. /arpakitlib/{_arpakit_project_template/src/test_data/__init__.py → _arpakit_project_template_v_1/site/asgi.py} +0 -0
  277. /arpakitlib/{_arpakit_project_template/src/tg_bot/__init__.py → _arpakit_project_template_v_1/site/consts.py} +0 -0
  278. /arpakitlib/{_arpakit_project_template/src/tg_bot/blank/__init__.py → _arpakit_project_template_v_1/site/create_site_app.py} +0 -0
  279. /arpakitlib/{_arpakit_project_template/src/tg_bot/filter/__init__.py → _arpakit_project_template_v_1/site/event.py} +0 -0
  280. /arpakitlib/{_arpakit_project_template/src/tg_bot/handler/__init__.py → _arpakit_project_template_v_1/site/exception_handler.py} +0 -0
  281. /arpakitlib/{_arpakit_project_template/src/tg_bot/kb → _arpakit_project_template_v_1/site/router}/__init__.py +0 -0
  282. /arpakitlib/{_arpakit_project_template/src/tg_bot/kb/inline_ → _arpakit_project_template_v_1/sqladmin_}/__init__.py +0 -0
  283. /arpakitlib/{_arpakit_project_template/src/tg_bot/kb/static_ → _arpakit_project_template_v_1/sqlalchemy_db}/__init__.py +0 -0
  284. /arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/sqlalchemy_db/const.py +0 -0
  285. /arpakitlib/{_arpakit_project_template/src/tg_bot/middleware → _arpakit_project_template_v_1/test_data}/__init__.py +0 -0
  286. /arpakitlib/{_arpakit_project_template/src/tg_bot/router → _arpakit_project_template_v_1/tg_bot}/__init__.py +0 -0
  287. /arpakitlib/{_arpakit_project_template/src/util → _arpakit_project_template_v_1/tg_bot/blank}/__init__.py +0 -0
  288. /arpakitlib/{_arpakit_project_template/src/tg_bot/handler/cmd_arpakitlib.py → _arpakit_project_template_v_1/tg_bot/filter/__init__.py} +0 -0
  289. /arpakitlib/{_arpakit_project_template/src/tg_bot/handler/cmd_healthcheck.py → _arpakit_project_template_v_1/tg_bot/kb/__init__.py} +0 -0
  290. /arpakitlib/{_arpakit_project_template/src/tg_bot/kb/inline_/callback.py → _arpakit_project_template_v_1/tg_bot/kb/inline_/__init__.py} +0 -0
  291. /arpakitlib/{_arpakit_project_template/src/tg_bot/kb/inline_/common.py → _arpakit_project_template_v_1/tg_bot/kb/inline_/callback.py} +0 -0
  292. /arpakitlib/{_arpakit_project_template/src/tg_bot/kb/static_ → _arpakit_project_template_v_1/tg_bot/kb/inline_}/common.py +0 -0
  293. {arpakitlib-1.7.257.dist-info → arpakitlib-1.8.1.dist-info}/LICENSE +0 -0
  294. {arpakitlib-1.7.257.dist-info → arpakitlib-1.8.1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,23 @@
1
+ from functools import lru_cache
2
+
3
+ from arpakitlib.ar_file_storage_in_dir_util import FileStorageInDir
4
+ from core.settings import get_cached_settings
5
+
6
+
7
+ def create_media_file_storage_in_dir() -> FileStorageInDir | None:
8
+ if get_cached_settings().media_dirpath is None:
9
+ return None
10
+ return FileStorageInDir(dirpath=get_cached_settings().media_dirpath)
11
+
12
+
13
+ @lru_cache()
14
+ def get_cached_media_file_storage_in_dir() -> FileStorageInDir | None:
15
+ return create_media_file_storage_in_dir()
16
+
17
+
18
+ def __example():
19
+ print(get_cached_media_file_storage_in_dir().dirpath)
20
+
21
+
22
+ if __name__ == '__main__':
23
+ __example()
@@ -0,0 +1,195 @@
1
+ import os
2
+ from functools import lru_cache
3
+ from typing import Any
4
+
5
+ import pytz
6
+ from pydantic import field_validator
7
+ from pydantic_core.core_schema import ValidationInfo
8
+
9
+ from arpakitlib.ar_enumeration_util import Enumeration
10
+ from arpakitlib.ar_json_util import safely_transfer_obj_to_json_str
11
+ from arpakitlib.ar_settings_util import SimpleSettings
12
+ from arpakitlib.ar_sqlalchemy_util import generate_sqlalchemy_url
13
+ from core.const import ProjectPaths
14
+
15
+
16
+ class ModeTypes(Enumeration):
17
+ not_prod: str = "not_prod"
18
+ prod: str = "prod"
19
+
20
+
21
+ class Settings(SimpleSettings):
22
+ mode_type: str = ModeTypes.not_prod
23
+
24
+ @field_validator("mode_type")
25
+ @classmethod
26
+ def validate_mode_type(cls, v: Any, validation_info: ValidationInfo, **kwargs):
27
+ if v is None:
28
+ v = ModeTypes.not_prod
29
+ ModeTypes.parse_and_validate_values(v.lower().strip())
30
+ return v
31
+
32
+ @property
33
+ def is_mode_type_not_prod(self) -> bool:
34
+ return self.mode_type == ModeTypes.not_prod
35
+
36
+ def raise_if_mode_type_not_prod(self):
37
+ if self.is_mode_type_not_prod:
38
+ raise ValueError(f"mode type = {self.mode_type}")
39
+
40
+ @property
41
+ def is_mode_type_prod(self) -> bool:
42
+ return self.mode_type == ModeTypes.prod
43
+
44
+ def raise_if_mode_type_prod(self):
45
+ if self.is_mode_type_prod:
46
+ raise ValueError(f"mode type = {self.mode_type}")
47
+
48
+ project_name: str | None = "arpakitlib"
49
+
50
+ sqlalchemy_db_user: str | None = project_name
51
+
52
+ sqlalchemy_db_password: str | None = project_name
53
+
54
+ sqlalchemy_db_host: str | None = "127.0.0.1"
55
+
56
+ sqlalchemy_db_port: int | None = 5432
57
+
58
+ sqlalchemy_db_database: str | None = project_name
59
+
60
+ sqlalchemy_sync_db_url: str | None = None
61
+
62
+ @field_validator("sqlalchemy_sync_db_url", mode="after")
63
+ def validate_sqlalchemy_sync_db_url(cls, v: Any, validation_info: ValidationInfo, **kwargs) -> str | None:
64
+ if v is not None:
65
+ return v
66
+
67
+ return generate_sqlalchemy_url(
68
+ base="postgresql",
69
+ user=validation_info.data.get("sqlalchemy_db_user"),
70
+ password=validation_info.data.get("sqlalchemy_db_password"),
71
+ host=validation_info.data.get("sqlalchemy_db_host"),
72
+ port=validation_info.data.get("sqlalchemy_db_port"),
73
+ database=validation_info.data.get("sqlalchemy_db_database")
74
+ )
75
+
76
+ sqlalchemy_async_db_url: str | None = None
77
+
78
+ @field_validator("sqlalchemy_async_db_url", mode="after")
79
+ def validate_sqlalchemy_async_db_url(cls, v: Any, validation_info: ValidationInfo, **kwargs) -> str | None:
80
+ if v is not None:
81
+ return v
82
+
83
+ return generate_sqlalchemy_url(
84
+ base="postgresql+asyncpg",
85
+ user=validation_info.data.get("sqlalchemy_db_user"),
86
+ password=validation_info.data.get("sqlalchemy_db_password"),
87
+ host=validation_info.data.get("sqlalchemy_db_host"),
88
+ port=validation_info.data.get("sqlalchemy_db_port"),
89
+ database=validation_info.data.get("sqlalchemy_db_database")
90
+ )
91
+
92
+ @property
93
+ def is_any_sql_db_url_set(self) -> bool:
94
+ if self.sqlalchemy_sync_db_url is not None:
95
+ return True
96
+ if self.sqlalchemy_async_db_url is not None:
97
+ return True
98
+ return False
99
+
100
+ sqlalchemy_db_echo: bool = False
101
+
102
+ api_port: int | None = 50519
103
+
104
+ api_init_sqlalchemy_db: bool = False
105
+
106
+ api_init_json_db: bool = False
107
+
108
+ api_correct_api_keys: list[str] | None = ["1"]
109
+
110
+ @field_validator("api_correct_api_keys", mode="before")
111
+ def validate_api_correct_api_keys(cls, v: Any, validation_info: ValidationInfo, **kwargs) -> list[str] | None:
112
+ if isinstance(v, str):
113
+ v = [v]
114
+ if isinstance(v, int):
115
+ v = [str(v)]
116
+ if isinstance(v, list):
117
+ for i, v_ in enumerate(v):
118
+ if isinstance(v_, int):
119
+ v[i] = str(v_)
120
+ return v
121
+
122
+ api_correct_tokens: list[str] | None = ["1"]
123
+
124
+ @field_validator("api_correct_tokens", mode="before")
125
+ def validate_api_correct_tokens(cls, v: Any, validation_info: ValidationInfo, **kwargs) -> list[str] | None:
126
+ if isinstance(v, str):
127
+ v = [v]
128
+ if isinstance(v, int):
129
+ v = [str(v)]
130
+ if isinstance(v, list):
131
+ for i, v_ in enumerate(v):
132
+ if isinstance(v_, int):
133
+ v[i] = str(v_)
134
+ return v
135
+
136
+ api_enable_sqladmin: bool = True
137
+
138
+ api_start_operation_executor_worker: bool = False
139
+
140
+ api_start_scheduled_operation_creator_worker: bool = False
141
+
142
+ api_story_log__api_func_before_in_exception_handler: bool = False
143
+
144
+ sqladmin_secret_key: str | None = "85a9583cb91c4de7a78d7eb1e5306a04418c9c43014c447ea8ec8dd5deb4cf71"
145
+
146
+ sqladmin_correct_passwords: list[str] | None = ["1"]
147
+
148
+ tg_bot_token: str | None = None
149
+
150
+ tg_bot_proxy_url: str | None = None
151
+
152
+ tg_bot_init_sqlalchemy_db: bool = False
153
+
154
+ tg_bot_init_json_db: bool = False
155
+
156
+ tg_bot_webhook_server_hostname: str | None = "127.0.0.1"
157
+
158
+ tg_bot_webhook_server_port: int | None = None
159
+
160
+ tg_bot_webhook_path: str | None = "/tg_bot_webhook"
161
+
162
+ tg_bot_webhook_secret: str | None = "09780c63-22b5-44e2-9b72-f0cf651f7a9a"
163
+
164
+ tg_bot_webhook_url: str | None = None
165
+
166
+ tg_bot_webhook_enabled: bool = False
167
+
168
+ var_dirpath: str | None = os.path.join(ProjectPaths.base_dirpath, "var")
169
+
170
+ log_filepath: str | None = os.path.join(var_dirpath, "story.log")
171
+
172
+ cache_dirpath: str | None = os.path.join(var_dirpath, "cache")
173
+
174
+ media_dirpath: str | None = os.path.join(var_dirpath, "media")
175
+
176
+ dump_dirpath: str | None = os.path.join(var_dirpath, "dump")
177
+
178
+ json_db_dirpath: str | None = os.path.join(var_dirpath, f"{project_name}_json_db")
179
+
180
+ local_timezone: str | None = None
181
+
182
+ @property
183
+ def local_timezone_as_pytz(self) -> Any:
184
+ return pytz.timezone(self.local_timezone)
185
+
186
+
187
+ @lru_cache()
188
+ def get_cached_settings() -> Settings:
189
+ if os.path.exists(ProjectPaths.env_filepath):
190
+ return Settings(_env_file=ProjectPaths.env_filepath, _env_file_encoding="utf-8")
191
+ return Settings()
192
+
193
+
194
+ if __name__ == '__main__':
195
+ print(safely_transfer_obj_to_json_str(get_cached_settings().model_dump(mode="json")))
@@ -0,0 +1,29 @@
1
+ import asyncio
2
+ from datetime import datetime
3
+
4
+ from arpakitlib.ar_datetime_util import now_dt
5
+ from arpakitlib.ar_logging_util import setup_normal_logging
6
+ from arpakitlib.ar_type_util import raise_if_none
7
+ from core.settings import get_cached_settings
8
+
9
+
10
+ def setup_logging():
11
+ setup_normal_logging(log_filepath=get_cached_settings().log_filepath)
12
+
13
+
14
+ def now_local_dt() -> datetime:
15
+ raise_if_none(get_cached_settings().local_timezone_as_pytz)
16
+ return now_dt(tz=get_cached_settings().local_timezone_as_pytz)
17
+
18
+
19
+ def __example():
20
+ pass
21
+
22
+
23
+ async def __async_example():
24
+ pass
25
+
26
+
27
+ if __name__ == '__main__':
28
+ __example()
29
+ asyncio.run(__async_example())
@@ -11,22 +11,28 @@
11
11
  # api_port=
12
12
  # api_init_sqlalchemy_db=
13
13
  # api_init_json_db=
14
- # api_logging__api_func_before_in_handle_exception=
15
- # api_story_log__api_func_before_in_handle_exception=
16
- # api_correct_api_key=
17
- # api_correct_token=
18
- # api_enable_admin1=
14
+ # api_correct_api_keys=
15
+ # api_correct_tokens=
16
+ # api_enable_sqladmin=
19
17
  # api_start_operation_executor_worker=
20
18
  # api_start_scheduled_operation_creator_worker=
21
- # admin1_secret_key=
19
+ # api_story_log__api_func_before_in_exception_handler=
20
+ # sqladmin_secret_key=
21
+ # sqladmin_correct_passwords=
22
22
  # tg_bot_token=
23
23
  # tg_bot_proxy_url=
24
24
  # tg_bot_init_sqlalchemy_db=
25
25
  # tg_bot_init_json_db=
26
+ # tg_bot_webhook_server_hostname=
27
+ # tg_bot_webhook_server_port=
28
+ # tg_bot_webhook_path=
29
+ # tg_bot_webhook_secret=
30
+ # tg_bot_webhook_url=
31
+ # tg_bot_webhook_enabled=
26
32
  # var_dirpath=
27
33
  # log_filepath=
28
34
  # cache_dirpath=
29
35
  # media_dirpath=
30
36
  # dump_dirpath=
31
- # local_timezone=
32
37
  # json_db_dirpath=
38
+ # local_timezone=
@@ -0,0 +1,28 @@
1
+ import os
2
+ from functools import lru_cache
3
+
4
+ from arpakitlib.ar_json_db_util import BaseJSONDb
5
+ from core.settings import get_cached_settings
6
+
7
+
8
+ class JSONDb(BaseJSONDb):
9
+ def __init__(self, dirpath: str):
10
+ super().__init__()
11
+ self.story_log = self.create_json_db_file(
12
+ filepath=os.path.join(dirpath, "story_log.json"), use_memory=True, beautify_json=False
13
+ )
14
+
15
+
16
+ def create_json_db() -> JSONDb | None:
17
+ if get_cached_settings().json_db_dirpath is None:
18
+ return None
19
+ return JSONDb(
20
+ dirpath=get_cached_settings().json_db_dirpath
21
+ )
22
+
23
+
24
+ @lru_cache()
25
+ def get_cached_json_db() -> JSONDb:
26
+ return JSONDb(
27
+ dirpath=get_cached_settings().json_db_dirpath
28
+ )
@@ -0,0 +1,256 @@
1
+ from __future__ import annotations
2
+
3
+ import inspect
4
+ from datetime import timedelta
5
+ from typing import Any
6
+
7
+ import sqlalchemy
8
+ from sqlalchemy import asc
9
+
10
+ from arpakitlib.ar_base_worker_util import BaseWorker
11
+ from arpakitlib.ar_datetime_util import now_utc_dt
12
+ from arpakitlib.ar_dict_util import combine_dicts
13
+ from arpakitlib.ar_exception_util import exception_to_traceback_str
14
+ from arpakitlib.ar_sqlalchemy_util import SQLAlchemyDb
15
+ from arpakitlib.ar_type_util import raise_for_type
16
+ from sqlalchemy_db.sqlalchemy_db import get_cached_sqlalchemy_db
17
+ from sqlalchemy_db.sqlalchemy_model import OperationDBM, StoryLogDBM
18
+
19
+
20
+ class OperationExecutorWorker(BaseWorker):
21
+
22
+ def __init__(
23
+ self,
24
+ *,
25
+ sqlalchemy_db: SQLAlchemyDb,
26
+ filter_operation_types: str | list[str] | None = None,
27
+ startup_funcs: list[Any] | None = None
28
+ ):
29
+ super().__init__(
30
+ timeout_after_run=timedelta(seconds=0.1),
31
+ timeout_after_error_in_run=timedelta(seconds=0.1),
32
+ startup_funcs=startup_funcs,
33
+ )
34
+
35
+ raise_for_type(sqlalchemy_db, SQLAlchemyDb)
36
+ self.sqlalchemy_db = sqlalchemy_db
37
+
38
+ if isinstance(filter_operation_types, str):
39
+ filter_operation_types = [filter_operation_types]
40
+ self.filter_operation_types = filter_operation_types
41
+
42
+ def sync_execute_operation(self, operation_dbm: OperationDBM):
43
+ if operation_dbm.type == OperationDBM.Types.healthcheck_:
44
+ self._logger.info(f"healthcheck {now_utc_dt()}")
45
+ elif operation_dbm.type == OperationDBM.Types.raise_fake_error_:
46
+ self._logger.error(f"{OperationDBM.Types.raise_fake_error_}")
47
+ raise Exception(f"{OperationDBM.Types.raise_fake_error_}")
48
+ # ...
49
+
50
+ async def async_execute_operation(self, *, operation_dbm: OperationDBM):
51
+ if operation_dbm.type == OperationDBM.Types.healthcheck_:
52
+ self._logger.info(f"healthcheck {now_utc_dt()}")
53
+ elif operation_dbm.type == OperationDBM.Types.raise_fake_error_:
54
+ self._logger.error(f"{OperationDBM.Types.raise_fake_error_}")
55
+ raise Exception(f"{OperationDBM.Types.raise_fake_error_}")
56
+ # ...
57
+
58
+ def sync_run(self):
59
+ # 1
60
+ with self.sqlalchemy_db.new_session() as sync_session:
61
+ query = (
62
+ sync_session
63
+ .query(OperationDBM)
64
+ .filter(OperationDBM.status == OperationDBM.Statuses.waiting_for_execution)
65
+ )
66
+ if self.filter_operation_types is not None:
67
+ query = query.filter(OperationDBM.type.in_(self.filter_operation_types))
68
+ query = query.with_for_update()
69
+ query = query.order_by(asc(OperationDBM.creation_dt))
70
+ operation_dbm: OperationDBM | None = query.first()
71
+ if operation_dbm is None:
72
+ return
73
+ operation_dbm.execution_start_dt = now_utc_dt()
74
+ operation_dbm.status = OperationDBM.Statuses.executing
75
+ operation_dbm.output_data = combine_dicts(
76
+ operation_dbm.output_data,
77
+ {
78
+ self.worker_fullname: True,
79
+ f"{inspect.currentframe().f_code.co_name}": True
80
+ }
81
+ )
82
+ sync_session.commit()
83
+ sync_session.refresh(operation_dbm)
84
+
85
+ # 2
86
+ self._logger.info(
87
+ f"start execute_operation"
88
+ f", operation_id={operation_dbm.id}"
89
+ f", operation_type={operation_dbm.type})"
90
+ f", worker_fullname={self.worker_fullname}"
91
+ )
92
+ exception_in_execute_operation: Exception | None = None
93
+ try:
94
+ self.sync_execute_operation(operation_dbm=operation_dbm)
95
+ except Exception as exception:
96
+ self._logger.exception(
97
+ f"exception in execute_operation"
98
+ f", operation_id={operation_dbm.id}"
99
+ f", operation_type={operation_dbm.type}"
100
+ f", worker_fullname={self.worker_fullname}",
101
+ )
102
+ exception_in_execute_operation = exception
103
+
104
+ # 3
105
+ with self.sqlalchemy_db.new_session() as sync_session:
106
+ operation_dbm: OperationDBM = (
107
+ sync_session.query(OperationDBM).with_for_update().filter(OperationDBM.id == operation_dbm.id).one()
108
+ )
109
+ operation_dbm.execution_finish_dt = now_utc_dt()
110
+ if exception_in_execute_operation is not None:
111
+ operation_dbm.status = OperationDBM.Statuses.executed_with_error
112
+ operation_dbm.error_data = combine_dicts(
113
+ operation_dbm.error_data,
114
+ {
115
+ "exception_in_execute_operation": str(exception_in_execute_operation),
116
+ "traceback_str_in_execute_operation": exception_to_traceback_str(
117
+ exception=exception_in_execute_operation
118
+ ),
119
+ }
120
+ )
121
+ else:
122
+ operation_dbm.status = OperationDBM.Statuses.executed_without_error
123
+ sync_session.commit()
124
+ sync_session.refresh(operation_dbm)
125
+ self._logger.info(
126
+ f"finish execute_operation"
127
+ f", operation_id={operation_dbm.id}"
128
+ f", operation_type={operation_dbm.type}"
129
+ f", worker_fullname={self.worker_fullname}"
130
+ )
131
+
132
+ # 4
133
+ if exception_in_execute_operation is not None:
134
+ with self.sqlalchemy_db.new_session() as sync_session:
135
+ story_log_dbm = StoryLogDBM(
136
+ level=StoryLogDBM.Levels.error,
137
+ type=StoryLogDBM.Types.error_in_execute_operation,
138
+ title=(
139
+ f"error in execute_operation"
140
+ f", operation_id={operation_dbm.id}"
141
+ f", operation_type={operation_dbm.type}"
142
+ ),
143
+ data={
144
+ "operation_id": operation_dbm.id,
145
+ "operation_type": operation_dbm.type,
146
+ }
147
+ )
148
+ sync_session.add(story_log_dbm)
149
+ sync_session.commit()
150
+ sync_session.refresh(story_log_dbm)
151
+
152
+ async def async_run(self):
153
+ # 1
154
+ async with self.sqlalchemy_db.new_async_session() as async_session:
155
+ query = (
156
+ sqlalchemy.select(OperationDBM)
157
+ .filter(OperationDBM.status == OperationDBM.Statuses.waiting_for_execution)
158
+ )
159
+ if self.filter_operation_types is not None:
160
+ query = query.filter(OperationDBM.type.in_(self.filter_operation_types))
161
+ query = query.order_by(asc(OperationDBM.creation_dt)).with_for_update()
162
+
163
+ result = await async_session.execute(query)
164
+ operation_dbm = result.scalars().first()
165
+ if operation_dbm is None:
166
+ return
167
+
168
+ operation_dbm.execution_start_dt = now_utc_dt()
169
+ operation_dbm.status = OperationDBM.Statuses.executing
170
+ operation_dbm.output_data = combine_dicts(
171
+ operation_dbm.output_data,
172
+ {
173
+ self.worker_fullname: True,
174
+ f"{inspect.currentframe().f_code.co_name}": True
175
+ }
176
+ )
177
+ await async_session.commit()
178
+ await async_session.refresh(operation_dbm)
179
+
180
+ # 2
181
+ self._logger.info(
182
+ f"start execute_operation"
183
+ f", operation_id={operation_dbm.id}"
184
+ f", operation_type={operation_dbm.type})"
185
+ f", worker_fullname={self.worker_fullname}"
186
+ )
187
+ exception_in_execute_operation = None
188
+ try:
189
+ await self.async_execute_operation(operation_dbm=operation_dbm)
190
+ except Exception as exception:
191
+ self._logger.exception(
192
+ f"exception in execute_operation"
193
+ f", operation_id={operation_dbm.id}"
194
+ f", operation_type={operation_dbm.type}"
195
+ f", worker_fullname={self.worker_fullname}",
196
+ )
197
+ exception_in_execute_operation = exception
198
+
199
+ # 3
200
+ async with self.sqlalchemy_db.new_async_session() as async_session:
201
+ result = await async_session.execute(
202
+ sqlalchemy.select(OperationDBM).filter(OperationDBM.id == operation_dbm.id).with_for_update()
203
+ )
204
+ operation_dbm = result.scalars().one()
205
+ operation_dbm.execution_finish_dt = now_utc_dt()
206
+ if exception_in_execute_operation is not None:
207
+ operation_dbm.status = OperationDBM.Statuses.executed_with_error
208
+ operation_dbm.error_data = combine_dicts(
209
+ {
210
+ "exception_in_execute_operation": str(exception_in_execute_operation),
211
+ "traceback_str_in_execute_operation": exception_to_traceback_str(
212
+ exception=exception_in_execute_operation
213
+ )
214
+ },
215
+ operation_dbm.error_data
216
+ )
217
+ else:
218
+ operation_dbm.status = OperationDBM.Statuses.executed_without_error
219
+ await async_session.commit()
220
+ await async_session.refresh(operation_dbm)
221
+ self._logger.info(
222
+ f"finish execute_operation"
223
+ f", operation_id={operation_dbm.id}"
224
+ f", operation_type={operation_dbm.type}"
225
+ f", worker_fullname={self.worker_fullname}"
226
+ )
227
+
228
+ # 4
229
+ if exception_in_execute_operation is not None:
230
+ async with self.sqlalchemy_db.new_async_session() as async_session:
231
+ story_log_dbm = StoryLogDBM(
232
+ level=StoryLogDBM.Levels.error,
233
+ type=StoryLogDBM.Types.error_in_execute_operation,
234
+ title=(
235
+ f"error in execute_operation"
236
+ f", operation_id={operation_dbm.id}"
237
+ f", operation_type={operation_dbm.type}"
238
+ ),
239
+ data={
240
+ "operation_id": operation_dbm.id,
241
+ "operation_type": operation_dbm.type,
242
+ }
243
+ )
244
+ async_session.add(story_log_dbm)
245
+ await async_session.commit()
246
+ await async_session.refresh(story_log_dbm)
247
+
248
+
249
+ def create_operation_executor_worker(
250
+ *,
251
+ filter_operation_types: str | list[str] | None = None
252
+ ) -> OperationExecutorWorker:
253
+ return OperationExecutorWorker(
254
+ sqlalchemy_db=get_cached_sqlalchemy_db(),
255
+ filter_operation_types=filter_operation_types
256
+ )
@@ -0,0 +1,106 @@
1
+ from datetime import timedelta
2
+ from typing import Any
3
+
4
+ from arpakitlib.ar_base_worker_util import BaseWorker
5
+ from arpakitlib.ar_sleep_util import sync_safe_sleep, async_safe_sleep
6
+ from arpakitlib.ar_sqlalchemy_util import SQLAlchemyDb
7
+ from arpakitlib.ar_type_util import raise_for_type
8
+ from operation_execution.scheduled_operations import ScheduledOperation, get_scheduled_operations
9
+ from sqlalchemy_db.sqlalchemy_db import get_cached_sqlalchemy_db
10
+ from sqlalchemy_db.sqlalchemy_model import OperationDBM
11
+
12
+
13
+ class ScheduledOperationCreatorWorker(BaseWorker):
14
+ def __init__(
15
+ self,
16
+ *,
17
+ sqlalchemy_db: SQLAlchemyDb,
18
+ scheduled_operations: ScheduledOperation | list[ScheduledOperation] | None = None,
19
+ startup_funcs: list[Any] | None = None
20
+ ):
21
+ super().__init__(
22
+ timeout_after_run=timedelta(seconds=0.1),
23
+ timeout_after_error_in_run=timedelta(seconds=0.1),
24
+ startup_funcs=startup_funcs
25
+ )
26
+
27
+ raise_for_type(sqlalchemy_db, SQLAlchemyDb)
28
+ self.sqlalchemy_db = sqlalchemy_db
29
+
30
+ if scheduled_operations is None:
31
+ scheduled_operations = []
32
+ if isinstance(scheduled_operations, ScheduledOperation):
33
+ scheduled_operations = [scheduled_operations]
34
+ raise_for_type(scheduled_operations, list)
35
+ self.scheduled_operations = scheduled_operations
36
+
37
+ def sync_run(self):
38
+ timeout = None
39
+
40
+ for scheduled_operation in self.scheduled_operations:
41
+
42
+ if not scheduled_operation.is_time_func():
43
+ continue
44
+
45
+ with self.sqlalchemy_db.new_session() as session:
46
+ operation_dbm = OperationDBM(
47
+ type=scheduled_operation.type,
48
+ input_data=scheduled_operation.input_data
49
+ )
50
+ session.add(operation_dbm)
51
+ session.commit()
52
+ session.refresh(operation_dbm)
53
+ self._logger.info(
54
+ f"scheduled operation was created"
55
+ f", operation_id={operation_dbm.id}"
56
+ f", operation_type={operation_dbm.type}"
57
+ )
58
+
59
+ if scheduled_operation.timeout_after_creation is not None:
60
+ if timeout is not None:
61
+ if scheduled_operation.timeout_after_creation > timeout:
62
+ timeout = scheduled_operation.timeout_after_creation
63
+ else:
64
+ timeout = scheduled_operation.timeout_after_creation
65
+
66
+ if timeout is not None:
67
+ sync_safe_sleep(n=timeout)
68
+
69
+ async def async_run(self):
70
+ timeout: timedelta | None = None
71
+
72
+ for scheduled_operation in self.scheduled_operations:
73
+
74
+ if not scheduled_operation.is_time_func():
75
+ continue
76
+
77
+ async with self.sqlalchemy_db.new_async_session() as async_session:
78
+ operation_dbm = OperationDBM(
79
+ type=scheduled_operation.type,
80
+ input_data=scheduled_operation.input_data
81
+ )
82
+ async_session.add(operation_dbm)
83
+ await async_session.commit()
84
+ await async_session.refresh(operation_dbm)
85
+ self._logger.info(
86
+ f"scheduled operation was created"
87
+ f", operation_id={operation_dbm.id}"
88
+ f", operation_type={operation_dbm.type}"
89
+ )
90
+
91
+ if scheduled_operation.timeout_after_creation is not None:
92
+ if timeout is not None:
93
+ if scheduled_operation.timeout_after_creation > timeout:
94
+ timeout = scheduled_operation.timeout_after_creation
95
+ else:
96
+ timeout = scheduled_operation.timeout_after_creation
97
+
98
+ if timeout is not None:
99
+ await async_safe_sleep(n=timeout)
100
+
101
+
102
+ def create_scheduled_operation_creator_worker() -> ScheduledOperationCreatorWorker:
103
+ return ScheduledOperationCreatorWorker(
104
+ sqlalchemy_db=get_cached_sqlalchemy_db(),
105
+ scheduled_operations=get_scheduled_operations()
106
+ )