pubtools-pyxis 1.3.5__tar.gz → 1.3.7__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 (44) hide show
  1. {pubtools-pyxis-1.3.5/pubtools_pyxis.egg-info → pubtools_pyxis-1.3.7}/PKG-INFO +31 -3
  2. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/source/CHANGELOG.rst +11 -0
  3. pubtools_pyxis-1.3.7/requirements-test.txt +8 -0
  4. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/requirements.txt +1 -0
  5. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/setup.py +11 -3
  6. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7/src}/pubtools/_pyxis/pyxis_authentication.py +19 -10
  7. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7/src}/pubtools/_pyxis/pyxis_client.py +37 -25
  8. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7/src}/pubtools/_pyxis/pyxis_ops.py +156 -20
  9. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7/src}/pubtools/_pyxis/pyxis_session.py +18 -11
  10. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7/src}/pubtools/_pyxis/utils.py +3 -2
  11. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7/src/pubtools_pyxis.egg-info}/PKG-INFO +31 -3
  12. pubtools_pyxis-1.3.7/src/pubtools_pyxis.egg-info/SOURCES.txt +40 -0
  13. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7/src}/pubtools_pyxis.egg-info/entry_points.txt +7 -0
  14. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7/src}/pubtools_pyxis.egg-info/requires.txt +1 -0
  15. pubtools_pyxis-1.3.7/tests/test_pyxis_authentication.py +124 -0
  16. pubtools_pyxis-1.3.7/tests/test_pyxis_client.py +325 -0
  17. pubtools_pyxis-1.3.7/tests/test_pyxis_ops.py +1012 -0
  18. pubtools_pyxis-1.3.7/tests/test_pyxis_session.py +58 -0
  19. pubtools-pyxis-1.3.5/pubtools/__init__.py +0 -1
  20. pubtools-pyxis-1.3.5/pubtools_pyxis.egg-info/SOURCES.txt +0 -37
  21. pubtools-pyxis-1.3.5/requirements-test.txt +0 -5
  22. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/LICENSE +0 -0
  23. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/MANIFEST.in +0 -0
  24. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/README.rst +0 -0
  25. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/Makefile +0 -0
  26. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/source/README.rst +0 -0
  27. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/source/conf.py +0 -0
  28. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/source/delete_signatures.rst +0 -0
  29. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/source/entrypoints_reference.rst +0 -0
  30. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/source/get_indices.rst +0 -0
  31. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/source/get_repo_metadata.rst +0 -0
  32. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/source/get_signatures.rst +0 -0
  33. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/source/index.rst +0 -0
  34. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/source/modules_reference.rst +0 -0
  35. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/source/ops_helpers.rst +0 -0
  36. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/source/pyxis_authentication.rst +0 -0
  37. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/source/pyxis_client.rst +0 -0
  38. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/source/pyxis_session.rst +0 -0
  39. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/docs/source/upload_signatures.rst +0 -0
  40. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7}/setup.cfg +0 -0
  41. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7/src}/pubtools/_pyxis/__init__.py +0 -0
  42. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7/src}/pubtools/_pyxis/constants.py +0 -0
  43. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7/src}/pubtools_pyxis.egg-info/dependency_links.txt +0 -0
  44. {pubtools-pyxis-1.3.5 → pubtools_pyxis-1.3.7/src}/pubtools_pyxis.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: pubtools-pyxis
3
- Version: 1.3.5
3
+ Version: 1.3.7
4
4
  Summary: Pubtools-pyxis
5
5
  Home-page: https://github.com/release-engineering/pubtools-pyxis
6
6
  Author: Lubomir Gallovic
@@ -15,8 +15,25 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
15
15
  Classifier: Programming Language :: Python :: Implementation :: PyPy
16
16
  Requires-Python: >=3.6
17
17
  Description-Content-Type: text/x-rst
18
- Provides-Extra: reST
19
18
  License-File: LICENSE
