arpakitlib 1.5.33__py3-none-any.whl → 1.5.34__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.
@@ -13,8 +13,19 @@ _ARPAKIT_LIB_MODULE_VERSION = "3.0"
13
13
 
14
14
 
15
15
  class EasySQLAlchemyDB:
16
- def __init__(self, *, db_url: str, echo: bool = False):
16
+ def __init__(
17
+ self,
18
+ *,
19
+ db_url: str,
20
+ echo: bool = False,
21
+ need_include_operation_dbm: bool = False,
22
+ need_include_story_dbm: bool = False
23
+ ):
17
24
  self._logger = logging.getLogger(self.__class__.__name__)
25
+ self.need_include_operation_dbm = need_include_operation_dbm
26
+ self.need_include_story_dbm = need_include_story_dbm
27
+ if self.need_include_operation_dbm:
28
+ self.need_include_story_dbm = True
18
29
  self.engine = create_engine(
19
30
  url=db_url,
20
31
  echo=echo,
@@ -26,6 +37,16 @@ class EasySQLAlchemyDB:
26
37
  self.sessionmaker = sessionmaker(bind=self.engine)
27
38
  self.func_new_session_counter = 0
28
39
 
40
+ def include_operation_dbm(self):
41
+ if self.need_include_operation_dbm:
42
+ from arpakitlib.ar_operation_util import import_ar_operation_execution_util
43
+ import_ar_operation_execution_util()
44
+
45
+ def include_story_dbm(self):
46
+ if self.need_include_story_dbm or self.need_include_operation_dbm:
47
+ from arpakitlib.ar_story_log_util import import_ar_story_util
48
+ import_ar_story_util()
49
+
29
50
  def drop_celery_tables(self):
30
51
  with self.engine.connect() as connection:
31
52
  connection.execute(text("DROP TABLE IF EXISTS celery_tasksetmeta CASCADE;"))
@@ -41,6 +62,8 @@ class EasySQLAlchemyDB:
41
62
  self._logger.info("celery tables data were removed")
42
63
 
43
64
  def init(self):
65
+ self.include_operation_dbm()
66
+ self.include_story_dbm()
44
67
  from arpakitlib.ar_sqlalchemy_model_util import BaseDBM
45
68
  BaseDBM.metadata.create_all(bind=self.engine, checkfirst=True)
46
69
  self._logger.info("db was inited")
@@ -51,6 +74,8 @@ class EasySQLAlchemyDB:
51
74
  self._logger.info("db was dropped")
52
75
 
53
76
  def reinit(self):
77
+ self.include_operation_dbm()
78
+ self.include_story_dbm()
54
79
  from arpakitlib.ar_sqlalchemy_model_util import BaseDBM
55
80
  BaseDBM.metadata.drop_all(bind=self.engine, checkfirst=True)
56
81
  BaseDBM.metadata.create_all(bind=self.engine, checkfirst=True)
@@ -20,6 +20,7 @@ from pydantic import BaseModel, ConfigDict
20
20
  from starlette.middleware.cors import CORSMiddleware
21
21
  from starlette.staticfiles import StaticFiles
22
22
 
23
+ from arpakitlib.ar_easy_sqlalchemy_util import EasySQLAlchemyDB
23
24
  from arpakitlib.ar_enumeration import EasyEnumeration
24
25
 
25
26
  _ARPAKIT_LIB_MODULE_VERSION = "3.0"
@@ -27,9 +28,6 @@ _ARPAKIT_LIB_MODULE_VERSION = "3.0"
27
28
  _logger = logging.getLogger(__name__)
28
29
 
29
30
 
30
- # ---
31
-
32
-
33
31
  class BaseAPISchema(BaseModel):
34
32
  model_config = ConfigDict(extra="ignore", arbitrary_types_allowed=True, from_attributes=True)
35
33
 
@@ -77,9 +75,6 @@ class APIErrorSO(BaseAPISO):
77
75
  error_data: dict[str, Any] = {}
78
76
 
79
77
 
80
- # ---
81
-
82
-
83
78
  class APIJSONResponse(fastapi.responses.JSONResponse):
84
79
  def __init__(self, *, content: BaseAPISO, status_code: int = starlette.status.HTTP_200_OK):
85
80
  super().__init__(
@@ -182,9 +177,6 @@ def from_exception_to_api_json_response(
182
177
  )
183
178
 
184
179
 
185
- # ---
186
-
187
-
188
180
  def add_exception_handler_to_fastapi_app(*, fastapi_app: FastAPI, api_handle_exception_: Callable) -> FastAPI:
189
181
  fastapi_app.add_exception_handler(
190
182
  exc_class_or_status_code=Exception,
@@ -254,34 +246,55 @@ def add_ar_fastapi_static_docs_and_redoc_handlers_to_fastapi_app(
254
246
  return fastapi_app
255
247
 
256
248
 
257
- class BaseAPIEvent:
249
+ class BaseAPIStartupEvent:
258
250
  def __init__(self, *args, **kwargs):
259
251
  self._logger = logging.getLogger(self.__class__.__name__)
260
252
 
261
- async def on_startup(self, *args, **kwargs):
253
+ async def async_on_startup(self, *args, **kwargs):
262
254
  self._logger.info("on_startup starts")
263
255
  self._logger.info("on_startup ends")
264
256
 
265
- async def on_shutdown(self, *args, **kwargs):
257
+
258
+ class BaseAPIShutdownEvent:
259
+ def __init__(self, *args, **kwargs):
260
+ self._logger = logging.getLogger(self.__class__.__name__)
261
+
262
+ async def async_on_shutdown(self, *args, **kwargs):
266
263
  self._logger.info("on_shutdown starts")
267
264
  self._logger.info("on_shutdown ends")
268
265
 
269
266
 
267
+ class APIStartupEventInitEasySQLAlchemyDB(BaseAPIStartupEvent):
268
+ def __init__(self, easy_sqlalchemy_db: EasySQLAlchemyDB):
269
+ super().__init__()
270
+ self.easy_sqlalchemy_db = easy_sqlalchemy_db
271
+
272
+ async def async_on_startup(self, *args, **kwargs):
273
+ self.easy_sqlalchemy_db.init()
274
+
275
+
270
276
  def create_fastapi_app(
271
277
  *,
272
- title: str,
278
+ title: str = "ARPAKITLIB FastAPI",
273
279
  description: str | None = None,
274
- api_event: BaseAPIEvent | None = BaseAPIEvent(),
280
+ api_startup_events: list[BaseAPIStartupEvent] | None = None,
281
+ api_shutdown_events: list[BaseAPIStartupEvent] | None = None,
275
282
  api_handle_exception_: Callable | None = simple_api_handle_exception
276
283
  ):
284
+ if api_startup_events is None:
285
+ api_startup_events = [BaseAPIStartupEvent()]
286
+
287
+ if api_shutdown_events is None:
288
+ api_shutdown_events = [BaseAPIShutdownEvent()]
289
+
277
290
  app = FastAPI(
278
291
  title=title,
279
292
  description=description,
280
293
  docs_url=None,
281
294
  redoc_url=None,
282
295
  openapi_url="/openapi",
283
- on_startup=[api_event.on_startup] if api_event else [],
284
- on_shutdown=[api_event.on_shutdown] if api_event else []
296
+ on_startup=[api_startup_event.async_on_startup for api_startup_event in api_startup_events],
297
+ on_shutdown=[api_shutdown_event.async_on_shutdown for api_shutdown_event in api_shutdown_events]
285
298
  )
286
299
 
287
300
  add_middleware_cors_to_fastapi_app(fastapi_app=app)
@@ -302,9 +315,6 @@ def create_fastapi_app(
302
315
  return app
303
316
 
304
317
 
305
- # ---
306
-
307
-
308
318
  def __example():
309
319
  pass
310
320
 
@@ -16,11 +16,14 @@ from arpakitlib.ar_datetime_util import now_utc_dt
16
16
  from arpakitlib.ar_dict_util import combine_dicts
17
17
  from arpakitlib.ar_easy_sqlalchemy_util import EasySQLAlchemyDB
18
18
  from arpakitlib.ar_enumeration import EasyEnumeration
19
- from arpakitlib.ar_fastapi_util import BaseAPISO, BaseAPISimpleSO
19
+ from arpakitlib.ar_fastapi_util import BaseAPISimpleSO
20
20
  from arpakitlib.ar_sqlalchemy_model_util import SimpleDBM
21
+ from arpakitlib.ar_story_log_util import StoryLogDBM
21
22
 
22
23
  _ARPAKIT_LIB_MODULE_VERSION = "3.0"
23
24
 
25
+ _logger = logging.getLogger(__name__)
26
+
24
27
 
25
28
  class OperationDBM(SimpleDBM):
26
29
  __tablename__ = "operation"
@@ -226,6 +229,7 @@ class BaseOperationExecutor:
226
229
  traceback_str = traceback.format_exc()
227
230
 
228
231
  with self.easy_sql_alchemy_db.new_session() as session:
232
+
229
233
  operation_dbm: OperationDBM = get_operation_by_id(
230
234
  session=session, filter_operation_id=operation_dbm.id, strict=True
231
235
  )
@@ -239,7 +243,21 @@ class BaseOperationExecutor:
239
243
  else:
240
244
  operation_dbm.status = OperationDBM.Statuses.executed_without_error
241
245
  session.commit()
246
+
247
+ story_log_dbm = StoryLogDBM(
248
+ level=StoryLogDBM.Levels.error,
249
+ title="Error in sync_execute_operation",
250
+ data={
251
+ "operation_id": operation_dbm.id,
252
+ "exception": str(exception),
253
+ "traceback_str": traceback_str
254
+ }
255
+ )
256
+ session.add(story_log_dbm)
257
+ session.commit()
258
+
242
259
  session.refresh(operation_dbm)
260
+ session.refresh(story_log_dbm)
243
261
 
244
262
  self._logger.info(
245
263
  f"finish sync_safe_execute_operation"
@@ -306,3 +324,7 @@ class ExecuteOperationWorker(BaseWorker):
306
324
 
307
325
  def sync_run_on_error(self, exception: BaseException, kwargs: dict[str, Any]):
308
326
  self._logger.exception(exception)
327
+
328
+
329
+ def import_ar_operation_execution_util():
330
+ _logger.info("import_ar_operation_execution_util")
@@ -1,4 +1,4 @@
1
- from datetime import datetime
1
+ import logging
2
2
  from typing import Any
3
3
 
4
4
  from sqlalchemy import TEXT
@@ -6,10 +6,11 @@ from sqlalchemy.dialects.postgresql import JSONB
6
6
  from sqlalchemy.orm import Mapped, mapped_column
7
7
 
8
8
  from arpakitlib.ar_enumeration import EasyEnumeration
9
- from arpakitlib.ar_fastapi_util import BaseAPISO, BaseAPISimpleSO
10
- from arpakitlib.ar_sqlalchemy_model_util import BaseDBM, SimpleDBM
9
+ from arpakitlib.ar_fastapi_util import BaseAPISimpleSO
10
+ from arpakitlib.ar_sqlalchemy_model_util import SimpleDBM
11
11
 
12
12
  _ARPAKIT_LIB_MODULE_VERSION = "3.0"
13
+ _logger = logging.getLogger(__name__)
13
14
 
14
15
 
15
16
  class StoryLogDBM(SimpleDBM):
@@ -29,9 +30,11 @@ class StoryLogDBM(SimpleDBM):
29
30
  )
30
31
 
31
32
 
32
- class AdminStoryLogSO(BaseAPISimpleSO):
33
+ class StoryLogSO(BaseAPISimpleSO):
33
34
  level: str
34
35
  title: str | None
35
36
  data: dict[str, Any]
36
37
 
37
38
 
39
+ def import_ar_story_util():
40
+ _logger.info("import_ar_operation_execution_util")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: arpakitlib
3
- Version: 1.5.33
3
+ Version: 1.5.34
4
4
  Summary: arpakitlib
5
5
  Home-page: https://github.com/ARPAKIT-Company/arpakitlib
6
6
  License: Apache-2.0
@@ -14,7 +14,7 @@ arpakitlib/ar_cache_file.py,sha256=m73_vU6bMjXsIurSPO9VCLcHsiHk8ITFS0LNjfI_8Uw,3
14
14
  arpakitlib/ar_datetime_util.py,sha256=Xe1NiT9oPQzNSG7RVRkhukhbg4i-hhS5ImmV7sPUc8o,971
15
15
  arpakitlib/ar_dict_util.py,sha256=cF5LQJ6tLqyGoEXfDljMDZrikeZoWPw7CgINHIFGvXM,419
16
16
  arpakitlib/ar_dream_ai_api_client.py,sha256=hDPL9wbG4MjIuhn2ed6qepueogANIkt-NddhhiPUv0Y,4029
17
- arpakitlib/ar_easy_sqlalchemy_util.py,sha256=HuKRBD4XoxeZ5tpXlDTol5Y6AOzuCBluJQHfyRjlRqs,3224
17
+ arpakitlib/ar_easy_sqlalchemy_util.py,sha256=tHVL5bimXzY7u7TXEH--W7LSebSpN0Y5WN3iWiD8OR8,4180
18
18
  arpakitlib/ar_encrypt_and_decrypt_util.py,sha256=GhWnp7HHkbhwFVVCzO1H07m-5gryr4yjWsXjOaNQm1Y,520
19
19
  arpakitlib/ar_enumeration.py,sha256=6KUJYOabHDPLfdigBVN0ZI4ZOUJh8TkL0g4o92Hke2I,2254
20
20
  arpakitlib/ar_fastapi_static/redoc/redoc.standalone.js,sha256=WCuodUNv1qVh0oW5fjnJDwb5AwOue73jKHdI9z8iGKU,909365
@@ -36,7 +36,7 @@ arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.css,sha256=jzPZlgJTFwSdSphk9C
36
36
  arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.css.map,sha256=5wq8eXMLU6Zxb45orZPL1zAsBFJReFw6GjYqGpUX3hg,262650
37
37
  arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.js,sha256=ffrLZHHEQ_g84A-ul3yWa10Kk09waOAxHcQXPuZuavg,339292
38
38
  arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.js.map,sha256=9UhIW7MqCOZPAz1Sl1IKfZUuhWU0p-LJqrnjjJD9Xhc,1159454
39
- arpakitlib/ar_fastapi_util.py,sha256=lt5ziw_nbueLH71d4QHi8VE2hof6YYqPEwLF2w5vjkE,9864
39
+ arpakitlib/ar_fastapi_util.py,sha256=zuq3bGhCvnGtD3_Axh4vE_Y_-JNg_W_wEBa9gHO9CXY,10718
40
40
  arpakitlib/ar_file_storage_in_dir.py,sha256=D3e3rGuHoI6xqAA5mVvEpVVpOWY1jyjNsjj2UhyHRbE,3674
41
41
  arpakitlib/ar_generate_env_example.py,sha256=WseNlk_So6mTVQ2amMuigWYV4ZVmd940POvXtodoYj0,325
42
42
  arpakitlib/ar_hash_util.py,sha256=Iqy6KBAOLBQMFLWv676boI5sV7atT2B-fb7aCdHOmIQ,340
@@ -51,7 +51,7 @@ arpakitlib/ar_logging_util.py,sha256=c5wX2FLqCzb4aLckLVhIJ7go52rJQ4GN9dIkJ6KMc3o
51
51
  arpakitlib/ar_mongodb_util.py,sha256=2ECkTnGAZ92qxioL-fmN6R4yZOSr3bXdXLWTzT1C3vk,4038
52
52
  arpakitlib/ar_need_type_util.py,sha256=qCRSWlSgx-3yU0NRHZDQ5lCOmuZKcz2Na3py9nr6hJM,1618
53
53
  arpakitlib/ar_openai_util.py,sha256=d5Aj1O2yo_zYLZCLeOLvuveYYxA2jGOqhMs1oUbuVk8,1210
54
- arpakitlib/ar_operation_execution_util.py,sha256=PGyyvJoYAv01MWQl1TNWGamchfIrDkSovLrNMiyKqEg,11770
54
+ arpakitlib/ar_operation_util.py,sha256=miBG6hywKRwFaeE0tUHotAw7MBylRBlXL6YQnBCnfOU,12419
55
55
  arpakitlib/ar_parse_command.py,sha256=qpr2OwG3Bf7DFiL9S3iWgtbvtE80RSC35E5zFJvjG1I,2714
56
56
  arpakitlib/ar_postgresql_util.py,sha256=SAHEmAyMkZe516uk2gS830v_Wn2kRUZUYNcTNwmgXJk,1160
57
57
  arpakitlib/ar_run_cmd.py,sha256=D_rPavKMmWkQtwvZFz-Io5Ak8eSODHkcFeLPzNVC68g,1072
@@ -59,13 +59,13 @@ arpakitlib/ar_schedule_uust_api_client.py,sha256=1JGUy6rrjAXdWjeAqiAOQlCAEV3xuc5
59
59
  arpakitlib/ar_sleep_util.py,sha256=9ZN4Qo4eZ_q3hjM7vNBQjFRcH-9-sqv3QLSjnxVJE90,1405
60
60
  arpakitlib/ar_sqlalchemy_model_util.py,sha256=3zscvaloi9XY1NR70rJ4-jJlFUIqhmTbQ9wdvK-Yjf8,1379
61
61
  arpakitlib/ar_ssh_runner.py,sha256=jlnss4V4pziBN1rBzoK_lDiWm6nMOqGXfa6NFJSKH-Y,6796
62
- arpakitlib/ar_story_log_util.py,sha256=NKzC1nZkjofRTePHhncatO7B25hAFPvIwG45XWjI0tQ,1060
62
+ arpakitlib/ar_story_log_util.py,sha256=RmrjsWHpFvNYPcj6Htplzc6lMnw-f9t_RSIsqyskXeg,1141
63
63
  arpakitlib/ar_str_util.py,sha256=xSEzmsDvRiZVaxyqFFjcgzpphktCbXg2FHcvsd1DYpA,1885
64
64
  arpakitlib/ar_type_util.py,sha256=-h-SCsVl11eVo1u4hy2Asn0IfD5TIxmX3Ndug4AvnPE,1761
65
65
  arpakitlib/ar_yookassa_api_client.py,sha256=BwsTygaXf35AACVBl_09uYlSD_t-U1OOzbj58OOFT4Q,6480
66
66
  arpakitlib/ar_zabbix_util.py,sha256=MTQbmS0QpNCKNOGONNQHf6j7KTZsKGlIbd5rCH0R0WI,6313
67
- arpakitlib-1.5.33.dist-info/LICENSE,sha256=1jqWIkbnMxDfs_i0SXP5qbV6PHjBr1g8506oW7uPjfg,11347
68
- arpakitlib-1.5.33.dist-info/METADATA,sha256=xScH-mZtscIaV19pqqlcgX6IfeEKych_R7jlqzO-FJg,2330
69
- arpakitlib-1.5.33.dist-info/NOTICE,sha256=wHwmiq3wExfFfgMsE5U5TOBP9_l72ocIG82KurEels0,43
70
- arpakitlib-1.5.33.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
71
- arpakitlib-1.5.33.dist-info/RECORD,,
67
+ arpakitlib-1.5.34.dist-info/LICENSE,sha256=1jqWIkbnMxDfs_i0SXP5qbV6PHjBr1g8506oW7uPjfg,11347
68
+ arpakitlib-1.5.34.dist-info/METADATA,sha256=zPM7OWINm8HMIVCv2TT4eA9jyZI-enIAaXSjTsiR-Vg,2330
69
+ arpakitlib-1.5.34.dist-info/NOTICE,sha256=wHwmiq3wExfFfgMsE5U5TOBP9_l72ocIG82KurEels0,43
70
+ arpakitlib-1.5.34.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
71
+ arpakitlib-1.5.34.dist-info/RECORD,,