hcs-core 0.1.317__tar.gz → 0.1.319__tar.gz

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 (71) hide show
  1. {hcs_core-0.1.317 → hcs_core-0.1.319}/PKG-INFO +4 -4
  2. {hcs_core-0.1.317 → hcs_core-0.1.319}/README.md +0 -1
  3. hcs_core-0.1.319/hcs_core/__init__.py +1 -0
  4. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/cli_options.py +12 -1
  5. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/cli_processor.py +0 -1
  6. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/context.py +1 -2
  7. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/data_util.py +0 -2
  8. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/dispatcher.py +5 -4
  9. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/fstore.py +0 -1
  10. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/profile.py +0 -1
  11. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/task_schd.py +2 -1
  12. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/telemetry.py +0 -1
  13. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/util.py +6 -4
  14. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/plan/core.py +0 -1
  15. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/plan/provider/dev/fibonacci.py +6 -4
  16. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/sglib/client_util.py +1 -1
  17. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/sglib/ez_client.py +27 -6
  18. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/sglib/utils.py +0 -1
  19. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/util/duration.py +0 -1
  20. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/util/pki_util.py +0 -1
  21. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/util/query_util.py +3 -3
  22. {hcs_core-0.1.317 → hcs_core-0.1.319}/pyproject.toml +5 -10
  23. hcs_core-0.1.317/hcs_core/__init__.py +0 -1
  24. {hcs_core-0.1.317 → hcs_core-0.1.319}/.gitignore +0 -0
  25. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/__init__.py +0 -0
  26. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/_init.py +0 -0
  27. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/built_in_cmds/__init__.py +0 -0
  28. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/built_in_cmds/_ut.py +0 -0
  29. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/built_in_cmds/context.py +0 -0
  30. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/built_in_cmds/profile.py +0 -0
  31. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/cmd_util.py +0 -0
  32. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/config.py +0 -0
  33. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/duration.py +0 -0
  34. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/extension.py +0 -0
  35. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/fn_util.py +0 -0
  36. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/jsondot.py +0 -0
  37. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/logger.py +0 -0
  38. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/profile_store.py +0 -0
  39. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/recent.py +0 -0
  40. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/state.py +0 -0
  41. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/template_util.py +0 -0
  42. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/timeutil.py +0 -0
  43. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/ctxp/var_template.py +0 -0
  44. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/plan/__init__.py +0 -0
  45. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/plan/actions.py +0 -0
  46. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/plan/base_provider.py +0 -0
  47. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/plan/context.py +0 -0
  48. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/plan/dag.py +0 -0
  49. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/plan/helper.py +0 -0
  50. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/plan/kop.py +0 -0
  51. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/plan/provider/__init__.py +0 -0
  52. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/plan/provider/dev/__init__.py +0 -0
  53. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/plan/provider/dev/_prepare.py +0 -0
  54. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/plan/provider/dev/dummy.py +0 -0
  55. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/sglib/__init__.py +0 -0
  56. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/sglib/auth.py +0 -0
  57. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/sglib/cli_options.py +0 -0
  58. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/sglib/csp.py +0 -0
  59. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/sglib/hcs_client.py +0 -0
  60. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/sglib/init.py +0 -0
  61. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/sglib/login_support.py +0 -0
  62. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/sglib/payload_util.py +0 -0
  63. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/sglib/requtil.py +0 -0
  64. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/util/__init__.py +0 -0
  65. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/util/check_license.py +0 -0
  66. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/util/exit.py +0 -0
  67. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/util/hcs_constants.py +0 -0
  68. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/util/job_view.py +0 -0
  69. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/util/scheduler.py +0 -0
  70. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/util/ssl_util.py +0 -0
  71. {hcs_core-0.1.317 → hcs_core-0.1.319}/hcs_core/util/versions.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hcs-core
3
- Version: 0.1.317
3
+ Version: 0.1.319
4
4
  Summary: Horizon Cloud Service CLI module.
5
5
  Project-URL: Homepage, https://github.com/euc-eng/hcs-cli
6
6
  Project-URL: Bug Tracker, https://github.com/euc-eng/hcs-cli/issues
@@ -35,10 +35,9 @@ Requires-Dist: rich>=14.0.0
35
35
  Requires-Dist: schedule>=1.1.0
36
36
  Requires-Dist: tabulate>=0.9.0
37
37
  Requires-Dist: websocket-client>=1.2.3
38
- Requires-Dist: yumako>=0.1.36
38
+ Requires-Dist: yumako>=0.1.37
39
39
  Provides-Extra: dev