19
+ Requires-Dist: setuptools
20
+ Requires-Dist: more-executors>=2.3.0
21
+ Requires-Dist: requests
22
+ Requires-Dist: requests-kerberos
23
+ Requires-Dist: urllib3<2
24
+ Provides-Extra: rest
25
+ Requires-Dist: Sphinx; extra == "rest"
26
+ Dynamic: author
27
+ Dynamic: author-email
28
+ Dynamic: classifier
29
+ Dynamic: description
30
+ Dynamic: description-content-type
31
+ Dynamic: home-page
32
+ Dynamic: license-file
33
+ Dynamic: provides-extra
34
+ Dynamic: requires-dist
35
+ Dynamic: requires-python
36
+ Dynamic: summary
20
37
 
21
38
  ===============
22
39
  pubtools-pyxis
@@ -128,6 +145,17 @@ Get signatures:
128
145
  ChangeLog
129
146
  =========
130
147
 
148
+ 1.3.7 (2025-05-06)
149
+ ------------------
150
+
151
+ * python3.9 compatibility fixes
152
+
153
+ 1.3.6 (2025-03-06)
154
+ ------------------
155
+
156
+ * Splitted entrypoitnts to `console_scripts` and `mod`.
157
+
158
+
131
159
  1.3.5 (2023-03-14)
132
160
  ------------------
133
161
 
@@ -1,6 +1,17 @@
1
1
  ChangeLog
2
2
  =========
3
3
 
4
+ 1.3.7 (2025-05-06)
5
+ ------------------
6
+
7
+ * python3.9 compatibility fixes
8
+
9
+ 1.3.6 (2025-03-06)
10
+ ------------------
11
+
12
+ * Splitted entrypoitnts to `console_scripts` and `mod`.
13
+
14
+
4
15
  1.3.5 (2023-03-14)
5
16
  ------------------
6
17
 
@@ -0,0 +1,8 @@
1
+ mock
2
+ requests-mock
3
+ pytest
4
+ pytest-pylint
5
+ pytest-cov
6
+ bandit==1.7.5
7
+ mypy
8
+ types-requests
@@ -2,3 +2,4 @@ setuptools
2
2
  more-executors>=2.3.0
3
3
  requests
4
4
  requests-kerberos
5
+ urllib3<2
@@ -7,7 +7,7 @@ import sys
7
7
 
8
8
  # import pkg_resources
9
9
  import sys
10
- from setuptools import setup, find_packages
10
+ from setuptools import setup, find_namespace_packages
11
11
  from setuptools.command.test import test as TestCommand
12
12
 
13
13
 
@@ -71,7 +71,7 @@ if os.environ.get("READTHEDOCS", None):
71
71
 
