arpakitlib 1.7.63__py3-none-any.whl → 1.7.65__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.
@@ -1,6 +1,6 @@
1
1
  from fastapi import FastAPI
2
2
 
3
- from arpakitlib.ar_base_worker_util import BaseWorker
3
+ from arpakitlib.ar_base_worker_util import SafeRunInBackgroundModes
4
4
  from arpakitlib.ar_fastapi_util import create_fastapi_app, InitSqlalchemyDBStartupAPIEvent, InitFileStoragesInDir, \
5
5
  create_handle_exception, create_story_log_before_response_in_handle_exception, DEFAULT_CONTACT, \
6
6
  SafeRunWorkerStartupAPIEvent
@@ -22,18 +22,25 @@ def create_api_app() -> FastAPI:
22
22
  setup_logging()
23
23
 
24
24
  settings = get_cached_settings()
25
+
25
26
  sqlalchemy_db = get_cached_sqlalchemy_db() if settings.sql_db_url is not None else None
27
+
26
28
  transmitted_api_data = TransmittedAPIData(
27
29
  settings=settings,
28
30
  sqlalchemy_db=sqlalchemy_db
29
31
  )
30
32
 
31
33
  funcs_before_response = []
34
+
32
35
  if settings.api_create_story_log_before_response_in_handle_exception:
33
36
  raise_for_type(sqlalchemy_db, SQLAlchemyDB)
34
37
  funcs_before_response.append(
35
- create_story_log_before_response_in_handle_exception(sqlalchemy_db=sqlalchemy_db)
38
+ create_story_log_before_response_in_handle_exception(
39
+ sqlalchemy_db=sqlalchemy_db,
40
+ ignore_api_error_code_not_found=True
41
+ )
36
42
  )
43
+
37
44
  handle_exception = create_handle_exception(
38
45
  funcs_before_response=funcs_before_response,
39
46
  async_funcs_after_response=[]
@@ -66,7 +73,7 @@ def create_api_app() -> FastAPI:
66
73
  filter_operation_types=None
67
74
  )
68
75
  ],
69
- safe_run_in_background_mode=BaseWorker.SafeRunInBackgroundModes.async_task
76
+ safe_run_in_background_mode=SafeRunInBackgroundModes.async_task
70
77
  )
71
78
  )
72
79
 
@@ -80,7 +87,7 @@ def create_api_app() -> FastAPI:
80
87
  scheduled_operations=ALL_SCHEDULED_OPERATIONS
81
88
  )
82
89
  ],
83
- safe_run_in_background_mode=BaseWorker.SafeRunInBackgroundModes.async_task
90
+ safe_run_in_background_mode=SafeRunInBackgroundModes.async_task
84
91
  )
85
92
  )
86
93
 
@@ -14,49 +14,23 @@ _ARPAKIT_LIB_MODULE_VERSION = "3.0"
14
14
 
15
15
 
16
16
  class BaseWorker(ABC):
17
- class SafeRunInBackgroundModes(Enumeration):
18
- async_task = "async_task"
19
- thread = "thread"
20
- process = "process"
21
-
22
17
  def __init__(self):
23
18
  self.worker_name = self.__class__.__name__
24
19
  self._logger = logging.getLogger(self.worker_name)
25
20
  self.timeout_after_run = timedelta(seconds=0.1).total_seconds()
26
21
  self.timeout_after_err_in_run = timedelta(seconds=1).total_seconds()
27
22
 
28
- def safe_run_in_background(self, *, safe_run_in_background_mode: str) -> (
29
- asyncio.Task | threading.Thread | multiprocessing.Process
30
- ):
31
- if safe_run_in_background_mode == self.SafeRunInBackgroundModes.async_task:
32
- res: asyncio.Task = asyncio.create_task(self.async_safe_run())
33
- elif safe_run_in_background_mode == self.SafeRunInBackgroundModes.thread:
34
- res: threading.Thread = threading.Thread(
35
- target=self.sync_safe_run,
36
- daemon=True
37
- )
38
- res.start()
39
- elif safe_run_in_background_mode == self.SafeRunInBackgroundModes.process:
40
- res: multiprocessing.Process = multiprocessing.Process(
41
- target=self.sync_safe_run,
42
- daemon=True
43
- )
44
- res.start()
45
- else:
46
- raise ValueError(f"unknown safe_run_mode={safe_run_in_background_mode}")
47
- return res
48
-
49
23
  def sync_on_startup(self):