40
40
  Requires-Dist: bandit; extra == 'dev'
41
- Requires-Dist: black; extra == 'dev'
42
41
  Requires-Dist: build; extra == 'dev'
43
42
  Requires-Dist: flake8; extra == 'dev'
44
43
  Requires-Dist: hatch; extra == 'dev'
@@ -47,8 +46,9 @@ Requires-Dist: pylint; extra == 'dev'
47
46
  Requires-Dist: pytest; extra == 'dev'
48
47
  Requires-Dist: ruff; extra == 'dev'
49
48
  Requires-Dist: twine; extra == 'dev'
49
+ Requires-Dist: vulture; extra == 'dev'
50
50
  Requires-Dist: wheel; extra == 'dev'
51
+ Requires-Dist: yamlfix; extra == 'dev'
51
52
  Description-Content-Type: text/markdown
52
53
 
53
54
  hcs-cli core component.
54
-
@@ -1,2 +1 @@
1
1
  hcs-cli core component.
2
-
@@ -0,0 +1 @@
1
+ __version__ = "0.1.319"
@@ -76,7 +76,18 @@ sort = click.option(
76
76
  help="Ascending/Descending. Format is property,{asc|desc} and default is ascending",
77
77
  )
78
78
 
79
- limit = click.option("--limit", "-l", type=int, required=False, default=100, help="Optionally, specify the number of records to fetch.")
79
+
80
+ def limit(func=None, *, default=100):
81
+ decorator = click.option(
82
+ "--limit", "-l", type=int, required=False, default=default, help="Optionally, specify the number of records to fetch."
83
+ )
84
+ if func is not None:
85
+ # Called as @limit (without parentheses)
86
+ return decorator(func)
87
+ else:
88
+ # Called as @limit() or @limit(default=...)
89
+ return decorator
90
+
80
91
 