72
72
  setup(
73
73
  name="pubtools-pyxis",
74
- version="1.3.5",
74
+ version="1.3.7",
75
75
  description="Pubtools-pyxis",
76
76
  long_description=long_description,
77
77
  long_description_content_type='text/x-rst',
@@ -80,7 +80,8 @@ setup(
80
80
  url="https://github.com/release-engineering/pubtools-pyxis",
81
81
  classifiers=classifiers,
82
82
  python_requires='>=3.6',
83
- packages=find_packages(exclude=["tests"]),
83
+ packages=find_namespace_packages(where="src"),
84
+ package_dir={"": "src"},
84
85
  data_files=[],
85
86
  install_requires=get_requirements(),
86
87
  dependency_links=DEPENDENCY_LINKS,
@@ -91,6 +92,13 @@ setup(
91
92
  "pubtools-pyxis-upload-signatures = pubtools._pyxis.pyxis_ops:upload_signatures_main",
92
93
  "pubtools-pyxis-get-signatures = pubtools._pyxis.pyxis_ops:get_signatures_main",
93
94
  "pubtools-pyxis-delete-signatures = pubtools._pyxis.pyxis_ops:delete_signatures_main"
95
+ ],
96
+ "mod": [
97
+ "pubtools-pyxis-get-operator-indices = pubtools._pyxis.pyxis_ops:get_operator_indices_mod",
98
+ "pubtools-pyxis-get-repo-metadata = pubtools._pyxis.pyxis_ops:get_repo_metadata_mod",
99
+ "pubtools-pyxis-upload-signatures = pubtools._pyxis.pyxis_ops:upload_signatures_mod",
100
+ "pubtools-pyxis-get-signatures = pubtools._pyxis.pyxis_ops:get_signatures_mod",
101
+ "pubtools-pyxis-delete-signatures = pubtools._pyxis.pyxis_ops:delete_signatures_mod"
94
102
  ]
95
103
  },
96
104
  include_package_data=True,
@@ -1,17 +1,20 @@
1
1
  import os
2
2
  import subprocess
3
+ from typing import Optional
3
4
 
4
5
  from requests_kerberos import HTTPKerberosAuth, OPTIONAL
5
6
 
7
+ from .pyxis_session import PyxisSession
6
8
 
7
- class PyxisAuth(object):
9
+
10
+ class PyxisAuth:
8
11
  """Base Auth class."""
9
12
 
10
- def __init__(self):
13
+ def __init__(self) -> None:
11
14
  """Initialize."""
12
15
  raise NotImplementedError # pragma: no cover"
13
16
 
14
- def apply_to_session(self, pyxis_session):
17
+ def apply_to_session(self, pyxis_session: PyxisSession) -> None:
15
18
  """Set up initialization in the Pyxis session."""
16
19
  raise NotImplementedError # pragma: no cover"
17
20
 
@@ -20,7 +23,7 @@ class PyxisSSLAuth(PyxisAuth):
20
23
  """SSL Auth provider to PyxisClient."""
21
24
 
22
25
  # pylint: disable=super-init-not-called
23
- def __init__(self, crt_path, key_path):
26
+ def __init__(self, crt_path: str, key_path: str) -> None:
24
27
  """
25
28
  Initialize.
26
29
 
@@ -33,7 +36,7 @@ class PyxisSSLAuth(PyxisAuth):
33
36
  self.crt_path = crt_path
34
37
  self.key_path = key_path
35
38
 
36
- def apply_to_session(self, pyxis_session):
39
+ def apply_to_session(self, pyxis_session: PyxisSession) -> None:
37
40
  """
38
41
  Set up PyxisSession with SSL auth.
39
42
 
@@ -47,7 +50,13 @@ class PyxisSSLAuth(PyxisAuth):
47
50
  class PyxisKrbAuth(PyxisAuth):
48
51
  """Kerberos authentication support for PyxisClient."""
49
52
 
50
- def __init__(self, krb_princ, service, ktfile=None, ccache_file=None):
53
+ def __init__(
54
+ self,
55
+ krb_princ: str,
56
+ service: str,
57
+ ccache_file: str,
58
+ ktfile: Optional[str] = None,
59
+ ) -> None:
51
60
  """
52
61
  Initialize.
53
62
 
@@ -56,17 +65,17 @@ class PyxisKrbAuth(PyxisAuth):
56
65
  Kerberos principal for obtaining ticket.
57
66
  service (str)
58
67
  URL of the service to apply the authentication to.
59
- ktfile (str)
60
- Kerberos client keytab file.
61
68
  ccache_file (str)
62
69
  Path to a file used for ccache. Only necessary if kinit will be used.
70
+ ktfile (str)
71
+ Kerberos client keytab file.
63
72
  """
64
73
  self.krb_princ = krb_princ
65
74
  self.service = service
66
75
  self.ktfile = ktfile
67
76
  self.ccache_file = ccache_file
68
77
 
69
- def _krb_auth(self):
78
+ def _krb_auth(self) -> HTTPKerberosAuth:
70
79
  retcode = subprocess.Popen(
71
80
  ["klist", "-s"], stdout=subprocess.PIPE, stderr=subprocess.PIPE
72
81
  ).wait()
@@ -102,7 +111,7 @@ class PyxisKrbAuth(PyxisAuth):
102
111
  force_preemptive=True,
103
112
  )
