arpakitlib 1.6.47__py3-none-any.whl → 1.7.89__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.
- arpakitlib/_arpakit_project_template/.gitignore +51 -0
- arpakitlib/_arpakit_project_template/.python-version +1 -0
- arpakitlib/_arpakit_project_template/ARPAKITLIB +1 -0
- arpakitlib/_arpakit_project_template/AUTHOR.md +4 -0
- arpakitlib/_arpakit_project_template/NOTICE +16 -0
- arpakitlib/_arpakit_project_template/README.md +6 -0
- arpakitlib/_arpakit_project_template/example.env +22 -0
- arpakitlib/_arpakit_project_template/manage/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/manage/docker_ps.sh +2 -0
- arpakitlib/_arpakit_project_template/manage/docker_ps_a.sh +2 -0
- arpakitlib/_arpakit_project_template/manage/docker_run_postgres_for_dev.sh +4 -0
- arpakitlib/_arpakit_project_template/manage/docker_start_postgres_for_dev.sh +2 -0
- arpakitlib/_arpakit_project_template/manage/docker_stop_postgres_for_dev.sh +2 -0
- arpakitlib/_arpakit_project_template/manage/example_nginx_proxy.nginx +14 -0
- arpakitlib/_arpakit_project_template/manage/example_poetry_arpakitlib.sh +1 -0
- arpakitlib/_arpakit_project_template/manage/example_pyproject.toml +18 -0
- arpakitlib/_arpakit_project_template/manage/example_systemd.service +12 -0
- arpakitlib/_arpakit_project_template/manage/git_branch.sh +2 -0
- arpakitlib/_arpakit_project_template/manage/git_commit.sh +3 -0
- arpakitlib/_arpakit_project_template/manage/git_push_arpakit_company_github_1.sh +4 -0
- arpakitlib/_arpakit_project_template/manage/git_push_arpakit_company_gitlab_1.sh +4 -0
- arpakitlib/_arpakit_project_template/manage/git_push_arpakit_github_1.sh +4 -0
- arpakitlib/_arpakit_project_template/manage/git_push_arpakit_gitlab_1.sh +4 -0
- arpakitlib/_arpakit_project_template/manage/git_remote_v.sh +2 -0
- arpakitlib/_arpakit_project_template/manage/git_set_arpakit_company_origin.sh +7 -0
- arpakitlib/_arpakit_project_template/manage/git_set_arpakit_origin.sh +7 -0
- arpakitlib/_arpakit_project_template/manage/git_status.sh +2 -0
- arpakitlib/_arpakit_project_template/manage/hello_world.py +6 -0
- arpakitlib/_arpakit_project_template/manage/json_beutify.py +10 -0
- arpakitlib/_arpakit_project_template/manage/logging_check.py +14 -0
- arpakitlib/_arpakit_project_template/manage/note/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/manage/note/note_1.txt +0 -0
- arpakitlib/_arpakit_project_template/manage/note/note_2.txt +0 -0
- arpakitlib/_arpakit_project_template/manage/note/note_3.txt +0 -0
- arpakitlib/_arpakit_project_template/manage/note/note_4.txt +0 -0
- arpakitlib/_arpakit_project_template/manage/note/note_5.txt +0 -0
- arpakitlib/_arpakit_project_template/manage/poetry_add_plugin_export.sh +2 -0
- arpakitlib/_arpakit_project_template/manage/poetry_check.sh +2 -0
- arpakitlib/_arpakit_project_template/manage/poetry_clear_cache.sh +4 -0
- arpakitlib/_arpakit_project_template/manage/poetry_config_virtualenvs_in_project_true.sh +2 -0
- arpakitlib/_arpakit_project_template/manage/poetry_generate_requirements.txt.sh +1 -0
- arpakitlib/_arpakit_project_template/manage/poetry_install.sh +5 -0
- arpakitlib/_arpakit_project_template/manage/poetry_lock.sh +2 -0
- arpakitlib/_arpakit_project_template/manage/poetry_remove_and_add_arpakitlib.sh +7 -0
- arpakitlib/_arpakit_project_template/manage/poetry_show.sh +2 -0
- arpakitlib/_arpakit_project_template/manage/poetry_show_arpakitlib.sh +2 -0
- arpakitlib/_arpakit_project_template/manage/poetry_update.sh +6 -0
- arpakitlib/_arpakit_project_template/manage/poetry_update_arpakitlib.sh +5 -0
- arpakitlib/_arpakit_project_template/manage/requirements.txt +209 -0
- arpakitlib/_arpakit_project_template/manage/sandbox/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/manage/sandbox/sandbox_1.py +14 -0
- arpakitlib/_arpakit_project_template/manage/sandbox/sandbox_2.py +14 -0
- arpakitlib/_arpakit_project_template/manage/sandbox/sandbox_3.py +14 -0
- arpakitlib/_arpakit_project_template/manage/sandbox/sandbox_4.py +14 -0
- arpakitlib/_arpakit_project_template/manage/sandbox/sandbox_5.py +14 -0
- arpakitlib/_arpakit_project_template/manage/sandbox/sandbox_6.py +14 -0
- arpakitlib/_arpakit_project_template/manage/sandbox/sandbox_7.py +14 -0
- arpakitlib/_arpakit_project_template/manage/sandbox/sandbox_8.sh +0 -0
- arpakitlib/_arpakit_project_template/manage/sandbox/sandbox_9.sh +0 -0
- arpakitlib/_arpakit_project_template/manage/settings_check.py +10 -0
- arpakitlib/_arpakit_project_template/manage/settings_generate_env_example.py +13 -0
- arpakitlib/_arpakit_project_template/manage/sqlalchemy_db_check_conn.py +11 -0
- arpakitlib/_arpakit_project_template/manage/sqlalchemy_db_init.py +11 -0
- arpakitlib/_arpakit_project_template/manage/sqlalchemy_db_reinit.py +11 -0
- arpakitlib/_arpakit_project_template/resource/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/resource/static/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/resource/static/healthcheck +1 -0
- arpakitlib/_arpakit_project_template/resource/static/helloworld +1 -0
- arpakitlib/_arpakit_project_template/src/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/src/additional_model/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/src/additional_model/additional_model.py +6 -0
- arpakitlib/_arpakit_project_template/src/api/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/src/api/asgi.py +3 -0
- arpakitlib/_arpakit_project_template/src/api/auth.py +1 -0
- arpakitlib/_arpakit_project_template/src/api/const.py +13 -0
- arpakitlib/_arpakit_project_template/src/api/create_api_app.py +117 -0
- arpakitlib/_arpakit_project_template/src/api/event.py +20 -0
- arpakitlib/_arpakit_project_template/src/api/router/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/src/api/router/main_router.py +9 -0
- arpakitlib/_arpakit_project_template/src/api/router/v1/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/src/api/router/v1/get_api_error_info.py +27 -0
- arpakitlib/_arpakit_project_template/src/api/router/v1/main_router.py +11 -0
- arpakitlib/_arpakit_project_template/src/api/schema/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/src/api/schema/v1/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/src/api/schema/v1/in_.py +0 -0
- arpakitlib/_arpakit_project_template/src/api/schema/v1/out.py +6 -0
- arpakitlib/_arpakit_project_template/src/api/start_api_for_dev.py +17 -0
- arpakitlib/_arpakit_project_template/src/api/start_api_for_dev_with_reload.py +9 -0
- arpakitlib/_arpakit_project_template/src/api/transmitted_api_data.py +9 -0
- arpakitlib/_arpakit_project_template/src/api/util.py +0 -0
- arpakitlib/_arpakit_project_template/src/business_service/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/src/core/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/src/core/const.py +48 -0
- arpakitlib/_arpakit_project_template/src/core/settings.py +86 -0
- arpakitlib/_arpakit_project_template/src/core/util.py +58 -0
- arpakitlib/_arpakit_project_template/src/db/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/src/db/sqlalchemy_model.py +8 -0
- arpakitlib/_arpakit_project_template/src/db/util.py +21 -0
- arpakitlib/_arpakit_project_template/src/operation_execution/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/src/operation_execution/const.py +9 -0
- arpakitlib/_arpakit_project_template/src/operation_execution/operation_executor.py +14 -0
- arpakitlib/_arpakit_project_template/src/operation_execution/scheduled_operations.py +25 -0
- arpakitlib/_arpakit_project_template/src/operation_execution/start_operation_executor_worker_for_dev.py +18 -0
- arpakitlib/_arpakit_project_template/src/operation_execution/start_scheduled_operation_creator_worker_for_dev.py +17 -0
- arpakitlib/_arpakit_project_template/src/operation_execution/util.py +21 -0
- arpakitlib/_arpakit_project_template/src/test_data/__init__.py +0 -0
- arpakitlib/_arpakit_project_template/src/test_data/make_test_data_1.py +6 -0
- arpakitlib/_arpakit_project_template/src/test_data/make_test_data_2.py +6 -0
- arpakitlib/_arpakit_project_template/src/test_data/make_test_data_3.py +6 -0
- arpakitlib/_arpakit_project_template/src/test_data/make_test_data_4.py +6 -0
- arpakitlib/_arpakit_project_template/src/test_data/make_test_data_5.py +6 -0
- arpakitlib/_arpakit_project_template/src/util/__init__.py +0 -0
- arpakitlib/api_key_util.py +21 -0
- arpakitlib/ar_additional_model_util.py +25 -2
- arpakitlib/ar_aiogram_util.py +10 -18
- arpakitlib/ar_arpakit_lib_module_util.py +6 -1
- arpakitlib/ar_arpakit_project_template_util.py +96 -0
- arpakitlib/ar_arpakit_schedule_uust_api_client_util.py +24 -3
- arpakitlib/ar_arpakitlib_cli_util.py +79 -0
- arpakitlib/ar_base_worker_util.py +95 -48
- arpakitlib/ar_dream_ai_api_client_util.py +26 -52
- arpakitlib/ar_enumeration_util.py +11 -0
- arpakitlib/ar_exception_util.py +18 -0
- arpakitlib/ar_fastapi_static/healthcheck +1 -0
- arpakitlib/ar_fastapi_util.py +270 -137
- arpakitlib/ar_file_util.py +22 -0
- arpakitlib/ar_func_util.py +55 -0
- arpakitlib/ar_http_request_util.py +35 -6
- arpakitlib/ar_json_util.py +13 -7
- arpakitlib/ar_logging_util.py +5 -2
- arpakitlib/ar_need_type_util.py +12 -2
- arpakitlib/{ar_openai_util.py → ar_openai_api_client_util.py} +16 -2
- arpakitlib/ar_operation_execution_util.py +250 -105
- arpakitlib/ar_parse_command.py +25 -7
- arpakitlib/ar_schedule_uust_api_client_util.py +37 -23
- arpakitlib/ar_settings_util.py +37 -11
- arpakitlib/ar_sleep_util.py +0 -13
- arpakitlib/ar_sqlalchemy_model_util.py +35 -10
- arpakitlib/ar_sqlalchemy_util.py +4 -3
- arpakitlib/{ar_ssh_util.py → ar_ssh_runner_util.py} +2 -2
- arpakitlib/ar_str_util.py +43 -2
- arpakitlib/ar_type_util.py +68 -4
- arpakitlib/ar_yookassa_api_client_util.py +26 -44
- {arpakitlib-1.6.47.dist-info → arpakitlib-1.7.89.dist-info}/METADATA +17 -8
- arpakitlib-1.7.89.dist-info/NOTICE +16 -0
- arpakitlib-1.7.89.dist-info/RECORD +186 -0
- arpakitlib-1.7.89.dist-info/entry_points.txt +3 -0
- arpakitlib/AUTHOR.md +0 -7
- arpakitlib/NOTICE +0 -2
- arpakitlib/ar_arpakitlib_info.py +0 -13
- arpakitlib/ar_generate_env_example.py +0 -22
- arpakitlib-1.6.47.dist-info/NOTICE +0 -2
- arpakitlib-1.6.47.dist-info/RECORD +0 -70
- /arpakitlib/{LICENSE → _arpakit_project_template/LICENSE} +0 -0
- /arpakitlib/{ar_zabbix_util.py → ar_zabbix_api_client_util.py} +0 -0
- {arpakitlib-1.6.47.dist-info → arpakitlib-1.7.89.dist-info}/LICENSE +0 -0
- {arpakitlib-1.6.47.dist-info → arpakitlib-1.7.89.dist-info}/WHEEL +0 -0
@@ -3,14 +3,14 @@
|
|
3
3
|
import asyncio
|
4
4
|
import hashlib
|
5
5
|
import logging
|
6
|
-
from datetime import datetime
|
6
|
+
from datetime import datetime
|
7
7
|
from typing import Any
|
8
8
|
|
9
9
|
import pytz
|
10
|
+
from aiohttp import ClientResponse
|
10
11
|
|
11
12
|
from arpakitlib.ar_dict_util import combine_dicts
|
12
13
|
from arpakitlib.ar_http_request_util import async_make_http_request
|
13
|
-
from arpakitlib.ar_type_util import raise_for_type
|
14
14
|
|
15
15
|
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
16
16
|
|
@@ -72,25 +72,25 @@ class ScheduleUUSTAPIClient:
|
|
72
72
|
def generate_v2_token(self) -> str:
|
73
73
|
return self.generate_new_v2_token(password_first_part=self.api_password_first_part)
|
74
74
|
|
75
|
-
async def
|
75
|
+
async def _async_make_http_request(
|
76
76
|
self,
|
77
77
|
*,
|
78
|
+
method: str = "GET",
|
78
79
|
url: str,
|
79
|
-
params: dict | None = None
|
80
|
-
) ->
|
80
|
+
params: dict[str, Any] | None = None
|
81
|
+
) -> ClientResponse:
|
81
82
|
response = await async_make_http_request(
|
83
|
+
method=method,
|
82
84
|
url=url,
|
83
|
-
|
85
|
+
headers=self.headers,
|
84
86
|
params=combine_dicts(params, self.auth_params()),
|
85
87
|
proxy_url_=self.api_proxy_url,
|
86
|
-
|
87
|
-
timeout_=timedelta(seconds=15),
|
88
|
-
raise_for_status_=True,
|
89
|
-
headers=self.headers
|
88
|
+
raise_for_status_=True
|
90
89
|
)
|
91
90
|
json_data = await response.json()
|
92
|
-
|
93
|
-
|
91
|
+
if "error" in json_data.keys():
|
92
|
+
raise Exception(f"error in json_data, {json_data}")
|
93
|
+
return response
|
94
94
|
|
95
95
|
async def get_current_week(self) -> int:
|
96
96
|
"""
|
@@ -100,10 +100,11 @@ class ScheduleUUSTAPIClient:
|
|
100
100
|
}
|
101
101
|
"""
|
102
102
|
|
103
|
-
|
103
|
+
response = await self._async_make_http_request(
|
104
104
|
url=self.api_url,
|
105
105
|
params={"ask": "get_current_week"}
|
106
106
|
)
|
107
|
+
json_data = await response.json()
|
107
108
|
return json_data["data"][0]
|
108
109
|
|
109
110
|
async def get_current_semester(self) -> str:
|
@@ -114,10 +115,11 @@ class ScheduleUUSTAPIClient:
|
|
114
115
|
}
|
115
116
|
"""
|
116
117
|
|
117
|
-
|
118
|
+
response = await self._async_make_http_request(
|
118
119
|
url=self.api_url,
|
119
120
|
params={"ask": "get_current_semestr"}
|
120
121
|
)
|
122
|
+
json_data = await response.json()
|
121
123
|
return json_data["data"][0]
|
122
124
|
|
123
125
|
async def get_groups(self) -> list[dict[str, Any]]:
|
@@ -135,10 +137,11 @@ class ScheduleUUSTAPIClient:
|
|
135
137
|
}
|
136
138
|
"""
|
137
139
|
|
138
|
-
|
140
|
+
response = await self._async_make_http_request(
|
139
141
|
url=self.api_url,
|
140
142
|
params={"ask": "get_group_list"}
|
141
143
|
)
|
144
|
+
json_data = await response.json()
|
142
145
|
return list(json_data["data"].values())
|
143
146
|
|
144
147
|
async def get_group_lessons(self, group_id: int, semester: str | None = None) -> list[dict[str, Any]]:
|
@@ -148,45 +151,56 @@ class ScheduleUUSTAPIClient:
|
|
148
151
|
}
|
149
152
|
if semester is not None:
|
150
153
|
params["semester"] = semester
|
151
|
-
|
154
|
+
response = await self._async_make_http_request(
|
152
155
|
url=self.api_url,
|
153
156
|
params=params
|
154
157
|
)
|
158
|
+
json_data = await response.json()
|
155
159
|
return json_data["data"]
|
156
160
|
|
157
161
|
async def get_teachers(self) -> list[dict[str, Any]]:
|
158
|
-
|
162
|
+
response = await self._async_make_http_request(
|
159
163
|
url=self.api_url,
|
160
164
|
params={"ask": "get_teacher_list"}
|
161
165
|
)
|
166
|
+
json_data = await response.json()
|
162
167
|
return list(json_data["data"].values())
|
163
168
|
|
164
169
|
async def get_teacher_lessons(self, teacher_id: int, semester: str | None = None) -> list[dict[str, Any]]:
|
165
170
|
params = {"ask": "get_teacher_schedule", "id": teacher_id}
|
166
171
|
if semester is not None:
|
167
172
|
params["semester"] = semester
|
168
|
-
|
173
|
+
response = await self._async_make_http_request(
|
169
174
|
url=self.api_url,
|
170
175
|
params=params
|
171
176
|
)
|
177
|
+
json_data = await response.json()
|
172
178
|
return json_data["data"]
|
173
179
|
|
174
180
|
async def check_conn(self):
|
175
181
|
await self.get_current_week()
|
182
|
+
self._logger.info(f"connection is good")
|
176
183
|
|
177
184
|
async def is_conn_good(self):
|
178
185
|
try:
|
179
186
|
await self.check_conn()
|
180
187
|
except Exception as e:
|
181
|
-
self._logger.error(e)
|
188
|
+
self._logger.error(f"connection is bad", exc_info=e)
|
182
189
|
return False
|
183
190
|
return True
|
184
191
|
|
185
192
|
async def check_all(self):
|
186
|
-
await self.get_groups()
|
187
|
-
|
188
|
-
|
189
|
-
await self.
|
193
|
+
groups = await self.get_groups()
|
194
|
+
self._logger.info(f"groups len: {len(groups)}")
|
195
|
+
|
196
|
+
teachers = await self.get_teachers()
|
197
|
+
self._logger.info(f"teachers len: {len(teachers)}")
|
198
|
+
|
199
|
+
current_semester = await self.get_current_semester()
|
200
|
+
self._logger.info(f"current_semester: {current_semester}")
|
201
|
+
|
202
|
+
current_week = await self.get_current_week()
|
203
|
+
self._logger.info(f"current_week: {current_week}")
|
190
204
|
|
191
205
|
|
192
206
|
def __example():
|
arpakitlib/ar_settings_util.py
CHANGED
@@ -1,19 +1,34 @@
|
|
1
|
+
# arpakit
|
2
|
+
|
3
|
+
from typing import Union
|
4
|
+
|
1
5
|
from pydantic import ConfigDict, field_validator
|
6
|
+
from pydantic_core import PydanticUndefined
|
2
7
|
from pydantic_settings import BaseSettings
|
3
8
|
|
4
9
|
from arpakitlib.ar_enumeration_util import Enumeration
|
5
|
-
|
10
|
+
|
11
|
+
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
12
|
+
|
13
|
+
|
14
|
+
def generate_env_example(settings_class: Union[BaseSettings, type[BaseSettings]]):
|
15
|
+
res = ""
|
16
|
+
for k, f in settings_class.model_fields.items():
|
17
|
+
if f.default is not PydanticUndefined:
|
18
|
+
res += f"# {k}=\n"
|
19
|
+
else:
|
20
|
+
res += f"{k}=\n"
|
21
|
+
return res
|
6
22
|
|
7
23
|
|
8
24
|
class SimpleSettings(BaseSettings):
|
9
25
|
model_config = ConfigDict(extra="ignore")
|
10
26
|
|
11
27
|
class ModeTypes(Enumeration):
|
12
|
-
|
13
|
-
test: str = "preprod"
|
28
|
+
not_prod: str = "not_prod"
|
14
29
|
prod: str = "prod"
|
15
30
|
|
16
|
-
mode_type: str = ModeTypes.
|
31
|
+
mode_type: str = ModeTypes.not_prod
|
17
32
|
|
18
33
|
@field_validator("mode_type")
|
19
34
|
@classmethod
|
@@ -22,17 +37,28 @@ class SimpleSettings(BaseSettings):
|
|
22
37
|
return v
|
23
38
|
|
24
39
|
@property
|
25
|
-
def
|
26
|
-
return self.mode_type == self.ModeTypes.
|
27
|
-
|
28
|
-
@property
|
29
|
-
def is_mode_type_test(self) -> bool:
|
30
|
-
return self.mode_type == self.ModeTypes.test
|
40
|
+
def is_mode_type_not_prod(self) -> bool:
|
41
|
+
return self.mode_type == self.ModeTypes.not_prod
|
31
42
|
|
32
43
|
@property
|
33
44
|
def is_mode_type_prod(self) -> bool:
|
34
45
|
return self.mode_type == self.ModeTypes.prod
|
35
46
|
|
36
47
|
@classmethod
|
37
|
-
def
|
48
|
+
def generate_env_example(cls) -> str:
|
38
49
|
return generate_env_example(settings_class=cls)
|
50
|
+
|
51
|
+
@classmethod
|
52
|
+
def save_env_example_to_file(cls, filepath: str) -> str:
|
53
|
+
env_example = cls.generate_env_example()
|
54
|
+
with open(filepath, mode="w") as f:
|
55
|
+
f.write(env_example)
|
56
|
+
return env_example
|
57
|
+
|
58
|
+
|
59
|
+
def __example():
|
60
|
+
pass
|
61
|
+
|
62
|
+
|
63
|
+
if __name__ == '__main__':
|
64
|
+
__example()
|
arpakitlib/ar_sleep_util.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# arpakit
|
2
2
|
|
3
3
|
import asyncio
|
4
|
-
import logging
|
5
4
|
import math
|
6
5
|
from time import sleep
|
7
6
|
|
@@ -9,12 +8,8 @@ from asyncpg.pgproto.pgproto import timedelta
|
|
9
8
|
|
10
9
|
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
11
10
|
|
12
|
-
_logger = logging.getLogger(__name__)
|
13
|
-
|
14
11
|
|
15
12
|
def sync_safe_sleep(n: timedelta | float | int):
|
16
|
-
_logger.info(f"sync_safe_sleep ({n}) starts")
|
17
|
-
|
18
13
|
if isinstance(n, timedelta):
|
19
14
|
n = n.total_seconds()
|
20
15
|
elif isinstance(n, int):
|
@@ -31,12 +26,8 @@ def sync_safe_sleep(n: timedelta | float | int):
|
|
31
26
|
sleep(1)
|
32
27
|
sleep(frac)
|
33
28
|
|
34
|
-
_logger.info(f"sync_safe_sleep ({n}) ends")
|
35
|
-
|
36
29
|
|
37
30
|
async def async_safe_sleep(n: timedelta | float | int):
|
38
|
-
_logger.info(f"async_safe_sleep ({n}) starts")
|
39
|
-
|
40
31
|
if isinstance(n, timedelta):
|
41
32
|
n = n.total_seconds()
|
42
33
|
elif isinstance(n, int):
|
@@ -48,11 +39,7 @@ async def async_safe_sleep(n: timedelta | float | int):
|
|
48
39
|
|
49
40
|
n: float = n
|
50
41
|
|
51
|
-
_logger.info(f"sleep_time ({n}) starts")
|
52
42
|
await asyncio.sleep(n)
|
53
|
-
_logger.info(f"sleep_time ({n}) ends")
|
54
|
-
|
55
|
-
_logger.info(f"async_safe_sleep ({n}) ends")
|
56
43
|
|
57
44
|
|
58
45
|
def __example():
|
@@ -10,11 +10,19 @@ from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
|
|
10
10
|
|
11
11
|
from arpakitlib.ar_datetime_util import now_utc_dt
|
12
12
|
from arpakitlib.ar_enumeration_util import Enumeration
|
13
|
-
from arpakitlib.ar_json_util import
|
13
|
+
from arpakitlib.ar_json_util import safely_transfer_obj_to_json_str
|
14
14
|
|
15
15
|
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
16
16
|
|
17
17
|
|
18
|
+
def generate_default_long_id():
|
19
|
+
return (
|
20
|
+
f"longid"
|
21
|
+
f"{str(uuid4()).replace('-', '')}"
|
22
|
+
f"{str(now_utc_dt().timestamp()).replace('.', '')}"
|
23
|
+
)
|
24
|
+
|
25
|
+
|
18
26
|
class BaseDBM(DeclarativeBase):
|
19
27
|
__abstract__ = True
|
20
28
|
_bus_data: dict[str, Any] | None = None
|
@@ -26,17 +34,29 @@ class BaseDBM(DeclarativeBase):
|
|
26
34
|
return self._bus_data
|
27
35
|
|
28
36
|
def simple_dict(self, *, include_sd_properties: bool = True) -> dict[str, Any]:
|
29
|
-
res = {
|
37
|
+
res = {}
|
38
|
+
|
39
|
+
for c in inspect(self).mapper.column_attrs:
|
40
|
+
value = getattr(self, c.key)
|
41
|
+
if isinstance(value, BaseDBM):
|
42
|
+
res[c.key] = value.simple_dict(include_sd_properties=include_sd_properties)
|
43
|
+
else:
|
44
|
+
res[c.key] = value
|
30
45
|
|
31
46
|
if include_sd_properties:
|
32
47
|
for attr_name in dir(self):
|
33
48
|
if attr_name.startswith("sdp_") and isinstance(getattr(type(self), attr_name, None), property):
|
34
|
-
|
49
|
+
prop_name = attr_name.removeprefix("sdp_")
|
50
|
+
value = getattr(self, attr_name)
|
51
|
+
if isinstance(value, BaseDBM):
|
52
|
+
res[prop_name] = value.simple_dict(include_sd_properties=include_sd_properties)
|
53
|
+
else:
|
54
|
+
res[prop_name] = value
|
35
55
|
|
36
56
|
return res
|
37
57
|
|
38
58
|
def simple_json(self, *, include_sd_properties: bool = True) -> str:
|
39
|
-
return
|
59
|
+
return safely_transfer_obj_to_json_str(self.simple_dict(include_sd_properties=include_sd_properties))
|
40
60
|
|
41
61
|
|
42
62
|
class SimpleDBM(BaseDBM):
|
@@ -46,7 +66,7 @@ class SimpleDBM(BaseDBM):
|
|
46
66
|
INTEGER, primary_key=True, autoincrement=True, sort_order=-3, nullable=False
|
47
67
|
)
|
48
68
|
long_id: Mapped[str] = mapped_column(
|
49
|
-
TEXT, insert_default=
|
69
|
+
TEXT, insert_default=generate_default_long_id, unique=True, sort_order=-2, nullable=False
|
50
70
|
)
|
51
71
|
creation_dt: Mapped[datetime] = mapped_column(
|
52
72
|
TIMESTAMP(timezone=True), insert_default=now_utc_dt, index=True, sort_order=-1, nullable=False
|
@@ -73,6 +93,11 @@ class StoryLogDBM(SimpleDBM):
|
|
73
93
|
)
|
74
94
|
|
75
95
|
|
96
|
+
class BaseOperationTypes(Enumeration):
|
97
|
+
healthcheck_ = "healthcheck"
|
98
|
+
raise_fake_exception_ = "raise_fake_exception"
|
99
|
+
|
100
|
+
|
76
101
|
class OperationDBM(SimpleDBM):
|
77
102
|
__tablename__ = "operation"
|
78
103
|
|
@@ -82,16 +107,12 @@ class OperationDBM(SimpleDBM):
|
|
82
107
|
executed_without_error = "executed_without_error"
|
83
108
|
executed_with_error = "executed_with_error"
|
84
109
|
|
85
|
-
class Types(Enumeration):
|
86
|
-
healthcheck_ = "healthcheck"
|
87
|
-
raise_fake_exception_ = "raise_fake_exception"
|
88
|
-
|
89
110
|
status: Mapped[str] = mapped_column(
|
90
111
|
TEXT, index=True, insert_default=Statuses.waiting_for_execution,
|
91
112
|
server_default=Statuses.waiting_for_execution, nullable=False
|
92
113
|
)
|
93
114
|
type: Mapped[str] = mapped_column(
|
94
|
-
TEXT, index=True, insert_default=
|
115
|
+
TEXT, index=True, insert_default=BaseOperationTypes.healthcheck_, nullable=False
|
95
116
|
)
|
96
117
|
execution_start_dt: Mapped[datetime | None] = mapped_column(TIMESTAMP(timezone=True), nullable=True)
|
97
118
|
execution_finish_dt: Mapped[datetime | None] = mapped_column(TIMESTAMP(timezone=True), nullable=True)
|
@@ -128,6 +149,10 @@ class OperationDBM(SimpleDBM):
|
|
128
149
|
return None
|
129
150
|
return self.duration.total_seconds()
|
130
151
|
|
152
|
+
@property
|
153
|
+
def sdp_duration_total_seconds(self) -> float | None:
|
154
|
+
return self.duration_total_seconds
|
155
|
+
|
131
156
|
|
132
157
|
def __example():
|
133
158
|
pass
|
arpakitlib/ar_sqlalchemy_util.py
CHANGED
@@ -26,9 +26,10 @@ class SQLAlchemyDB:
|
|
26
26
|
self,
|
27
27
|
*,
|
28
28
|
db_url: str = "postgresql://arpakitlib:arpakitlib@localhost:50629/arpakitlib",
|
29
|
-
|
29
|
+
db_echo: bool = False,
|
30
30
|
need_include_operation_dbm: bool = False,
|
31
|
-
need_include_story_dbm: bool = False
|
31
|
+
need_include_story_dbm: bool = False,
|
32
|
+
db_models: list[Any] | None = None
|
32
33
|
):
|
33
34
|
self._logger = logging.getLogger(self.__class__.__name__)
|
34
35
|
self.need_include_operation_dbm = need_include_operation_dbm
|
@@ -37,7 +38,7 @@ class SQLAlchemyDB:
|
|
37
38
|
self.need_include_story_dbm = True
|
38
39
|
self.engine = create_engine(
|
39
40
|
url=db_url,
|
40
|
-
echo=
|
41
|
+
echo=db_echo,
|
41
42
|
pool_size=5,
|
42
43
|
max_overflow=10,
|
43
44
|
poolclass=QueuePool,
|
@@ -11,7 +11,7 @@ import asyncssh
|
|
11
11
|
import paramiko
|
12
12
|
from pydantic import BaseModel
|
13
13
|
|
14
|
-
from arpakitlib.ar_json_util import
|
14
|
+
from arpakitlib.ar_json_util import safely_transfer_obj_to_json_str
|
15
15
|
|
16
16
|
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
17
17
|
|
@@ -61,7 +61,7 @@ class SSHRunRes(BaseModel):
|
|
61
61
|
}
|
62
62
|
|
63
63
|
def simple_json(self) -> str:
|
64
|
-
return
|
64
|
+
return safely_transfer_obj_to_json_str(self.simple_dict())
|
65
65
|
|
66
66
|
def __repr__(self) -> str:
|
67
67
|
return self.simple_json()
|
arpakitlib/ar_str_util.py
CHANGED
@@ -52,12 +52,18 @@ def bidirectional_str_startswith(string1: str, string2: str, max_diff: Optional[
|
|
52
52
|
return False
|
53
53
|
|
54
54
|
|
55
|
-
def
|
55
|
+
def make_blank_if_none(string: Optional[str] = None) -> str:
|
56
56
|
if string is None:
|
57
57
|
return ""
|
58
58
|
return string
|
59
59
|
|
60
60
|
|
61
|
+
def make_none_if_blank(string: Optional[str] = None) -> str | None:
|
62
|
+
if not string:
|
63
|
+
return None
|
64
|
+
return string
|
65
|
+
|
66
|
+
|
61
67
|
def remove_html(string: str) -> str:
|
62
68
|
raise_for_type(string, str)
|
63
69
|
return BeautifulSoup(string, "html.parser").text
|
@@ -73,8 +79,43 @@ def remove_tags_and_html(string: str) -> str:
|
|
73
79
|
return remove_tags(remove_html(string))
|
74
80
|
|
75
81
|
|
82
|
+
def raise_if_string_blank(string: str) -> str:
|
83
|
+
if not string:
|
84
|
+
raise ValueError("not string")
|
85
|
+
return string
|
86
|
+
|
87
|
+
|
76
88
|
def __example():
|
77
|
-
|
89
|
+
print("str_in:")
|
90
|
+
print(str_in(string="hello", main_string="hello world")) # True
|
91
|
+
print(str_in(string="bye", main_string="hello world")) # False
|
92
|
+
print(str_in(string="hello", main_string="hello world", max_diff=6)) # True
|
93
|
+
print(str_in(string="hello", main_string="hello world", max_diff=1)) # False
|
94
|
+
|
95
|
+
print("\nbidirectional_str_in:")
|
96
|
+
print(bidirectional_str_in(string1="hello", string2="hello world")) # True
|
97
|
+
print(bidirectional_str_in(string1="world", string2="hello world")) # True
|
98
|
+
|
99
|
+
print("\nstr_startswith:")
|
100
|
+
print(str_startswith(string="hello", main_string="hello world")) # True
|
101
|
+
print(str_startswith(string="world", main_string="hello world")) # False
|
102
|
+
|
103
|
+
print("\nbidirectional_str_startswith:")
|
104
|
+
print(bidirectional_str_startswith(string1="hello", string2="hello world")) # True
|
105
|
+
print(bidirectional_str_startswith(string1="world", string2="hello world")) # False
|
106
|
+
|
107
|
+
print("\nmake blank_if_none:")
|
108
|
+
print(make_blank_if_none()) # ""
|
109
|
+
print(make_blank_if_none(string="test")) # "test"
|
110
|
+
|
111
|
+
print("\nremove_html:")
|
112
|
+
print(remove_html(string="<div>Hello <b>World</b></div>")) # "Hello World"
|
113
|
+
|
114
|
+
print("\nremove_tags:")
|
115
|
+
print(remove_tags(string="<div>Hello <b>World</b></div>")) # "divHello bWorldbdiv"
|
116
|
+
|
117
|
+
print("\nremove_tags_and_html:")
|
118
|
+
print(remove_tags_and_html("<div>Hello <b>World</b></div>")) # "Hello World"
|
78
119
|
|
79
120
|
|
80
121
|
if __name__ == '__main__':
|
arpakitlib/ar_type_util.py
CHANGED
@@ -67,13 +67,77 @@ def raise_for_types(comparable, need_types, comment_for_error: Optional[str] = N
|
|
67
67
|
raise TypeError(err)
|
68
68
|
|
69
69
|
|
70
|
-
def
|
71
|
-
if
|
72
|
-
|
70
|
+
def make_none_to_false(v: Any) -> Any:
|
71
|
+
if v is None:
|
72
|
+
return False
|
73
|
+
return v
|
74
|
+
|
75
|
+
|
76
|
+
def raise_if_none(v: Any) -> Any:
|
77
|
+
if v is None:
|
78
|
+
raise ValueError(f"v is None, v={v}, type(v)={type(v)}")
|
79
|
+
return v
|
80
|
+
|
81
|
+
|
82
|
+
def raise_if_not_none(v: Any) -> Any:
|
83
|
+
if v is not None:
|
84
|
+
raise ValueError(f"v is not None, v={v}, type(v)={type(v)}")
|
85
|
+
return v
|
73
86
|
|
74
87
|
|
75
88
|
def __example():
|
76
|
-
|
89
|
+
print("is_set:")
|
90
|
+
print(is_set(v=NotSet)) # False
|
91
|
+
print(is_set(v="hello world")) # True
|
92
|
+
|
93
|
+
print("\nis_not_set:")
|
94
|
+
print(is_not_set(v=NotSet)) # True
|
95
|
+
print(is_not_set(v="hello world")) # False
|
96
|
+
|
97
|
+
print("\nis_set_and_not_none:")
|
98
|
+
print(is_set_and_not_none(v=NotSet)) # False
|
99
|
+
print(is_set_and_not_none(v=None)) # False
|
100
|
+
print(is_set_and_not_none(v=1000)) # True
|
101
|
+
|
102
|
+
print("\nis_not_set_or_none:")
|
103
|
+
print(is_not_set_or_none(v=NotSet)) # True
|
104
|
+
print(is_not_set_or_none(v=None)) # True
|
105
|
+
print(is_not_set_or_none(v=100)) # False
|
106
|
+
|
107
|
+
print("\nmake_none_if_not_set:")
|
108
|
+
print(make_none_if_not_set(v=NotSet)) # None
|
109
|
+
print(make_none_if_not_set(v="hello world")) # hello world
|
110
|
+
|
111
|
+
print("\nmake_none_to_false:")
|
112
|
+
print(make_none_to_false(v=None)) # False
|
113
|
+
print(make_none_to_false(v=True)) # True
|
114
|
+
print(make_none_to_false(v=100)) # 100
|
115
|
+
|
116
|
+
print("\nraise_if_set:")
|
117
|
+
try:
|
118
|
+
raise_if_set(v=100) # raise
|
119
|
+
except ValueError as e:
|
120
|
+
print(e)
|
121
|
+
|
122
|
+
print("\nraise_if_set:")
|
123
|
+
try:
|
124
|
+
raise_if_not_set(v=NotSet) # raise
|
125
|
+
except ValueError as e:
|
126
|
+
print(e)
|
127
|
+
|
128
|
+
print("\nraise_for_type:")
|
129
|
+
try:
|
130
|
+
raise_for_type(comparable="test", need_type=str) # pass
|
131
|
+
raise_for_type(comparable=100, need_type=str) # raise
|
132
|
+
except TypeError as e:
|
133
|
+
print(e)
|
134
|
+
|
135
|
+
print("\nraise_for_types:")
|
136
|
+
try:
|
137
|
+
raise_for_types(comparable="test", need_types=[str, int]) # pass
|
138
|
+
raise_for_types(comparable=100.5, need_types=[str, int], comment_for_error="Ooops") # raise
|
139
|
+
except TypeError as e:
|
140
|
+
print(e)
|
77
141
|
|
78
142
|
|
79
143
|
if __name__ == '__main__':
|