50
24
  pass
51
25
 
52
26
  def sync_run(self):
53
- raise NotImplementedError()
27
+ self._logger.info("hello world")
54
28
 
55
29
  def sync_run_on_error(self, exception: BaseException, **kwargs):
56
30
  pass
57
31
 
58
32
  def sync_safe_run(self):
59
- self._logger.info("start sync_safe_run")
33
+ self._logger.info("start")
60
34
  try:
61
35
  self.sync_on_startup()
62
36
  except BaseException as exception:
@@ -65,8 +39,6 @@ class BaseWorker(ABC):
65
39
  while True:
66
40
  try:
67
41
  self.sync_run()
68
- if self.timeout_after_run is not None:
69
- sync_safe_sleep(self.timeout_after_run)
70
42
  except BaseException as exception:
71
43
  self._logger.error("error in sync_run", exc_info=exception)
72
44
  try:
@@ -74,14 +46,14 @@ class BaseWorker(ABC):
74
46
  except BaseException as exception_:
75
47
  self._logger.error("error in sync_run_on_error", exc_info=exception_)
76
48
  raise exception_
77
- if self.timeout_after_err_in_run is not None:
78
- sync_safe_sleep(self.timeout_after_err_in_run)
49
+ if self.timeout_after_run is not None:
50
+ sync_safe_sleep(self.timeout_after_run)
79
51
 
80
52
  async def async_on_startup(self):
81
53
  pass
82
54
 
83
55
  async def async_run(self):
84
- raise NotImplementedError()
56
+ self._logger.info("hello world")
85
57
 
86
58
  async def async_run_on_error(self, exception: BaseException, **kwargs):
87
59
  pass
@@ -96,8 +68,6 @@ class BaseWorker(ABC):
96
68
  while True:
97
69
  try:
98
70
  await self.async_run()
99
- if self.timeout_after_run is not None:
100
- await async_safe_sleep(self.timeout_after_run)
101
71
  except BaseException as exception:
102
72
  self._logger.error("error in async_run", exc_info=exception)
103
73
  try:
@@ -105,8 +75,36 @@ class BaseWorker(ABC):
105
75
  except BaseException as exception_:
106
76
  self._logger.error("error in async_run_on_error", exc_info=exception_)
107
77
  raise exception_
108
- if self.timeout_after_err_in_run is not None:
109
- await async_safe_sleep(self.timeout_after_err_in_run)
78
+ if self.timeout_after_err_in_run is not None:
79
+ await async_safe_sleep(self.timeout_after_err_in_run)
80
+
81
+
82
+ class SafeRunInBackgroundModes(Enumeration):
83
+ async_task = "async_task"
84
+ thread = "thread"
85
+ process = "process"
86
+
87
+
88
+ def safe_run_worker_in_background(*, worker: BaseWorker, mode: str) -> (
89
+ asyncio.Task | threading.Thread | multiprocessing.Process
90
+ ):
91
+ if mode == SafeRunInBackgroundModes.async_task:
92
+ res: asyncio.Task = asyncio.create_task(worker.async_safe_run())
93
+ elif mode == SafeRunInBackgroundModes.thread:
94
+ res: threading.Thread = threading.Thread(
95
+ target=worker.sync_safe_run,
96
+ daemon=True
97
+ )
98
+ res.start()
99
+ elif mode == SafeRunInBackgroundModes.process:
100
+ res: multiprocessing.Process = multiprocessing.Process(
101
+ target=worker.sync_safe_run,
102
+ daemon=True
103
+ )
104
+ res.start()
105
+ else:
106
+ raise ValueError(f"unknown safe_run_mode={mode}")
107
+ return res
110
108
 