104
113
 
105
- def apply_to_session(self, pyxis_session):
114
+ def apply_to_session(self, pyxis_session: PyxisSession) -> None:
106
115
  """Set up PyxisSession with Kerberos auth.
107
116
 
108
117
  Args:
@@ -3,27 +3,29 @@ from concurrent.futures import as_completed
3
3
  from functools import partial
4
4
  import math
5
5
  import threading
6
+ from typing import Callable, Any, Optional, Union
6
7
 
7
8
  from more_executors import Executors
8
9
  from requests.exceptions import HTTPError
10
+ from requests import Response
9
11
 
10
12
  from .constants import DEFAULT_REQUEST_THREADS_LIMIT
11
13
  from .pyxis_session import PyxisSession
14
+ from .pyxis_authentication import PyxisAuth
12
15
 
13
16
 
14
- # pylint: disable=bad-option-value,useless-object-inheritance
15
- class PyxisClient(object):
17
+ class PyxisClient:
16
18
  """Pyxis requests wrapper."""
17
19
 
18
20
  def __init__(
19
21
  self,
20
- hostname,
21
- retries=5,
22
- auth=None,
23
- backoff_factor=5,
24
- verify=True,
25
- threads=DEFAULT_REQUEST_THREADS_LIMIT,
26
- ):
22
+ hostname: str,
23
+ retries: int = 5,
24
+ auth: Optional[PyxisAuth] = None,
25
+ backoff_factor: int = 5,
26
+ verify: bool = True,
27
+ threads: int = DEFAULT_REQUEST_THREADS_LIMIT,
28
+ ) -> None:
27
29
  """
28
30
  Initialize.
29
31
 
@@ -53,7 +55,7 @@ class PyxisClient(object):
53
55
  self.threads_limit = threads
54
56
 
55
57
  @property
56
- def pyxis_session(self):
58
+ def pyxis_session(self) -> Union[PyxisSession, Any]:
57
59
  """
58
60
  Return a thread-local session for Pyxis requests.
59
61
 
@@ -64,13 +66,15 @@ class PyxisClient(object):
64
66
  self.thread_local.pyxis_session = self._make_session()
65
67
  return self.thread_local.pyxis_session
66
68
 
67
- def _make_session(self):
69
+ def _make_session(self) -> PyxisSession:
68
70
  session = self._session_factory()
69
71
  if self._auth:
70
72
  self._auth.apply_to_session(session)
71
73
  return session
72
74
 
73
- def get_operator_indices(self, ocp_versions_range, organization=None):
75
+ def get_operator_indices(
76
+ self, ocp_versions_range: str, organization: Optional[str] = None
77
+ ) -> Union[list[str], Any]:
74
78
  """Get a list of index images satisfying versioning and organization conditions.
75
79
 
76
80
  Args:
@@ -91,8 +95,12 @@ class PyxisClient(object):
91
95
  return resp.json()["data"]
92
96
 
93
97
  def get_repository_metadata(
94
- self, repo_name, custom_registry=None, only_internal=False, only_partner=False
95
- ):
98
+ self,
99
+ repo_name: str,
100
+ custom_registry: Optional[str] = None,
101
+ only_internal: bool = False,
102
+ only_partner: bool = False,
103
+ ) -> Union[dict[Any, Any], Any]:
96
104
  """Get metadata of a Comet repository.
97
105
 
98
106
  If checking only one registry hasn't been specified, check both with precedence on
@@ -130,19 +138,19 @@ class PyxisClient(object):
130
138
  resp.raise_for_status()
131
139
  return resp.json()
132
140
 
133
- def upload_signatures(self, signatures):
141
+ def upload_signatures(self, signatures: list[str]) -> list[Any]:
134
142
  """
135
143
  Upload signatures from given JSON string.
136
144
 
137
145
  Args:
138
- signatures (str)
146
+ signatures [str]
139
147
  JSON with signatures to upload. See Pyxis API for details.