81
92
  ids = click.option(
82
93
  "--ids",
@@ -167,7 +167,6 @@ def _import_cmd_file(mod_path: Path, parent: click.core.Group):
167
167
 
168
168
  # Create a new decorator that combines the individual decorators
169
169
  def _default_io(cmd: click.Command):
170
-
171
170
  from .cli_options import exclude_field, field, first, ids, output
172
171
 
173
172
  cmd = output(cmd)
@@ -81,8 +81,7 @@ class Context:
81
81
  self._store.save(key=self.name, data=self.data)
82
82
  return False
83
83
 
84
- def apply_variables(self, object: any, additional_vars: dict = None):
85
-
84
+ def apply_variables(self, object: Any, additional_vars: dict = None):
86
85
  mapping = self._data.copy()
87
86
  if additional_vars:
88
87
  mapping.update(additional_vars)
@@ -16,7 +16,6 @@ def load_data(file_name: str, class_type: str):
16
16
 
17
17
 
18
18
  def load_data_file(file, default=None, format="auto"):
19
-
20
19
  if isinstance(file, TextIOWrapper):
21
20
  text = file.read(-1)
22
21
  text = text.strip()
@@ -259,7 +258,6 @@ def process_variables(obj: dict, fn_get_var=None, use_env: bool = True):
259
258
  fn_get_var = _fn_get_var
260
259
 
261
260
  if use_env:
262
-
263
261
  prev_fn_get_var = fn_get_var
264
262
 
265
263
  def _fn_get_var_from_env(name: str):
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ from typing import Callable
2
3
  from weakref import WeakSet
3
4
 
4
5
  log = logging.getLogger(__name__)
@@ -7,7 +8,7 @@ log = logging.getLogger(__name__)
7
8
  class Dispatcher:
8
9
  _registry: dict = {}
9
10
 
10
- def register(self, key: str, fn: callable):
11
+ def register(self, key: str, fn: Callable):
11
12
  listeners = self._registry.get(key)
12
13
  if not listeners:
13
14
  listeners = WeakSet()
@@ -20,7 +21,7 @@ class Dispatcher:
20
21
  self.register(k, v)
21
22
  return self
22
23
 
23
- def unregister(self, key: str, fn: callable):
24
+ def unregister(self, key: str, fn: Callable):
24
25
  listeners = self._registry.get(key)
25
26
  if listeners:
26
27
  listeners.remove(fn)
@@ -52,7 +53,7 @@ class StrictDispatcher:
52
53
  self._impl = impl
53
54
  self._events = events
54
55
 
55
- def register(self, key: str, fn: callable):
56
+ def register(self, key: str, fn: Callable):
56
57
  self._validate(key)
57
58
  self._impl.register(key, fn)
58
59
  return self
@@ -62,7 +63,7 @@ class StrictDispatcher:
62
63
  self.register(k, v)
63
64
  return self
64
65
 
65
- def unregister(self, key: str, fn: callable):
66
+ def unregister(self, key: str, fn: Callable):
66
67
  self._validate(key)
67
68
  self._impl.unregister(key, fn)
68
69
  return self
@@ -234,7 +234,6 @@ class fstore:
234
234
  if depth == 0:
235
235
  return [f for f in listdir(self._path) if path.isdir(path.join(self._path, f))]
236
236
  else:
237
-
238
237
  return _list_sub_dirs(self._path, depth)
239
238
 
240
239
  raise Exception("TODO: list children for RAM store")
@@ -164,7 +164,6 @@ def get(profile_name: str, reload: bool = False, default=None) -> dotdict:
164
164
 
165
165
 
166
166
  def _load_data_file_with_env_overrides(profile_name: str, default: dict) -> dict:
167
-
168
167
  from ._init import app_name
169
168
 
170
169
  my_name = app_name()
@@ -3,6 +3,7 @@ import threading
3
3
  from copy import deepcopy
4
4
  from dataclasses import dataclass
5
5
  from time import sleep, time
6
+ from typing import Callable
6
7
 
7
8
  import schedule
8
9
 
@@ -78,7 +79,7 @@ def _task_wrapper_once(fn_impl, kwargs):
78
79
  return schedule.CancelJob
79
80
 
80
81
 
81
- def submit(fn_task: callable, initial_delay: str = None, repeat_interval: str = None, **kwargs):
82
+ def submit(fn_task: Callable, initial_delay: str = None, repeat_interval: str = None, **kwargs):
82
83
  if initial_delay:
83
84
  initial_delay_seconds = duration.to_seconds(initial_delay)
84
85
  else:
@@ -127,7 +127,6 @@ def _fix_missing_commands(record):
127
127
 
128
128
 
129
129
  def _injest(doc):
130
-
131
130
  # print('TELEMETRY end', json.dumps(doc, indent=4), flush=True)
132
131
 
133
132
  try:
@@ -21,7 +21,7 @@ import subprocess
21
21
  import sys
22
22
  import traceback
23
23
  import types
24
- from typing import Any, Callable
24
+ from typing import Any, Callable, Union
25
25
 
26
26
  import click
27
27
  import httpx
@@ -34,7 +34,7 @@ class CtxpException(Exception):
34
34
  pass
35
35
 
36
36
 
37
- def error(reason: any, return_code: int = 1) -> tuple[CtxpException, int]:
37
+ def error(reason: Any, return_code: int = 1) -> tuple[CtxpException, int]:
38
38
  # Shortcut if the reason is an Exception already
39
39
  if isinstance(reason, Exception):
40
40
  return reason, return_code
@@ -49,7 +49,7 @@ def error(reason: any, return_code: int = 1) -> tuple[CtxpException, int]:
49
49
  return CtxpException(reason), return_code
50
50
 
51
51
 
52
- def validate_error_return(reason, return_code):
52
+ def validate_error_return(reason: Any, return_code: int):
53
53
  if return_code == 0:
54
54
  raise CtxpException("Invalid return code. return_code must not be 0 (success) in error situation.")
55
55
  if not isinstance(return_code, int):
@@ -391,7 +391,7 @@ def format_table(data: list, fields_mapping: dict, columns_to_sum: list = None):
391
391
  return tabulate(table, headers=headers) + "\n"
392
392
 
393
393
 
394
- def colorize(data: dict, name: str, mapping: dict):
394
+ def colorize(data: dict, name: str, mapping: Union[dict, str, Callable]):
395
395
  if os.environ.get("TERM_COLOR") == "0":
396
396
  return
397
397
 
@@ -413,6 +413,8 @@ def colorize(data: dict, name: str, mapping: dict):
413
413
  c = mapping(s)
414
414
  if c:
415
415
  data[name] = click.style(s, fg=c)
416
+ elif isinstance(mapping, str):
417
+ data[name] = click.style(s, fg=mapping)
416
418
  else:
417
419
  raise Exception(f"Unexpected mapping type: {type(mapping)} {mapping}")
418
420
 
@@ -415,7 +415,6 @@ def _handle_resource(name, res, state, for_deploy: bool, fn_process: typing.Call
415
415
 
416
416
  kop_mode = KOP.MODE.create if for_deploy else KOP.MODE.delete
417
417
  with KOP(state, kind, name, kop_mode) as kop:
418
-
419
418
  conditions = res.get("conditions")
420
419
  if conditions:
421
420
  conditions = deepcopy(conditions)
@@ -13,13 +13,15 @@ See the License for the specific language governing permissions and
13
13
  limitations under the License.
14
14
  """
15
15
 
16
+ from typing import Any, Optional
16
17
 
17
- def process(data: dict, state: dict) -> dict:
18
+
19
+ def process(data: dict, state: dict) -> Any:
18
20
  n = data["n"]
19
21
  return _fibonacci(n)
20
22
 
21
23
 
22
- def _fibonacci(n: int):
24
+ def _fibonacci(n: int) -> int:
23
25
  if n <= 0:
24
26
  raise ValueError("n must be a positive integer.")
25
27
  if n == 1:
@@ -33,9 +35,9 @@ def _fibonacci(n: int):
33
35
  return curr
34
36
 
35
37
 
36
- def destroy(data: dict, state: dict, force: bool) -> dict:
38
+ def destroy(data: dict, state: dict, force: bool) -> Optional[dict]:
37
39
  return None
38
40
 
39
41
 
40
- def eta(action: str, data: dict, state: dict):
42
+ def eta(action: str, data: dict, state: dict) -> str:
41
43
  return "10s"
@@ -316,7 +316,7 @@ def wait_for_res_deleted(
316
316
  time.sleep(sleep_seconds)
317
317
 
318
318
 
319
- # flake8: noqa=E731
319
+ # flake8: noqa: E731
320
320
  def wait_for_res_status(
321
321
  resource_name: str,
322
322
  fn_get: Callable,
@@ -175,6 +175,7 @@ class EzClient:
175
175
  self._init_client(base_url, client)
176
176
  self._lazy_init = None
177
177
 
178
+ self._client_impl.follow_redirects = True
178
179
  self._client_impl.ensure_token()
179
180
  return self._client_impl
180
181
  finally:
@@ -193,9 +194,29 @@ class EzClient:
193
194
  # import json as jsonlib
194
195
  # print("->", self._client().base_url, url, jsonlib.dumps(json, indent=4))
195
196
  try:
196
- resp = self._client().post(url, json=json, content=text, files=files, headers=headers, timeout=timeout)
197
+ resp = self._client().post(url, json=json, content=text, files=files, headers=headers, timeout=timeout, follow_redirects=True)
197
198
  except httpx.HTTPStatusError as e:
198
- _raise_http_error(e)
199
+ # the follow_redirects does not work for 307
200
+ if e.response.status_code in [301, 302, 307]:
201
+ target = e.response.headers.get("Location")
202
+ if target:
203
+ client_base_url = str(self._client().base_url)
204
+ default_is_https = client_base_url.startswith("https://")
205
+ target_is_https = target.startswith("https://")
206
+ if default_is_https and not target_is_https:
207
+ target = target.replace("http://", "https://", 1)
208
+ elif not default_is_https and target_is_https:
209
+ target = target.replace("https://", "http://", 1)
210
+ try:
211
+ resp = self._client().post(
212
+ target, json=json, content=text, files=files, headers=headers, timeout=timeout, follow_redirects=True
213
+ )
214
+ except httpx.HTTPStatusError as e:
215
+ _raise_http_error(e)
216
+ else:
217
+ _raise_http_error(e)
218
+ else:
219
+ _raise_http_error(e)
199
220
  data = _parse_resp(resp)
200
221
  if data and type:
201
222
  try:
@@ -209,7 +230,7 @@ class EzClient:
209
230
  def get(self, url: str, headers: dict = None, raise_on_404: bool = False, type: Optional[Type[BaseModel]] = None):
210
231
  try:
211
232
  # print("->", self._client().base_url, url)
212
- resp = self._client().get(url, headers=headers)
233
+ resp = self._client().get(url, headers=headers, follow_redirects=True)
213
234
  data = _parse_resp(resp)
214
235
  if data and type:
215
236
  try:
@@ -230,7 +251,7 @@ class EzClient:
230
251
 
231
252
  def patch(self, url: str, json: dict = None, text=None, headers: dict = None):
232
253
  try:
233
- resp = self._client().patch(url, json=json, content=text, headers=headers)
254
+ resp = self._client().patch(url, json=json, content=text, headers=headers, follow_redirects=True)
234
255
  return _parse_resp(resp)
235
256
  except httpx.HTTPStatusError as e:
236
257
  _raise_http_error(e)
@@ -238,7 +259,7 @@ class EzClient:
238
259
 
239
260
  def delete(self, url: str, headers: dict = None, raise_on_404: bool = False):
240
261
  try:
241
- resp = self._client().delete(url, headers=headers)
262
+ resp = self._client().delete(url, headers=headers, follow_redirects=True)
242
263
  return _parse_resp(resp)
243
264
  except httpx.HTTPStatusError as e:
244
265
  if _is_404(e):
@@ -251,7 +272,7 @@ class EzClient:
251
272
 
252
273
  def put(self, url: str, json: dict = None, text=None, headers: dict = None):
253
274
  try:
254
- resp = self._client().put(url, json=json, content=text, headers=headers)
275
+ resp = self._client().put(url, json=json, content=text, headers=headers, follow_redirects=True)
255
276
  return _parse_resp(resp)
256
277
  except httpx.HTTPStatusError as e:
257
278
  _raise_http_error(e)
@@ -65,7 +65,6 @@ def run_govc_guest_script(script, args):
65
65
 
66
66
 
67
67
  def waitForVmPowerOff(iPath):
68
-
69
68
  def current_millis():
70
69
  return int(round(time.time() * 1000))
71
70
 
@@ -59,7 +59,6 @@ def to_seconds(duration_string: str) -> int:
59
59
 
60
60
 
61
61
  def to_duration(seconds: int, simple: bool = False) -> str:
62
-
63
62
  future = seconds < 0
64
63
  if future:
65
64
  seconds = -seconds
@@ -173,7 +173,6 @@ def generate_CSR(nodename, sans=[], key_length: int = 2048):
173
173
 
174
174
 
175
175
  def generate_self_signed_cert(common_name: str):
176
-
177
176
  validity_days = 365
178
177
 
179
178
  private_key = rsa.generate_private_key(
@@ -13,7 +13,7 @@ See the License for the specific language governing permissions and
13
13
  limitations under the License.
14
14
  """
15
15
 
16
- from typing import Any, Callable, Iterator, Tuple
16
+ from typing import Any, Callable, Iterator, Optional, Tuple
17
17
  from urllib.parse import urlencode
18
18
 
19
19
 
@@ -38,7 +38,7 @@ def with_query(url: str, **kwargs: Any) -> str:
38
38
 
39
39
 
40
40
  class PageRequest:
41
- def __init__(self, fn_get_page: Callable, fn_filter: Callable = None, **kwargs):
41
+ def __init__(self, fn_get_page: Callable, fn_filter: Optional[Callable] = None, **kwargs):
42
42
  limit = kwargs.get("limit")
43
43
  if limit is None or limit == "":
44
44
  limit = 10
@@ -52,7 +52,7 @@ class PageRequest:
52
52
  self.query["size"] = 20
53
53
 
54
54
  def get_page(self, page: int, size: int) -> list:
55
- content, _ = self.get_page(page, size)
55
+ content, _ = self._get_page(page, size)
56
56
  return content
57
57
 
58
58
  def _get_page(self, page: int, size: int) -> Tuple[list, bool]:
@@ -42,7 +42,7 @@ dependencies = [
42
42
  "websocket_client>=1.2.3",
43
43
  "psutil>=7.0.0",
44
44
  "schedule>=1.1.0",
45
- "yumako>=0.1.36",
45
+ "yumako>=0.1.37",
46
46
  "pydantic>=2.11.7",
47
47
  "python-dotenv>=1.1.1",
48
48
  ]
@@ -50,7 +50,6 @@ dependencies = [
50
50
  [project.optional-dependencies]
51
51
  dev = [
52
52
  "build",
53
- "black",
54
53
  "mypy",
55
54
  "bandit",
56
55
  "wheel",
@@ -60,6 +59,8 @@ dev = [
60
59
  "ruff",
61
60
  "flake8",
62
61
  "hatch",
62
+ "vulture",
63
+ "yamlfix",
63
64
  ]
64
65
 
65
66
  [project.urls]
@@ -79,15 +80,9 @@ exclude = [
79
80
  "tests/**",
80
81
  ]
81
82
 
82
- [tool.black]
83
+ [tool.ruff]
83
84
  line-length = 140
84
- target-version = ['py39']
85
- include = '\.pyi?$'
86
- extend-exclude = '''
87
- # A regex preceded with ^/ will apply only to files and directories
88
- # in the root of the project.
89
- ^/foo.py # exclude a file named foo.py in the root of the project (in addition to the defaults)
90
- '''
85
+ target-version = "py39"
91
86
 
92
87
  [tool.hatch.version]
93
88
  path = "hcs_core/__init__.py"
@@ -1 +0,0 @@
1
- __version__ = "0.1.317"
File without changes