arpakitlib 1.8.36__py3-none-any.whl → 1.8.39__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_v_5/arpakitlib_project_template_info.json +1 -1
- arpakitlib/_arpakit_project_template_v_5/command/emojize.py +9 -0
- arpakitlib/_arpakit_project_template_v_5/project/api/create_api_app.py +12 -2
- arpakitlib/_arpakit_project_template_v_5/project/api/exception_handler.py +1 -1
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/check_sqlalchemy_db.py +43 -0
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/clear_log_file.py +44 -0
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/create_operation.py +78 -0
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_arpakitlib_project_template_info.py +8 -2
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_auth_data.py +8 -2
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_log_file.py +33 -0
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_operation.py +63 -0
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_operation_allowed_statuses.py +40 -0
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_operation_allowed_types.py +40 -0
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_sqlalchemy_db_table_name_to_amount.py +39 -0
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_story_log.py +14 -4
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/init_sqlalchemy_db.py +8 -2
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/main_router.py +43 -1
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/raise_fake_error.py +1 -2
- arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/reinit_sqlalchemy_db.py +8 -2
- arpakitlib/_arpakit_project_template_v_5/project/api/router/client/get_current_user.py +11 -3
- arpakitlib/_arpakit_project_template_v_5/project/api/router/client/get_current_user_token.py +10 -3
- arpakitlib/_arpakit_project_template_v_5/project/api/router/client/main_router.py +1 -11
- arpakitlib/_arpakit_project_template_v_5/project/api/router/general/check_authorization.py +46 -0
- arpakitlib/_arpakit_project_template_v_5/project/api/router/{client → general}/get_current_api_key.py +9 -3
- arpakitlib/_arpakit_project_template_v_5/project/api/router/{client → general}/get_errors_info.py +10 -8
- arpakitlib/_arpakit_project_template_v_5/project/api/router/general/healthcheck.py +12 -3
- arpakitlib/_arpakit_project_template_v_5/project/api/router/general/main_router.py +18 -1
- arpakitlib/_arpakit_project_template_v_5/project/api/router/general/now_utc_datetime.py +14 -2
- arpakitlib/_arpakit_project_template_v_5/project/api/schema/common.py +11 -0
- arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/admin/common.py +1 -0
- arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/admin/operation.py +6 -3
- arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/admin/story_log.py +8 -6
- arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/client/common.py +3 -1
- arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/client/user.py +14 -5
- arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/client/user_token.py +5 -3
- arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/{client → general}/api_key.py +5 -3
- arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/user.py +31 -0
- arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/user_token.py +16 -0
- arpakitlib/_arpakit_project_template_v_5/project/operation_execution/operation_executor_worker.py +27 -4
- arpakitlib/_arpakit_project_template_v_5/project/operation_execution/scheduled_operation_creator_worker.py +2 -1
- arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_1.py +6 -1
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/api_key.py +4 -11
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/common.py +1 -1
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/operation.py +6 -18
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/story_log.py +5 -15
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user.py +5 -15
- arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user_token.py +5 -11
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/operation.py +6 -1
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/story_log.py +6 -9
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user.py +30 -30
- arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user_token.py +4 -0
- arpakitlib/_arpakit_project_template_v_5/project/test_data/make_test_api_keys.py +2 -2
- arpakitlib/_arpakit_project_template_v_5/project/tg_bot/blank/{client.py → general.py} +7 -6
- arpakitlib/_arpakit_project_template_v_5/project/tg_bot/const.py +2 -2
- arpakitlib/_arpakit_project_template_v_5/project/tg_bot/kb/inline_/client/hello_world.py +1 -1
- arpakitlib/_arpakit_project_template_v_5/project/tg_bot/kb/static_/client/hello_world.py +1 -1
- arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/about.py +4 -4
- arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/author.py +4 -4
- arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/error_handler.py +2 -2
- arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/healthcheck.py +3 -3
- arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/hello_world.py +3 -3
- arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/raw_callback_query.py +1 -1
- arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/raw_message.py +1 -1
- arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/start.py +4 -4
- arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/support.py +4 -4
- arpakitlib/_arpakit_project_template_v_5/project/tg_bot/util/set_tg_bot_commands.py +14 -14
- arpakitlib/ar_enumeration_util.py +2 -2
- arpakitlib/ar_sqlalchemy_util.py +52 -24
- arpakitlib/ar_str_util.py +6 -0
- arpakitlib/ar_zabbix_api_client_util.py +43 -3
- {arpakitlib-1.8.36.dist-info → arpakitlib-1.8.39.dist-info}/METADATA +1 -1
- {arpakitlib-1.8.36.dist-info → arpakitlib-1.8.39.dist-info}/RECORD +75 -65
- arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/errors_info_general.py +0 -6
- arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/healthcheck.py +0 -5
- {arpakitlib-1.8.36.dist-info → arpakitlib-1.8.39.dist-info}/LICENSE +0 -0
- {arpakitlib-1.8.36.dist-info → arpakitlib-1.8.39.dist-info}/WHEEL +0 -0
- {arpakitlib-1.8.36.dist-info → arpakitlib-1.8.39.dist-info}/entry_points.txt +0 -0
@@ -8,8 +8,8 @@ from project.core.settings import get_cached_settings
|
|
8
8
|
from project.core.util import setup_logging
|
9
9
|
from project.sqlalchemy_db_.sqlalchemy_db import get_cached_sqlalchemy_db
|
10
10
|
from project.sqlalchemy_db_.sqlalchemy_model import UserDBM
|
11
|
-
from project.tg_bot.blank.
|
12
|
-
from project.tg_bot.const import
|
11
|
+
from project.tg_bot.blank.general import get_cached_client_tg_bot_blank
|
12
|
+
from project.tg_bot.const import GeneralTgBotCommands, AdminTgBotCommands
|
13
13
|
from project.tg_bot.tg_bot import get_cached_tg_bot
|
14
14
|
|
15
15
|
_logger = logging.getLogger(__name__)
|
@@ -18,31 +18,31 @@ _logger = logging.getLogger(__name__)
|
|
18
18
|
def get_client_tg_bot_commands_to_set() -> list[BotCommand]:
|
19
19
|
res = [
|
20
20
|
BotCommand(
|
21
|
-
command=
|
21
|
+
command=GeneralTgBotCommands.start,
|
22
22
|
description=return_str_if_none(
|
23
|
-
get_cached_client_tg_bot_blank().command_to_desc().get(
|
24
|
-
|
23
|
+
get_cached_client_tg_bot_blank().command_to_desc().get(GeneralTgBotCommands.start),
|
24
|
+
GeneralTgBotCommands.start
|
25
25
|
)
|
26
26
|
),
|
27
27
|
BotCommand(
|
28
|
-
command=
|
28
|
+
command=GeneralTgBotCommands.about,
|
29
29
|
description=return_str_if_none(
|
30
|
-
get_cached_client_tg_bot_blank().command_to_desc().get(
|
31
|
-
|
30
|
+
get_cached_client_tg_bot_blank().command_to_desc().get(GeneralTgBotCommands.about),
|
31
|
+
GeneralTgBotCommands.about
|
32
32
|
)
|
33
33
|
),
|
34
34
|
BotCommand(
|
35
|
-
command=
|
35
|
+
command=GeneralTgBotCommands.support,
|
36
36
|
description=return_str_if_none(
|
37
|
-
get_cached_client_tg_bot_blank().command_to_desc().get(
|
38
|
-
|
37
|
+
get_cached_client_tg_bot_blank().command_to_desc().get(GeneralTgBotCommands.support),
|
38
|
+
GeneralTgBotCommands.support
|
39
39
|
)
|
40
40
|
),
|
41
41
|
BotCommand(
|
42
|
-
command=
|
42
|
+
command=GeneralTgBotCommands.author,
|
43
43
|
description=return_str_if_none(
|
44
|
-
get_cached_client_tg_bot_blank().command_to_desc().get(
|
45
|
-
|
44
|
+
get_cached_client_tg_bot_blank().command_to_desc().get(GeneralTgBotCommands.author),
|
45
|
+
GeneralTgBotCommands.author
|
46
46
|
)
|
47
47
|
)
|
48
48
|
|
@@ -48,14 +48,14 @@ class Enumeration:
|
|
48
48
|
|
49
49
|
if isinstance(value, str) or isinstance(value, int):
|
50
50
|
if validate is True and value not in cls.values_set():
|
51
|
-
raise ValueError(f"
|
51
|
+
raise ValueError(f"{value} not in {cls.values_set()}")
|
52
52
|
res.append(value)
|
53
53
|
|
54
54
|
elif isinstance(value, Iterable):
|
55
55
|
for value_ in value:
|
56
56
|
if isinstance(value_, str) or isinstance(value_, int):
|
57
57
|
if validate is True and value_ not in cls.values_set():
|
58
|
-
raise ValueError(f"
|
58
|
+
raise ValueError(f"{value_} not in {cls.values_set()}")
|
59
59
|
res.append(value_)
|
60
60
|
else:
|
61
61
|
raise TypeError(f"bad type, value={value}, type={type(value)}")
|
arpakitlib/ar_sqlalchemy_util.py
CHANGED
@@ -73,7 +73,10 @@ class BaseDBM(DeclarativeBase):
|
|
73
73
|
*,
|
74
74
|
include_sd_properties: bool = True,
|
75
75
|
exclude_columns: set[str] | None = None,
|
76
|
-
|
76
|
+
only_columns: list[str] | None = None,
|
77
|
+
exclude_sd_properties: set[str] | None = None,
|
78
|
+
only_sd_properties: list[str] | None = None,
|
79
|
+
only_columns_and_sd_properties: list[str] | None = None
|
77
80
|
) -> dict[str, Any]:
|
78
81
|
if exclude_columns is None:
|
79
82
|
exclude_columns = set()
|
@@ -84,6 +87,10 @@ class BaseDBM(DeclarativeBase):
|
|
84
87
|
|
85
88
|
# Обрабатываем только колонки текущей модели
|
86
89
|
for c in inspect(self).mapper.column_attrs:
|
90
|
+
if only_columns_and_sd_properties is not None and c.key not in only_columns_and_sd_properties:
|
91
|
+
continue # Пропускаем колонку, если она не в only_columns_and_sd_properties
|
92
|
+
if only_columns is not None and c.key not in only_columns:
|
93
|
+
continue # Пропускаем колонку, если она не в only_columns
|
87
94
|
if c.key in exclude_columns:
|
88
95
|
continue # Пропускаем колонку, если она в exclude_columns
|
89
96
|
|
@@ -93,23 +100,32 @@ class BaseDBM(DeclarativeBase):
|
|
93
100
|
# Обработка свойств с префиксом "sdp_"
|
94
101
|
if include_sd_properties:
|
95
102
|
for attr_name in dir(self):
|
96
|
-
if attr_name.startswith("sdp_")
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
103
|
+
if not attr_name.startswith("sdp_") or not isinstance(getattr(type(self), attr_name, None), property):
|
104
|
+
continue
|
105
|
+
|
106
|
+
sd_property_name = attr_name.removeprefix("sdp_")
|
107
|
+
|
108
|
+
if (
|
109
|
+
only_columns_and_sd_properties is not None
|
110
|
+
and sd_property_name not in only_columns_and_sd_properties
|
111
|
+
):
|
112
|
+
continue # Пропускаем свойство, если оно не в only_columns_and_sd_properties
|
113
|
+
if only_sd_properties is not None and sd_property_name not in only_sd_properties:
|
114
|
+
continue # Пропускаем свойство, если оно не в only_sd_properties
|
115
|
+
if sd_property_name in exclude_sd_properties:
|
116
|
+
continue # Пропускаем свойство, если оно в exclude_sd_properties
|
117
|
+
|
118
|
+
value = getattr(self, attr_name)
|
119
|
+
if isinstance(value, BaseDBM):
|
120
|
+
res[sd_property_name] = value.simple_dict(include_sd_properties=include_sd_properties)
|
121
|
+
elif isinstance(value, list):
|
122
|
+
res[sd_property_name] = [
|
123
|
+
item.simple_dict(include_sd_properties=include_sd_properties)
|
124
|
+
if isinstance(item, BaseDBM) else item
|
125
|
+
for item in value
|
126
|
+
]
|
127
|
+
else:
|
128
|
+
res[sd_property_name] = value
|
113
129
|
|
114
130
|
return res
|
115
131
|
|
@@ -117,12 +133,18 @@ class BaseDBM(DeclarativeBase):
|
|
117
133
|
self,
|
118
134
|
*,
|
119
135
|
exclude_columns: set[str] | None = None,
|
120
|
-
|
136
|
+
only_columns: list[str] | None = None,
|
137
|
+
exclude_sdp_properties: set[str] | None = None,
|
138
|
+
only_sd_properties: list[str] | None = None,
|
139
|
+
only_columns_and_sd_properties: list[str] | None = None # Новый параметр
|
121
140
|
) -> dict[str, Any]:
|
122
141
|
return self.simple_dict(
|
123
142
|
include_sd_properties=True,
|
124
143
|
exclude_columns=exclude_columns,
|
125
|
-
|
144
|
+
only_columns=only_columns,
|
145
|
+
exclude_sd_properties=exclude_sdp_properties,
|
146
|
+
only_sd_properties=only_sd_properties,
|
147
|
+
only_columns_and_sd_properties=only_columns_and_sd_properties # Новый параметр
|
126
148
|
)
|
127
149
|
|
128
150
|
def simple_dict_json(
|
@@ -130,16 +152,22 @@ class BaseDBM(DeclarativeBase):
|
|
130
152
|
*,
|
131
153
|
include_sd_properties: bool = True,
|
132
154
|
exclude_columns: set[str] | None = None,
|
133
|
-
|
155
|
+
only_columns: list[str] | None = None,
|
156
|
+
exclude_sd_properties: set[str] | None = None,
|
157
|
+
only_sd_properties: list[str] | None = None,
|
158
|
+
only_columns_and_sd_properties: list[str] | None = None,
|
159
|
+
**transfer_data_to_json_str_kwargs
|
134
160
|
) -> str:
|
135
161
|
return transfer_data_to_json_str(
|
136
162
|
data=self.simple_dict(
|
137
163
|
include_sd_properties=include_sd_properties,
|
138
164
|
exclude_columns=exclude_columns,
|
139
|
-
|
165
|
+
only_columns=only_columns,
|
166
|
+
exclude_sd_properties=exclude_sd_properties,
|
167
|
+
only_sd_properties=only_sd_properties,
|
168
|
+
only_columns_and_sd_properties=only_columns_and_sd_properties
|
140
169
|
),
|
141
|
-
|
142
|
-
fast=False
|
170
|
+
**transfer_data_to_json_str_kwargs
|
143
171
|
)
|
144
172
|
|
145
173
|
|
arpakitlib/ar_str_util.py
CHANGED
@@ -98,6 +98,12 @@ def return_str_if_none(value: str | None, value_str: str) -> str:
|
|
98
98
|
return value
|
99
99
|
|
100
100
|
|
101
|
+
def strip_if_not_none(v: str | None) -> str | None:
|
102
|
+
if v is None:
|
103
|
+
return v
|
104
|
+
return v.strip()
|
105
|
+
|
106
|
+
|
101
107
|
def __example():
|
102
108
|
print("str_in:")
|
103
109
|
print(str_in(string="hello", main_string="hello world"))
|
@@ -3,10 +3,12 @@ import asyncio
|
|
3
3
|
import logging
|
4
4
|
import time
|
5
5
|
from datetime import timedelta, datetime
|
6
|
-
from typing import Any, Optional, Self
|
6
|
+
from typing import Any, Optional, Self, Iterator
|
7
7
|
|
8
8
|
from pyzabbix import ZabbixAPI
|
9
9
|
|
10
|
+
from arpakitlib.ar_list_util import iter_group_list
|
11
|
+
from arpakitlib.ar_logging_util import setup_normal_logging
|
10
12
|
from arpakitlib.ar_type_util import raise_for_type
|
11
13
|
|
12
14
|
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
@@ -41,10 +43,23 @@ class ZabbixApiClient:
|
|
41
43
|
pass
|
42
44
|
else:
|
43
45
|
raise_for_type(timeout, timedelta)
|
44
|
-
|
46
|
+
|
47
|
+
self.zabbix_api = ZabbixAPI(
|
48
|
+
server=self.api_url,
|
49
|
+
timeout=timeout.total_seconds(),
|
50
|
+
)
|
51
|
+
self.zabbix_api.session.verify = False
|
52
|
+
|
53
|
+
self.is_logged_in = False
|
45
54
|
|
46
55
|
def login(self) -> Self:
|
47
56
|
self.zabbix_api.login(user=self.api_user, password=self.api_password)
|
57
|
+
self.is_logged_in = True
|
58
|
+
return self
|
59
|
+
|
60
|
+
def login_if_not_logged_in(self):
|
61
|
+
if not self.is_logged_in:
|
62
|
+
self.login()
|
48
63
|
return self
|
49
64
|
|
50
65
|
def is_login_good(self) -> bool:
|
@@ -57,6 +72,7 @@ class ZabbixApiClient:
|
|
57
72
|
|
58
73
|
def get_host_ids(self) -> list[str]:
|
59
74
|
kwargs = {"output": ["hostid"]}
|
75
|
+
self.login_if_not_logged_in()
|
60
76
|
host_ids = self.zabbix_api.host.get(**kwargs)
|
61
77
|
kwargs["sortfield"] = "hostid"
|
62
78
|
kwargs["sortorder"] = "DESC"
|
@@ -75,10 +91,23 @@ class ZabbixApiClient:
|
|
75
91
|
kwargs["sortfield"] = "hostid"
|
76
92
|
kwargs["sortorder"] = "DESC"
|
77
93
|
|
94
|
+
self.login_if_not_logged_in()
|
78
95
|
hosts = self.zabbix_api.host.get(**kwargs)
|
79
96
|
|
80
97
|
return hosts
|
81
98
|
|
99
|
+
def iter_all_hosts(self) -> Iterator[list[dict[str, Any]]]:
|
100
|
+
host_ids = self.login_if_not_logged_in().get_host_ids()
|
101
|
+
for zabbix_api_host_ids in iter_group_list(list_=host_ids, n=100):
|
102
|
+
hosts = self.get_hosts(host_ids=zabbix_api_host_ids)
|
103
|
+
yield hosts
|
104
|
+
|
105
|
+
def get_all_hosts(self) -> list[dict[str, Any]]:
|
106
|
+
res = []
|
107
|
+
for hosts in self.iter_all_hosts():
|
108
|
+
res += hosts
|
109
|
+
return res
|
110
|
+
|
82
111
|
def get_item_ids(
|
83
112
|
self,
|
84
113
|
*,
|
@@ -106,6 +135,7 @@ class ZabbixApiClient:
|
|
106
135
|
kwargs["limit"] = limit
|
107
136
|
kwargs["sortfield"] = "itemid"
|
108
137
|
kwargs["sortorder"] = "DESC"
|
138
|
+
self.login_if_not_logged_in()
|
109
139
|
itemid_ids = self.zabbix_api.item.get(**kwargs)
|
110
140
|
res = [d["itemid"] for d in itemid_ids]
|
111
141
|
return res
|
@@ -143,6 +173,7 @@ class ZabbixApiClient:
|
|
143
173
|
kwargs["limit"] = limit
|
144
174
|
kwargs["sortfield"] = "itemid"
|
145
175
|
kwargs["sortorder"] = "DESC"
|
176
|
+
self.login_if_not_logged_in()
|
146
177
|
res = self.zabbix_api.item.get(**kwargs)
|
147
178
|
return res
|
148
179
|
|
@@ -178,7 +209,9 @@ class ZabbixApiClient:
|
|
178
209
|
0, 0
|
179
210
|
)))
|
180
211
|
|
212
|
+
self.login_if_not_logged_in()
|
181
213
|
histories: list[dict[str, Any]] = self.zabbix_api.history.get(**kwargs)
|
214
|
+
|
182
215
|
for history in histories:
|
183
216
|
if "clock" in history.keys():
|
184
217
|
clock_ns_as_datetime = datetime.fromtimestamp(int(history["clock"]))
|
@@ -196,7 +229,14 @@ ZabbixAPIClient = ZabbixApiClient
|
|
196
229
|
|
197
230
|
|
198
231
|
def __example():
|
199
|
-
|
232
|
+
setup_normal_logging()
|
233
|
+
zabbix = ZabbixAPIClient(
|
234
|
+
api_url=...,
|
235
|
+
api_user=...,
|
236
|
+
api_password=...
|
237
|
+
)
|
238
|
+
|
239
|
+
print(zabbix.is_login_good())
|
200
240
|
|
201
241
|
|
202
242
|
async def __async_example():
|