140
148
 
141
149
  Returns:
142
150
  list: List of uploaded signatures including auto-populated fields.
143
151
  """
144
152
 
145
- def _send_post_request(data):
153
+ def _send_post_request(data: dict[Any, Any]) -> Response:
146
154
  response = self.pyxis_session.post("signatures", json=data)
147
155
  # SEE CLOUDDST-9698
148
156
  # Pyxis returns 500 error due to a potential sidecar config issue
@@ -156,11 +164,13 @@ class PyxisClient(object):
156
164
 
157
165
  return self._do_parallel_requests(_send_post_request, signatures)
158
166
 
159
- def _clear_session(self):
167
+ def _clear_session(self) -> None:
160
168
  self.thread_local.pyxis_session.close()
161
169
  delattr(self.thread_local, "pyxis_session")
162
170
 
163
- def _do_parallel_requests(self, make_request, data_items):
171
+ def _do_parallel_requests(
172
+ self, make_request: Callable[[Any], Any], data_items: list[Any]
173
+ ) -> Union[list[Any], Any]:
164
174
  """
165
175
  Call given function with given data items in parallel, collect responses.
166
176
 
@@ -189,7 +199,7 @@ class PyxisClient(object):
189
199
 
190
200
  return [f.result() for f in as_completed(futures)]
191
201
 
192
- def _handle_json_response(self, response):
202
+ def _handle_json_response(self, response: Response) -> Union[dict[Any, Any], Any]:
193
203
  """
194
204
  Get JSON from given response or raise an informative exception.
195
205
 
@@ -222,11 +232,13 @@ class PyxisClient(object):
222
232
  extra_msg = data["detail"] if "detail" in data else response.text
223
233
 
224
234
  # re-raise the exception with an extra message
225
- raise HTTPError("{0}\n{1}".format(e, extra_msg))
235
+ raise HTTPError("{0}\n{1}".format(e, extra_msg), response=response)
226
236
 
227
237
  return data
228
238
 
229
- def get_container_signatures(self, manifest_digests=None, references=None):
239
+ def get_container_signatures(
240
+ self, manifest_digests: Optional[str] = None, references: Optional[str] = None
241
+ ) -> list[str]:
230
242
  """Get a list of signature metadata matching given fields.
231
243
 
232
244
  Args:
@@ -254,7 +266,7 @@ class PyxisClient(object):
254
266
 
255
267
  return resp
256
268
 
257
- def _get_items_from_all_pages(self, endpoint, **kwargs):
269
+ def _get_items_from_all_pages(self, endpoint: str, **kwargs: Any) -> list[Any]:
258
270
  """
259
271
  Get response from all pages of pyxis.
260
272
 
@@ -283,7 +295,7 @@ class PyxisClient(object):
283
295
  all_resp.extend(resp.json()["data"])
284
296
  return all_resp
285
297
 
286
- def delete_container_signatures(self, signature_ids):
298
+ def delete_container_signatures(self, signature_ids: list[str]) -> list[Any]:
287
299
  """Delete signatures matching given fields.
288
300
 
289
301
  Args:
@@ -291,7 +303,7 @@ class PyxisClient(object):
291
303
  Internal Pyxis signature IDs of signatures which should be removed.
292
304
  """
293
305
 
294
- def _send_delete_request(signature_id):
306
+ def _send_delete_request(signature_id: str) -> Response:
295
307
  delete_endpoint = "signatures/id/{id}"
296
308
  resp = self.pyxis_session.delete(delete_endpoint.format(id=signature_id))
297
309
  return resp
@@ -1,9 +1,11 @@
1
1
  import json
2
2
  import sys
3
3
  import tempfile
4
+ from argparse import ArgumentParser, Namespace
5
+ from typing import Any, Optional, Union
4
6
 
5
7
  from .constants import DEFAULT_REQUEST_THREADS_LIMIT
6
- from .pyxis_authentication import PyxisKrbAuth, PyxisSSLAuth
8
+ from .pyxis_authentication import PyxisKrbAuth, PyxisSSLAuth, PyxisAuth
7
9
  from .pyxis_client import PyxisClient
8
10
  from .utils import setup_arg_parser
9
11
 
@@ -116,7 +118,7 @@ DELETE_SIGNATURES_ARGS[("--request-threads",)] = {
116
118
  }
117
119
 
118
120
 
119
- def setup_pyxis_client(args, ccache_file):
121
+ def setup_pyxis_client(args: Namespace, ccache_file: str) -> PyxisClient:
120
122
  """