111
109
 
112
110
  def __example():
@@ -176,6 +176,7 @@ def create_handle_exception(
176
176
  "exception_str": str(exception),
177
177
  "request.method": str(request.method),
178
178
  "request.url": str(request.url),
179
+ "request.headers": str(request.headers),
179
180
  }
180
181
  )
181
182
 
@@ -254,7 +255,8 @@ def create_handle_exception(
254
255
 
255
256
  def create_story_log_before_response_in_handle_exception(
256
257
  *,
257
- sqlalchemy_db: SQLAlchemyDB
258
+ sqlalchemy_db: SQLAlchemyDB,
259
+ ignore_api_error_code_not_found: bool = True
258
260
  ) -> Callable:
259
261
  def func(
260
262
  *,
@@ -264,6 +266,8 @@ def create_story_log_before_response_in_handle_exception(
264
266
  exception: Exception,
265
267
  **kwargs
266
268
  ) -> (int, ErrorSO, dict[str, Any]):
269
+ if ignore_api_error_code_not_found and error_so.error_code == BaseAPIErrorCodes.not_found:
270
+ return status_code, error_so, kwargs
267
271
  sqlalchemy_db.init()
268
272
  traceback_str = "".join(traceback.format_exception(type(exception), exception, exception.__traceback__))
269
273
  with sqlalchemy_db.new_session() as session:
@@ -2,7 +2,6 @@
2
2
 
3
3
  import logging
4
4
  import os
5
- from functools import wraps
6
5
  from typing import Optional
7
6
 
8
7
  _ARPAKIT_LIB_MODULE_VERSION = "3.0"
@@ -34,7 +33,7 @@ def setup_normal_logging(log_filepath: Optional[str] = None):
34
33
  stream_handler = logging.StreamHandler()
35
34
  stream_handler.setLevel(logging.INFO)
36
35
  stream_formatter = logging.Formatter(
37
- "%(asctime)s | %(levelname)s | %(name)s:%(funcName)s:%(lineno)d - %(message)s",
36
+ "%(asctime)s | %(levelname)s | %(filename)s | %(name)s:%(funcName)s:%(lineno)d - %(message)s",
38
37
  datefmt="%d.%m.%Y %I:%M:%S%p"
39
38
  )
40
39
  stream_handler.setFormatter(stream_formatter)
@@ -44,7 +43,7 @@ def setup_normal_logging(log_filepath: Optional[str] = None):
44
43
  file_handler = logging.FileHandler(log_filepath)
45
44
  file_handler.setLevel(logging.WARNING)
46
45
  file_formatter = logging.Formatter(
47
- "%(asctime)s | %(levelname)s | %(name)s:%(funcName)s:%(lineno)d - %(message)s",
46
+ "%(asctime)s | %(levelname)s | %(filename)s | %(name)s:%(funcName)s:%(lineno)d - %(message)s",
48
47
  datefmt="%d.%m.%Y %I:%M:%S%p"
49
48
  )
50
49
  file_handler.setFormatter(file_formatter)
@@ -55,38 +54,6 @@ def setup_normal_logging(log_filepath: Optional[str] = None):
55
54
  logger.info("normal logging was setup")
56
55
 
57
56
 
58
- def log_func():
59
- def decorator(func):
60
- @wraps(func)
61
- def wrapper(*args, **kwargs):
62
- function_path = f"{func.__module__}:{func.__qualname__}"
63
- logger = logging.getLogger(__name__)
64
- logger.info(f"start func {function_path}")
65
- result = func(*args, **kwargs)
66
- logger.info(f"finish func {function_path}")
67
- return result
68
-
69
- return wrapper
70
-
71
- return decorator
72
-
73
-
74
- def log_async_func():
75
- def decorator(func):
76
- @wraps(func)
77
- async def async_wrapper(*args, **kwargs):
78
- function_path = f"{func.__module__}:{func.__qualname__}"
79
- logger = logging.getLogger(__name__)
80
- logger.info(f"start async func {function_path}")
81
- result = await func(*args, **kwargs)
82
- logger.info(f"finish async func {function_path}")
83
- return result
84
-
85
- return async_wrapper
86
-
87
- return decorator
88
-
89
-
90
57
  def __example():
91
58
  pass
92
59
 
@@ -136,11 +136,17 @@ class BaseOperationExecutor:
136
136
  elif operation_dbm.type == BaseOperationTypes.raise_fake_exception_:
137
137
  self._logger.info("raise_fake_exception")
138
138
  raise Exception("raise_fake_exception")
139
+ else:
140
+ raise Exception(
141
+ f"unknown operation_dbm.type,"
142
+ f" operation_dbm.id={operation_dbm.id},"
143
+ f" operation_dbm.type={operation_dbm.type}"
144
+ )
139
145
  return operation_dbm
140
146
 
141
147
  def sync_safe_execute_operation(self, operation_dbm: OperationDBM) -> OperationDBM:
142
148
  self._logger.info(
143
- f"start sync_safe_execute_operation, "
149
+ f"start "
144
150
  f"operation_dbm.id={operation_dbm.id}, "
145
151
  f"operation_dbm.type={operation_dbm.type}, "
146
152
  f"operation_dbm.status={operation_dbm.status}"
@@ -219,11 +225,17 @@ class BaseOperationExecutor:
219
225
  elif operation_dbm.type == BaseOperationTypes.raise_fake_exception_:
220
226
  self._logger.info("raise_fake_exception")
221
227
  raise Exception("raise_fake_exception")
228
+ else:
229
+ raise Exception(
230
+ f"unknown operation_dbm.type,"
231
+ f" operation_dbm.id={operation_dbm.id},"
232
+ f" operation_dbm.type={operation_dbm.type}"
233
+ )
222
234
  return operation_dbm
223
235
 
224
236
  async def async_safe_execute_operation(self, operation_dbm: OperationDBM) -> OperationDBM:
225
237
  self._logger.info(
226
- f"start async_safe_execute_operation, "
238
+ f"start "
227
239
  f"operation_dbm.id={operation_dbm.id}, "
228
240
  f"operation_dbm.type={operation_dbm.type}, "
229
241
  f"operation_dbm.status={operation_dbm.status}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: arpakitlib
3
- Version: 1.7.63
3
+ Version: 1.7.65
4
4
  Summary: arpakitlib
5
5
  Home-page: https://github.com/ARPAKIT-Company/arpakitlib
6
6
  License: Apache-2.0
@@ -74,7 +74,7 @@ arpakitlib/_arpakit_project_template/src/api/__init__.py,sha256=47DEQpj8HBSa-_TI
74
74
  arpakitlib/_arpakit_project_template/src/api/asgi.py,sha256=a5UBxOyNC8NG3E0ayhiDo3t5tPoB3WtOf2gbZJFWBAA,74
75
75
  arpakitlib/_arpakit_project_template/src/api/auth.py,sha256=Ljq_VjjiAaW3HEzq60nkSI-HkHfuv6j5-8Q6Qs8V9bU,261
76
76
  arpakitlib/_arpakit_project_template/src/api/const.py,sha256=7d4qD5hedqr7QxVzbfsA7E1bNZn2Pm2U8joXGtpANu0,287
77
- arpakitlib/_arpakit_project_template/src/api/create_api_app.py,sha256=yEhwKpgSP0eCewXwEiSlKMtRm7fKOhZt_vhXssIjnUw,4491
77
+ arpakitlib/_arpakit_project_template/src/api/create_api_app.py,sha256=sSVf1Ft8VqdW_IAApYsL4C9mnK4M0wNUw8YafKXYJO4,4571
78
78
  arpakitlib/_arpakit_project_template/src/api/event.py,sha256=58wCVyVSIe_kydWi44M0Wvp7bTnV8xvO30gMXzjbFYc,750
79
79
  arpakitlib/_arpakit_project_template/src/api/router/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
80
  arpakitlib/_arpakit_project_template/src/api/router/main_router.py,sha256=__Z-pGoeooYCub7besFXGJJvZR3V-4IakXd3cKo6ZIM,209
@@ -118,7 +118,7 @@ arpakitlib/ar_arpakit_project_template_util.py,sha256=AswzQvvb-zfUyrcP4EP0K756YL
118
118
  arpakitlib/ar_arpakit_schedule_uust_api_client_util.py,sha256=SYWWQDohPnw0qpBIu2hEvGZRVdaI4NUUQdEjnMnseo4,18237
119
119
  arpakitlib/ar_arpakitlib_cli_util.py,sha256=ZktW3T6YRSM4_IDjbVhO3erceiQ5N6Gab_O-LtglfAI,3117
120
120
  arpakitlib/ar_base64_util.py,sha256=aZkg2cZTuAaP2IWeG_LXJ6RO7qhyskVwec-Lks0iM-k,676
121
- arpakitlib/ar_base_worker_util.py,sha256=41MvFpS1YzaHchcNOVIuqYP4q3BXycpGPvylb10IbDI,4228
121
+ arpakitlib/ar_base_worker_util.py,sha256=o7RksRG-f8Xf6xEhNFx-ddhnZfF_yq2OhhxHEI6_YJk,3760
122
122
  arpakitlib/ar_cache_file_util.py,sha256=Fo2pH-Zqm966KWFBHG_pbiySGZvhIFCYqy7k1weRfJ0,3476
123
123
  arpakitlib/ar_datetime_util.py,sha256=Xe1NiT9oPQzNSG7RVRkhukhbg4i-hhS5ImmV7sPUc8o,971
124
124
  arpakitlib/ar_dict_util.py,sha256=cF5LQJ6tLqyGoEXfDljMDZrikeZoWPw7CgINHIFGvXM,419
@@ -146,7 +146,7 @@ arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.css,sha256=jzPZlgJTFwSdSphk9C
146
146
  arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.css.map,sha256=5wq8eXMLU6Zxb45orZPL1zAsBFJReFw6GjYqGpUX3hg,262650
147
147
  arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.js,sha256=ffrLZHHEQ_g84A-ul3yWa10Kk09waOAxHcQXPuZuavg,339292
148
148
  arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.js.map,sha256=9UhIW7MqCOZPAz1Sl1IKfZUuhWU0p-LJqrnjjJD9Xhc,1159454
149
- arpakitlib/ar_fastapi_util.py,sha256=mkgM3_5ff6BUv-YuG6JyjQ1ez1l2FJqXrIAGGHWRU6w,24296
149
+ arpakitlib/ar_fastapi_util.py,sha256=eOErnvI8ujwC_yN0XGN2xHm2RUoDk103OCpIkFGJ8A4,24555
150
150
  arpakitlib/ar_file_storage_in_dir_util.py,sha256=D3e3rGuHoI6xqAA5mVvEpVVpOWY1jyjNsjj2UhyHRbE,3674
151
151
  arpakitlib/ar_file_util.py,sha256=07xCF7paAUP2JUyfpeX0l3N1oCSma7qAcBmrCIZVi3g,452
152
152
  arpakitlib/ar_hash_util.py,sha256=Iqy6KBAOLBQMFLWv676boI5sV7atT2B-fb7aCdHOmIQ,340
@@ -157,11 +157,11 @@ arpakitlib/ar_json_util.py,sha256=GwHDdrBWiJBHSc07Qe0aN1Gp_uM0pYpTwzU9JAgsKAo,97
157
157
  arpakitlib/ar_jwt_util.py,sha256=Rhm4ywoTAn6yOV8NLjDASfAtAtheROxxDP40G3XjnuQ,761
158
158
  arpakitlib/ar_list_of_dicts_to_xlsx.py,sha256=MyjEl4Jl4beLVZqLVQMMv0-XDtBD3Xh4Z_ZPDJeFu04,745
159
159
  arpakitlib/ar_list_util.py,sha256=2woOAHAU8oTIiVjZ8GLnx15odEaoQUq3Q0JPxlufFF0,457
160
- arpakitlib/ar_logging_util.py,sha256=gP5OqpafgdrjlpfPyz0ENEA1gGh2J7ZKHqr3EWZ-IJ4,2628
160
+ arpakitlib/ar_logging_util.py,sha256=jkc1qH7STKAjuwV7ipWqMA5Tn0LogQZ78BV6HCwW57A,1696
161
161
  arpakitlib/ar_mongodb_util.py,sha256=2ECkTnGAZ92qxioL-fmN6R4yZOSr3bXdXLWTzT1C3vk,4038
162
162
  arpakitlib/ar_need_type_util.py,sha256=xq5bbAXJG-93CRVZUcLW0ZdM22rj-ZUW17C5hX_5grg,1699
163
163
  arpakitlib/ar_openai_api_client_util.py,sha256=dHUbfg1sVVCjsNl_fra3iCMEz1bR-Hk9fE-DdYbu7Wc,1215
164
- arpakitlib/ar_operation_execution_util.py,sha256=1oobZxK9DBXMOKQKiqhvbatgqs7PUJfChXW1O6sgz44,17666
164
+ arpakitlib/ar_operation_execution_util.py,sha256=F3gX2ZaR-tMFEKjVptpmX2kBTwtyr9Wfp9qNS0DR0Gk,18049
165
165
  arpakitlib/ar_parse_command.py,sha256=-s61xcATIsfw1eV_iD3xi-grsitbGzSDoAFc5V0OFy4,3447
166
166
  arpakitlib/ar_postgresql_util.py,sha256=1AuLjEaa1Lg4pzn-ukCVnDi35Eg1k91APRTqZhIJAdo,945
167
167
  arpakitlib/ar_run_cmd_util.py,sha256=D_rPavKMmWkQtwvZFz-Io5Ak8eSODHkcFeLPzNVC68g,1072
@@ -175,9 +175,9 @@ arpakitlib/ar_str_util.py,sha256=oCEtQ_TTn35OEz9jCNLjbhopq76JmaifD_iYR-nEJJ4,214
175
175
  arpakitlib/ar_type_util.py,sha256=e6Ch8I_B3FMJMj-fiZvTwtGde4hxSa48fGt5g8RlV6I,2301
176
176
  arpakitlib/ar_yookassa_api_client_util.py,sha256=sh4fcUkAkdOetFn9JYoTvjcSXP-M1wU04KEY-ECLfLg,5137
177
177
  arpakitlib/ar_zabbix_api_client_util.py,sha256=Q-VR4MvoZ9aHwZeYZr9G3LwN-ANx1T5KFmF6pvPM-9M,6402
178
- arpakitlib-1.7.63.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
179
- arpakitlib-1.7.63.dist-info/METADATA,sha256=iZqft8zFKWYKyiwRuf1iA2uWMwiwi1dp5Jyzn0kK0mI,2824
180
- arpakitlib-1.7.63.dist-info/NOTICE,sha256=95aUzaPJjVpDsGAsNzVnq7tHTxAl0s5UFznCTkVCau4,763
181
- arpakitlib-1.7.63.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
182
- arpakitlib-1.7.63.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
183
- arpakitlib-1.7.63.dist-info/RECORD,,
178
+ arpakitlib-1.7.65.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
179
+ arpakitlib-1.7.65.dist-info/METADATA,sha256=47wQBgu-D9rSBd4fqxWGyUXaVjQxxEJxPo5mOvhL38o,2824
180
+ arpakitlib-1.7.65.dist-info/NOTICE,sha256=95aUzaPJjVpDsGAsNzVnq7tHTxAl0s5UFznCTkVCau4,763
181
+ arpakitlib-1.7.65.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
182
+ arpakitlib-1.7.65.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
183
+ arpakitlib-1.7.65.dist-info/RECORD,,