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.
Files changed (77) hide show
  1. arpakitlib/_arpakit_project_template_v_5/arpakitlib_project_template_info.json +1 -1
  2. arpakitlib/_arpakit_project_template_v_5/command/emojize.py +9 -0
  3. arpakitlib/_arpakit_project_template_v_5/project/api/create_api_app.py +12 -2
  4. arpakitlib/_arpakit_project_template_v_5/project/api/exception_handler.py +1 -1
  5. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/check_sqlalchemy_db.py +43 -0
  6. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/clear_log_file.py +44 -0
  7. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/create_operation.py +78 -0
  8. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_arpakitlib_project_template_info.py +8 -2
  9. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_auth_data.py +8 -2
  10. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_log_file.py +33 -0
  11. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_operation.py +63 -0
  12. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_operation_allowed_statuses.py +40 -0
  13. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_operation_allowed_types.py +40 -0
  14. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_sqlalchemy_db_table_name_to_amount.py +39 -0
  15. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/get_story_log.py +14 -4
  16. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/init_sqlalchemy_db.py +8 -2
  17. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/main_router.py +43 -1
  18. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/raise_fake_error.py +1 -2
  19. arpakitlib/_arpakit_project_template_v_5/project/api/router/admin/reinit_sqlalchemy_db.py +8 -2
  20. arpakitlib/_arpakit_project_template_v_5/project/api/router/client/get_current_user.py +11 -3
  21. arpakitlib/_arpakit_project_template_v_5/project/api/router/client/get_current_user_token.py +10 -3
  22. arpakitlib/_arpakit_project_template_v_5/project/api/router/client/main_router.py +1 -11
  23. arpakitlib/_arpakit_project_template_v_5/project/api/router/general/check_authorization.py +46 -0
  24. arpakitlib/_arpakit_project_template_v_5/project/api/router/{client → general}/get_current_api_key.py +9 -3
  25. arpakitlib/_arpakit_project_template_v_5/project/api/router/{client → general}/get_errors_info.py +10 -8
  26. arpakitlib/_arpakit_project_template_v_5/project/api/router/general/healthcheck.py +12 -3
  27. arpakitlib/_arpakit_project_template_v_5/project/api/router/general/main_router.py +18 -1
  28. arpakitlib/_arpakit_project_template_v_5/project/api/router/general/now_utc_datetime.py +14 -2
  29. arpakitlib/_arpakit_project_template_v_5/project/api/schema/common.py +11 -0
  30. arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/admin/common.py +1 -0
  31. arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/admin/operation.py +6 -3
  32. arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/admin/story_log.py +8 -6
  33. arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/client/common.py +3 -1
  34. arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/client/user.py +14 -5
  35. arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/client/user_token.py +5 -3
  36. arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/{client → general}/api_key.py +5 -3
  37. arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/user.py +31 -0
  38. arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/user_token.py +16 -0
  39. arpakitlib/_arpakit_project_template_v_5/project/operation_execution/operation_executor_worker.py +27 -4
  40. arpakitlib/_arpakit_project_template_v_5/project/operation_execution/scheduled_operation_creator_worker.py +2 -1
  41. arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_1.py +6 -1
  42. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/api_key.py +4 -11
  43. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/common.py +1 -1
  44. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/operation.py +6 -18
  45. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/story_log.py +5 -15
  46. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user.py +5 -15
  47. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user_token.py +5 -11
  48. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/operation.py +6 -1
  49. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/story_log.py +6 -9
  50. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user.py +30 -30
  51. arpakitlib/_arpakit_project_template_v_5/project/sqlalchemy_db_/sqlalchemy_model/user_token.py +4 -0
  52. arpakitlib/_arpakit_project_template_v_5/project/test_data/make_test_api_keys.py +2 -2
  53. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/blank/{client.py → general.py} +7 -6
  54. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/const.py +2 -2
  55. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/kb/inline_/client/hello_world.py +1 -1
  56. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/kb/static_/client/hello_world.py +1 -1
  57. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/about.py +4 -4
  58. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/author.py +4 -4
  59. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/error_handler.py +2 -2
  60. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/healthcheck.py +3 -3
  61. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/hello_world.py +3 -3
  62. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/raw_callback_query.py +1 -1
  63. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/raw_message.py +1 -1
  64. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/start.py +4 -4
  65. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/support.py +4 -4
  66. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/util/set_tg_bot_commands.py +14 -14
  67. arpakitlib/ar_enumeration_util.py +2 -2
  68. arpakitlib/ar_sqlalchemy_util.py +52 -24
  69. arpakitlib/ar_str_util.py +6 -0
  70. arpakitlib/ar_zabbix_api_client_util.py +43 -3
  71. {arpakitlib-1.8.36.dist-info → arpakitlib-1.8.39.dist-info}/METADATA +1 -1
  72. {arpakitlib-1.8.36.dist-info → arpakitlib-1.8.39.dist-info}/RECORD +75 -65
  73. arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/errors_info_general.py +0 -6
  74. arpakitlib/_arpakit_project_template_v_5/project/api/schema/out/general/healthcheck.py +0 -5
  75. {arpakitlib-1.8.36.dist-info → arpakitlib-1.8.39.dist-info}/LICENSE +0 -0
  76. {arpakitlib-1.8.36.dist-info → arpakitlib-1.8.39.dist-info}/WHEEL +0 -0
  77. {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.client import get_cached_client_tg_bot_blank
12
- from project.tg_bot.const import ClientTgBotCommands, AdminTgBotCommands
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=ClientTgBotCommands.start,
21
+ command=GeneralTgBotCommands.start,
22
22
  description=return_str_if_none(
23
- get_cached_client_tg_bot_blank().command_to_desc().get(ClientTgBotCommands.start),
24
- ClientTgBotCommands.start
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=ClientTgBotCommands.about,
28
+ command=GeneralTgBotCommands.about,
29
29
  description=return_str_if_none(
30
- get_cached_client_tg_bot_blank().command_to_desc().get(ClientTgBotCommands.about),
31
- ClientTgBotCommands.about
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=ClientTgBotCommands.support,
35
+ command=GeneralTgBotCommands.support,
36
36
  description=return_str_if_none(
37
- get_cached_client_tg_bot_blank().command_to_desc().get(ClientTgBotCommands.support),
38
- ClientTgBotCommands.support
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=ClientTgBotCommands.author,
42
+ command=GeneralTgBotCommands.author,
43
43
  description=return_str_if_none(
44
- get_cached_client_tg_bot_blank().command_to_desc().get(ClientTgBotCommands.author),
45
- ClientTgBotCommands.author
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"validate is True and {value} not in {cls.values_set()}")
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"validate is True and {value_} not in {cls.values_set()}")
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)}")
@@ -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
- exclude_sd_properties: set[str] | None = None
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_") and isinstance(getattr(type(self), attr_name, None), property):
97
-
98
- sdp_property_name = attr_name.removeprefix("sdp_")
99
- if sdp_property_name in exclude_sd_properties:
100
- continue # Пропускаем свойство, если оно в exclude_sdp_properties
101
-
102
- value = getattr(self, attr_name)
103
- if isinstance(value, BaseDBM):
104
- res[sdp_property_name] = value.simple_dict(include_sd_properties=include_sd_properties)
105
- elif isinstance(value, list):
106
- res[sdp_property_name] = [
107
- item.simple_dict(include_sd_properties=include_sd_properties)
108
- if isinstance(item, BaseDBM) else item
109
- for item in value
110
- ]
111
- else:
112
- res[sdp_property_name] = value
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
- exclude_sdp_properties: set[str] | None = None
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
- exclude_sd_properties=exclude_sdp_properties
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
- exclude_sdp_properties: set[str] | None = None
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
- exclude_sd_properties=exclude_sdp_properties
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
- beautify=True,
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
- self.zabbix_api = ZabbixAPI(server=self.api_url, timeout=timeout.total_seconds())
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
- pass
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():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: arpakitlib
3
- Version: 1.8.36
3
+ Version: 1.8.39
4
4
  Summary: arpakitlib
5
5
  License: Apache-2.0
6
6
  Keywords: arpakitlib,arpakit,arpakit-company,arpakitcompany,arpakit_company