121
123
  Set up a PyxisClient instance according to specified parameters.
122
124
 
@@ -131,11 +133,11 @@ def setup_pyxis_client(args, ccache_file):
131
133
  """
132
134
  # If both auths are specified, Kerberos is preferred
133
135
  if args.pyxis_krb_principal:
134
- auth = PyxisKrbAuth(
136
+ auth: PyxisAuth = PyxisKrbAuth(
135
137
  args.pyxis_krb_principal,
136
138
  args.pyxis_server,
137
- args.pyxis_krb_ktfile,
138
139
  ccache_file,
140
+ args.pyxis_krb_ktfile,
139
141
  )
140
142
  elif args.pyxis_ssl_crtfile and args.pyxis_ssl_keyfile:
141
143
  auth = PyxisSSLAuth(args.pyxis_ssl_crtfile, args.pyxis_ssl_keyfile)
@@ -156,12 +158,12 @@ def setup_pyxis_client(args, ccache_file):
156
158
  return PyxisClient(args.pyxis_server, auth=auth, verify=not args.pyxis_insecure)
157
159
 
158
160
 
159
- def set_get_operator_indices_args():
161
+ def set_get_operator_indices_args() -> ArgumentParser:
160
162
  """Set up argparser without extra parameters, this method is used for auto doc generation."""
161
163
  return setup_arg_parser(GET_OPERATORS_INDICES_ARGS)
162
164
 
163
165
 
164
- def get_operator_indices_main(sysargs=None):
166
+ def _get_operator_indices(sysargs: Optional[list[str]] = None) -> Union[list[str], Any]:
165
167
  """
166
168
  Entrypoint for getting operator indices.
167
169
 
@@ -179,17 +181,45 @@ def get_operator_indices_main(sysargs=None):
179
181
  resp = pyxis_client.get_operator_indices(
180
182
  args.ocp_versions_range, args.organization
181
183
  )
184
+ return resp
182
185
 
186
+
187
+ def get_operator_indices_main(sysargs: Optional[list[str]] = None) -> int:
188
+ """
189
+ Entrypoint for getting operator indices.
190
+
191
+ Returns:
192
+ int: Exit code (0 for success).
193
+ """
194
+ try:
195
+ resp = _get_operator_indices(sysargs)
183
196
  json.dump(resp, sys.stdout, sort_keys=True, indent=4, separators=(",", ": "))
184
- return resp
197
+ return 0
198
+ except Exception as e:
199
+ print(f"Error getting operator indices: {e}", file=sys.stderr)
200
+ return 1
201
+
202
+
203
+ def get_operator_indices_mod(
204
+ sysargs: Optional[list[str]] = None,
205
+ ) -> Union[list[str], Any]:
206
+ """
207
+ Entrypoint for getting operator indices in module mode.
208
+
209
+ This function is used when running the script as a module.
210
+ It does not return an exit code, but rather prints the result directly.
211
+ """
212
+ return _get_operator_indices(sysargs)
185
213
 
186
214
 
187
- def set_get_repo_metadata_args():
215
+ def set_get_repo_metadata_args() -> ArgumentParser:
188
216
  """Set up argparser without extra parameters, this method is used for auto doc generation."""
189
217
  return setup_arg_parser(GET_REPO_METADATA_ARGS)
190
218
 
191
219
 
192
- def get_repo_metadata_main(sysargs=None):
220
+ def _get_repo_metadata(
221
+ sysargs: Optional[list[str]] = None,
222
+ ) -> Union[dict[Any, Any], Any]:
193
223
  """
194
224
  Entrypoint for getting repository metadata.
195
225
 
@@ -216,17 +246,46 @@ def get_repo_metadata_main(sysargs=None):
216
246
  args.only_internal_registry,
217
247
  args.only_partner_registry,
218
248
  )
249
+ return res
250
+
219
251
 
252
+ def get_repo_metadata_main(
253
+ sysargs: Optional[list[str]] = None,
254
+ ) -> Union[dict[Any, Any], Any]:
255
+ """
256
+ Entrypoint for getting repository metadata.
257
+
258
+ Returns:
259
+ int: Exit code (0 for success).
260
+ """
261
+ try:
262
+ res = _get_repo_metadata(sysargs)
220
263
  json.dump(res, sys.stdout, sort_keys=True, indent=4, separators=(",", ": "))
221
- return res
264
+ return 0
265
+ except Exception as e:
266
+ print(f"Error getting repository metadata: {e}", file=sys.stderr)
267
+ return 1
268
+
269
+
270
+ def get_repo_metadata_mod(
271
+ sysargs: Optional[list[str]] = None,
272
+ ) -> Union[dict[Any, Any], Any]:
273
+ """
274
+ Entrypoint for getting repository metadata in module mode.
275
+
276
+ This function is used when running the script as a module.
277
+ It does not return an exit code, but rather prints the result directly.
278
+ """
279
+ return _get_repo_metadata(sysargs)
280
+ # No return value, output is printed directly
222
281
 
223
282
 
224
- def set_upload_signatures_args():
283
+ def set_upload_signatures_args() -> ArgumentParser:
225
284
  """Set up argparser without extra parameters, this method is used for auto doc generation."""
226
285
  return setup_arg_parser(UPLOAD_SIGNATURES_ARGS)
227
286
 
228
287
 
229
- def upload_signatures_main(sysargs=None):
288
+ def _upload_signatures(sysargs: Optional[list[str]] = None) -> list[Any]:
230
289
  """
231
290
  Entrypoint for uploading signatures from JSON or a file.
232
291
 
@@ -244,13 +303,39 @@ def upload_signatures_main(sysargs=None):
244
303
  with tempfile.NamedTemporaryFile() as tmpfile:
245
304
  pyxis_client = setup_pyxis_client(args, tmpfile.name)
246
305
  resp = pyxis_client.upload_signatures(signatures_json)
306
+ return resp
307
+
308
+
309
+ def upload_signatures_main(sysargs: Optional[list[str]] = None) -> int:
310
+ """
311
+ Entrypoint for uploading signatures from JSON or a file.
247
312
 
313
+ Returns:
314
+ int: Exit code (0 for success).
315
+ """
316
+ try:
317
+ resp = _upload_signatures(sysargs)
248
318
  json.dump(resp, sys.stdout, sort_keys=True, indent=4, separators=(",", ": "))
319
+ return 0
320
+ except Exception as e:
321
+ print(f"Error uploading signatures: {e}", file=sys.stderr)
322
+ return 1
249
323
 
250
- return resp
324
+
325
+ def upload_signatures_mod(sysargs: Optional[list[str]] = None) -> list[Any]:
326
+ """
327
+ Entrypoint for uploading signatures from JSON or a file in module mode.
328
+
329
+ This function is used when running the script as a module.
330
+ It does not return an exit code, but rather prints the result directly.
331
+ """
332
+ return _upload_signatures(sysargs)
333
+ # No return value, output is printed directly
251
334
 
252
335
 
253
- def deserialize_list_from_arg(value, csv_input=False):
336
+ def deserialize_list_from_arg(
337
+ value: str, csv_input: bool = False
338
+ ) -> Union[list[Any], Any]:
254
339
  """
255
340
  Conditionally load contents of a file if specified in argument value.
256
341
 
@@ -275,17 +360,17 @@ def deserialize_list_from_arg(value, csv_input=False):
275
360
  return json.load(f)
276
361
 
277
362
 
278
- def serialize_to_csv_from_list(list_value):
363
+ def serialize_to_csv_from_list(list_value: list[Any]) -> str:
279
364
  """Convert a list to comma separated string."""
280
365
  return ",".join(list_value)
281
366
 
282
367
 
283
- def set_get_signatures_args():
368
+ def set_get_signatures_args() -> ArgumentParser:
284
369
  """Set up argparser without extra parameters, this method is used for auto doc generation."""
285
370
  return setup_arg_parser(GET_SIGNATURES_ARGS)
286
371
 
287
372
 
288
- def get_signatures_main(sysargs=None):
373
+ def _get_signatures(sysargs: Optional[list[str]] = None) -> list[str]:
289
374
  """
290
375
  Entrypoint for getting container signature metadata.
291
376
 
@@ -315,17 +400,42 @@ def get_signatures_main(sysargs=None):
315
400
  res = pyxis_client.get_container_signatures(
316
401
  csv_manifest_digests, csv_references
317
402
  )
403
+ return res
318
404
 
405
+
406
+ def get_signatures_main(sysargs: Optional[list[str]] = None) -> int:
407
+ """
408
+ Entrypoint for getting container signature metadata.
409
+
410
+ Returns:
411
+ int: Exit code (0 for success).
412
+ """
413
+ try:
414
+ res = _get_signatures(sysargs)
319
415
  json.dump(res, sys.stdout, sort_keys=True, indent=4, separators=(",", ": "))
320
- return res
416
+ return 0
417
+ except Exception as e:
418
+ print(f"Error getting signatures: {e}", file=sys.stderr)
419
+ return 1
420
+
421
+
422
+ def get_signatures_mod(sysargs: Optional[list[str]] = None) -> list[str]:
423
+ """
424
+ Entrypoint for getting container signature metadata in module mode.
425
+
426
+ This function is used when running the script as a module.
427
+ It does not return an exit code, but rather prints the result directly.
428
+ """
429
+ return _get_signatures(sysargs)
430
+ # No return value, output is printed directly
321
431
 
322
432
 
323
- def set_delete_signatures_args():
433
+ def set_delete_signatures_args() -> ArgumentParser:
324
434
  """Set up argparser without extra parameters, this method is used for auto doc generation."""
325
435
  return setup_arg_parser(DELETE_SIGNATURES_ARGS)
326
436
 
327
437
 
328
- def delete_signatures_main(sysargs=None):
438
+ def _delete_signatures(sysargs: Optional[list[str]] = None) -> None:
329
439
  """
330
440
  Entrypoint for removing existing signatures.
331
441
 
@@ -344,3 +454,29 @@ def delete_signatures_main(sysargs=None):
344
454
  with tempfile.NamedTemporaryFile() as tmpfile:
345
455
  pyxis_client = setup_pyxis_client(args, tmpfile.name)
346
456
  pyxis_client.delete_container_signatures(signature_ids)
457
+
458
+
459
+ def delete_signatures_main(sysargs: Optional[list[str]] = None) -> int:
460
+ """
461
+ Entrypoint for removing existing signatures.
462
+
463
+ Returns:
464
+ int: Exit code (0 for success).
465
+ """
466
+ try:
467
+ _delete_signatures(sysargs)
468
+ return 0
469
+ except Exception as e:
470
+ print(f"Error deleting signatures: {e}", file=sys.stderr)
471
+ return 1
472
+
473
+
474
+ def delete_signatures_mod(sysargs: Optional[list[str]] = None) -> None:
475
+ """
476
+ Entrypoint for removing existing signatures in module mode.
477
+
478
+ This function is used when running the script as a module.
479
+ It does not return an exit code, but rather prints the result directly.
480
+ """
481
+ return _delete_signatures(sysargs)
482
+ # No return value, output is printed directly