agilicus 1.305.0__py3-none-any.whl → 1.306.0__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.
agilicus/__init__.py CHANGED
@@ -15,13 +15,19 @@ from .version import __version__ # noqa
15
15
  sys.path.append(os.path.dirname(__file__)) # noqa
16
16
 
17
17
  from .agilicus_api import * # noqa
18
+ from .agilicus_api.api_client import Endpoint
18
19
  from .agilicus_api import exceptions # noqa
19
20
  from . import patches # noqa
20
- from .pagination.pagination import get_many_entries
21
+ from pagination.pagination import get_many_entries
22
+
23
+ import agilicus_api.api_client
24
+
25
+ endpoint_class = agilicus_api.api_client.Endpoint
21
26
 
22
27
  from .create import create_or_update, add_list_resources, AddInfo, AddResult, find_guid
23
28
 
24
29
  ApiClient = patches.patched_api_client()
30
+ patches.patch_endpoint_class(endpoint_class)
25
31
 
26
32
 
27
33
  @dataclasses.dataclass
@@ -77,7 +77,7 @@ class ApiClient(object):
77
77
  self.default_headers[header_name] = header_value
78
78
  self.cookie = cookie
79
79
  # Set default User-Agent.
80
- self.user_agent = 'OpenAPI-Generator/1.305.0/python'
80
+ self.user_agent = 'OpenAPI-Generator/1.306.0/python'
81
81
 
82
82
  def __enter__(self):
83
83
  return self
@@ -387,7 +387,7 @@ class Configuration(object):
387
387
  "OS: {env}\n"\
388
388
  "Python Version: {pyversion}\n"\
389
389
  "Version of the API: 2025.10.29\n"\
390
- "SDK Package Version: 1.305.0".\
390
+ "SDK Package Version: 1.306.0".\
391
391
  format(env=sys.platform, pyversion=sys.version)
392
392
 
393
393
  def get_host_settings(self):
@@ -4,7 +4,7 @@ Agilicus is API-first. Modern software is controlled by other software, is open,
4
4
  The `agilicus_api` package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
5
5
 
6
6
  - API version: 2025.10.29
7
- - Package version: 1.305.0
7
+ - Package version: 1.306.0
8
8
  - Build package: org.openapitools.codegen.languages.PythonClientCodegen
9
9
  For more information, please visit [https://www.agilicus.com/api](https://www.agilicus.com/api)
10
10
 
agilicus/main.py CHANGED
@@ -6199,7 +6199,8 @@ def bulk_delete_resource_permission(ctx, **kwargs):
6199
6199
  type=resources.resource_type_enum,
6200
6200
  )
6201
6201
  @click.option("--page-at-id", default=None)
6202
- @click.option("--limit", default=500)
6202
+ @click.option("--limit", default=None, type=int)
6203
+ @click.option("--get-all", default=False, is_flag=True)
6203
6204
  @click.option("--show-columns", type=str, default=None)
6204
6205
  @click.option("--reset-columns", is_flag=True, default=False)
6205
6206
  @click.option("--show-stats", is_flag=True, default=None)
@@ -8471,7 +8472,8 @@ def get_connector_stats_config(ctx, **kwargs):
8471
8472
  @click.option("--name-slug", default=None)
8472
8473
  @click.option("--updated-since", default=None, type=click.DateTime())
8473
8474
  @click.option("--resource-id", default=None)
8474
- @click.option("--limit", default=500)
8475
+ @click.option("--limit", type=int, default=None)
8476
+ @click.option("--get-all", is_flag=True, default=False)
8475
8477
  @click.option(
8476
8478
  "--page-on", multiple=True, type=click.Choice(ssh.page_fields), default=None
8477
8479
  )
@@ -0,0 +1,173 @@
1
+ """
2
+ AutoIterator for paginating API client list functions.
3
+ """
4
+
5
+ import json
6
+ from agilicus_api.exceptions import ApiException
7
+
8
+ _page_on_preference = ["name", "created", "id"]
9
+ _default_page_on = "id"
10
+
11
+
12
+ def get_page_on(list_function):
13
+ """
14
+ tries to figure out the pagination key to use based on the endpoint:
15
+ - If it's an enum, uses the preferred one in the list, otherwise the first
16
+ - If it's not an enum, just tries the 'default', which is id.
17
+ """
18
+ # yes, the key here is a tuple or some reason
19
+ result = list(list_function.allowed_values.get(("page_on",), {}).values())
20
+ if not result and "page_on" in list_function.params_map["all"]:
21
+ return [_default_page_on]
22
+ return result
23
+
24
+
25
+ def _determine_page_on(list_function):
26
+ page_on_list = get_page_on(list_function)
27
+ if not page_on_list:
28
+ raise NotImplementedError("pagination not implemented on this endpoint")
29
+ for page_on in _page_on_preference:
30
+ if page_on in page_on_list:
31
+ return [page_on]
32
+
33
+ return [page_on_list[0]]
34
+
35
+
36
+ def patch_endpoint(list_function):
37
+ setattr(list_function, "auto_paging_iter", AutoIteratorWrapper(list_function))
38
+
39
+
40
+ class AutoIteratorWrapper:
41
+ def __init__(self, list_function):
42
+ self.list_function = list_function
43
+
44
+ def __call__(self, *args, limit=None, page_size=100, page_sort=None, **kwargs):
45
+ return AutoIterator(
46
+ self.list_function, limit, page_size, page_sort, *args, **kwargs
47
+ )
48
+
49
+
50
+ class AutoIterator:
51
+ def __init__(
52
+ self, list_function, limit, page_size, page_sort, *args, page_on=None, **kwargs
53
+ ):
54
+ """
55
+ Initializes the AutoIterator.
56
+
57
+ :param list_function: The API client list function to paginate.
58
+ :param args: Positional arguments to pass to the list_function.
59
+ :param kwargs: Keyword arguments to pass to the list_function.
60
+ """
61
+ self._list_function = list_function
62
+ self._args = args
63
+ self._kwargs = kwargs
64
+ self.page_sort = page_sort or []
65
+ self.limit = limit
66
+ self.page_size = page_size
67
+ self.configured_page_on = page_on or _determine_page_on(self._list_function)
68
+ self._reset()
69
+
70
+ def _reset(self):
71
+ self._total_items = 0
72
+ self._page_on = self.configured_page_on
73
+ self._next_page = []
74
+ self._has_more = True
75
+ self._current_page_items = []
76
+
77
+ def __iter__(self):
78
+ """
79
+ Returns the iterator object itself.
80
+ """
81
+ return self
82
+
83
+ def __next__(self):
84
+ """
85
+ Fetches the next item from the paginated results.
86
+ """
87
+ if not self._current_page_items and self._has_more:
88
+ self._fetch_next_page()
89
+
90
+ if self._current_page_items:
91
+ return self._current_page_items.pop(0)
92
+ else:
93
+ raise StopIteration
94
+
95
+ def _get_page_list(self, response):
96
+ for key in response.attribute_map:
97
+ if isinstance(response.get(key), list):
98
+ return response.get(key)
99
+ return []
100
+
101
+ def _fetch_next_page(self):
102
+ limit = self.page_size
103
+ if self.limit is not None:
104
+ limit = min(limit, self.limit - self._total_items)
105
+
106
+ try:
107
+ response = self._list_function(
108
+ page_on=self._page_on,
109
+ page_at_key=self._next_page,
110
+ limit=limit,
111
+ page_sort=self.page_sort,
112
+ **self._kwargs,
113
+ )
114
+ except ApiException as exc:
115
+ if exc.status != 400:
116
+ raise
117
+
118
+ _handle_page_failure(exc.body)
119
+ # Shut up the linter, which thinks the above doesn't always throw even
120
+ # though it does
121
+ assert False
122
+
123
+ self._current_page_items = self._get_page_list(response)
124
+ self._total_items = self._total_items + len(self._current_page_items)
125
+ page_info = response.page_info
126
+ if (
127
+ not page_info
128
+ or not self._current_page_items
129
+ or (self.limit and self._total_items >= self.limit)
130
+ ):
131
+ self._has_more = False
132
+ return
133
+
134
+ self._next_page = page_info.page_at_key
135
+ self._page_on = page_info.page_on.value
136
+
137
+ # Additional functionality when interacted with as an object
138
+ def all(self):
139
+ """
140
+ Returns all items by iterating through all pages.
141
+ """
142
+ all_items = []
143
+ for item in self:
144
+ all_items.append(item)
145
+ return all_items
146
+
147
+ def first(self):
148
+ """
149
+ Returns the first item, or None if no items.
150
+ """
151
+ self._reset()
152
+ try:
153
+ return next(self)
154
+ except StopIteration:
155
+ return None
156
+
157
+ def __repr__(self):
158
+ return f"<AutoIterator for {self._list_function.__name__}>"
159
+
160
+
161
+ def _handle_page_failure(body):
162
+ if not body:
163
+ raise
164
+ result = {}
165
+ try:
166
+ result = json.loads(body)
167
+ except Exception:
168
+ pass
169
+ error_message = result.get("error_message", "")
170
+ if "pagination key" not in error_message:
171
+ raise
172
+
173
+ raise NotImplementedError("Pagination not implemented on this key") from None
@@ -2,4 +2,7 @@ def normalize_page_args(kwargs):
2
2
  page_sort = kwargs.get("page_sort")
3
3
  if isinstance(page_sort, tuple):
4
4
  kwargs["page_sort"] = list(page_sort)
5
+ page_on = kwargs.get("page_on")
6
+ if isinstance(page_on, tuple):
7
+ kwargs["page_on"] = list(page_on)
5
8
  return kwargs
agilicus/patches.py CHANGED
@@ -5,6 +5,8 @@ import certifi
5
5
  from .agilicus_api.api_client import ApiClient
6
6
  from .agilicus_api.configuration import Configuration
7
7
 
8
+ from agilicus.pagination.auto_iterator import get_page_on, patch_endpoint
9
+
8
10
 
9
11
  class _ApiClientWrapper(ApiClient):
10
12
  def __init__(self, configuration: Configuration = None, **kwargs):
@@ -43,3 +45,18 @@ def patched_api_client():
43
45
  class _Response:
44
46
  def __init__(self, data):
45
47
  self.data = data
48
+
49
+
50
+ def patch_endpoint_class(endpoint_class):
51
+ """
52
+ patches the Endpoint class to inject the AutoIterator into itself if needed.
53
+ """
54
+ original_init = endpoint_class.__init__
55
+
56
+ def init_wrapper(self, *args, **kwargs):
57
+ original_init(self, *args, **kwargs)
58
+ if not get_page_on(self):
59
+ return
60
+ patch_endpoint(self)
61
+
62
+ endpoint_class.__init__ = init_wrapper
agilicus/resources.py CHANGED
@@ -113,7 +113,7 @@ def bulk_delete_permission(ctx, **kwargs):
113
113
  )
114
114
 
115
115
 
116
- def query_resources(ctx, org_id=None, **kwargs):
116
+ def query_resources(ctx, org_id=None, get_all=False, limit=None, **kwargs):
117
117
  org_id = get_org_from_input_or_ctx(ctx, org_id=org_id)
118
118
  token = context.get_token(ctx)
119
119
  apiclient = context.get_apiclient(ctx, token)
@@ -121,10 +121,13 @@ def query_resources(ctx, org_id=None, **kwargs):
121
121
  params = {}
122
122
  update_if_not_none(params, kwargs)
123
123
  params = normalize_page_args(params)
124
- query_results = apiclient.resources_api.list_resources(**params)
125
- if query_results:
126
- return query_results.resources
127
- return []
124
+ if not get_all:
125
+ if limit is None:
126
+ limit = 500
127
+ return apiclient.resources_api.list_resources(limit=limit, **params).resources
128
+ return apiclient.resources_api.list_resources.auto_paging_iter(
129
+ limit=limit, **params
130
+ ).all()
128
131
 
129
132
 
130
133
  def format_resources(ctx, resources, show_columns=None, reset_columns=None):
agilicus/ssh.py CHANGED
@@ -21,13 +21,23 @@ from .resource_helpers import map_resource_published, standard_page_fields
21
21
  page_fields = standard_page_fields
22
22
 
23
23
 
24
- def list_ssh_resources(ctx, **kwargs):
24
+ def list_ssh_resources(ctx, get_all=False, limit=None, **kwargs):
25
25
  apiclient = context.get_apiclient_from_ctx(ctx)
26
26
  update_org_from_input_or_ctx(kwargs, ctx, **kwargs)
27
27
  params = strip_none(kwargs)
28
28
  params = normalize_page_args(params)
29
- query_results = apiclient.app_services_api.list_ssh_resources(**params)
30
- return query_results.ssh_resources
29
+ if not get_all:
30
+ if limit is None:
31
+ limit = 500
32
+ return apiclient.app_services_api.list_ssh_resources(
33
+ limit=limit, **params
34
+ ).ssh_resources
35
+ return [
36
+ x
37
+ for x in apiclient.app_services_api.list_ssh_resources.auto_paging_iter(
38
+ limit=limit, **params
39
+ )
40
+ ]
31
41
 
32
42
 
33
43
  def add_ssh_resource(ctx, port, **kwargs):
@@ -0,0 +1,340 @@
1
+ import pytest
2
+ from unittest.mock import Mock
3
+ from agilicus.pagination.auto_iterator import (
4
+ AutoIterator,
5
+ AutoIteratorWrapper,
6
+ get_page_on,
7
+ _determine_page_on,
8
+ patch_endpoint,
9
+ _handle_page_failure,
10
+ )
11
+ from agilicus_api.exceptions import ApiException
12
+ from agilicus import ListSSHResourcesResponse
13
+ from agilicus_api.api_client import Endpoint
14
+
15
+
16
+ class MockPageInfo:
17
+ def __init__(self, page_at_key, page_on_value):
18
+ self.page_at_key = page_at_key
19
+ self.page_on = Mock(value=page_on_value)
20
+
21
+
22
+ class MockResponse:
23
+ def __init__(self, items, page_at_key=None, page_on_value=None):
24
+ self.items = items
25
+ self.attribute_map = {"items": "list[object]"}
26
+ self.page_info = (
27
+ MockPageInfo(page_at_key, page_on_value)
28
+ if page_at_key and page_on_value
29
+ else None
30
+ )
31
+
32
+ def get(self, key):
33
+ if key == "items":
34
+ return self.items
35
+ return None
36
+
37
+
38
+ class MockItem:
39
+ def __init__(self, name, index):
40
+ self.name = name
41
+ self.id = index
42
+
43
+
44
+ class MockListFunction:
45
+ def __init__(self, items_per_page, total_items, page_on_allowed=None):
46
+ self._all_items = [MockItem(f"item_{i}", i) for i in range(total_items)]
47
+ self._items_per_page = items_per_page
48
+ self.call_count = 0
49
+ self.allowed_values = {}
50
+ self.params_map = {"all": []}
51
+ if page_on_allowed is None:
52
+ page_on_allowed = ["id"]
53
+ if page_on_allowed:
54
+ self.allowed_values = {("page_on",): {k: k for k in page_on_allowed}}
55
+ self.params_map["all"].append("page_on")
56
+
57
+ def __call__(
58
+ self, page_on=None, page_at_key=None, limit=None, page_sort=None, **kwargs
59
+ ):
60
+ self.call_count += 1
61
+ start_index = 0
62
+ if page_at_key and page_at_key[0] is not None:
63
+ try:
64
+ start_index = len(self._all_items)
65
+ for idx, item in enumerate(self._all_items):
66
+ compare_tuple = [getattr(item, key) for key in page_on]
67
+ if page_at_key < compare_tuple:
68
+ start_index = idx
69
+ break
70
+ except ValueError:
71
+ start_index = len(self._all_items)
72
+
73
+ end_index = min(start_index + limit, len(self._all_items))
74
+ current_items = self._all_items[start_index:end_index]
75
+
76
+ next_page_at_key = None
77
+ if end_index < len(self._all_items):
78
+ next_page_at_key = [self._all_items[end_index - 1].id]
79
+
80
+ return MockResponse(
81
+ current_items,
82
+ page_at_key=next_page_at_key,
83
+ page_on_value=page_on if page_on else None,
84
+ )
85
+
86
+
87
+ def test_auto_iterator_basic_pagination():
88
+ mock_list_function = MockListFunction(items_per_page=2, total_items=5)
89
+ iterator = AutoIterator(mock_list_function, limit=None, page_size=2, page_sort=[])
90
+
91
+ items = list(iterator)
92
+ assert len(items) == 5
93
+ assert mock_list_function.call_count == 3 # 5 items, 2 per page = 3 calls (2,2,1)
94
+ assert [item.name for item in items] == [
95
+ "item_0",
96
+ "item_1",
97
+ "item_2",
98
+ "item_3",
99
+ "item_4",
100
+ ]
101
+
102
+
103
+ def test_auto_iterator_with_limit():
104
+ mock_list_function = MockListFunction(items_per_page=2, total_items=5)
105
+ iterator = AutoIterator(mock_list_function, limit=3, page_size=2, page_sort=[])
106
+
107
+ items = list(iterator)
108
+ assert len(items) == 3
109
+ assert mock_list_function.call_count == 2 # 3 items, 2 per page = 2 calls (2,1)
110
+ assert [item.name for item in items] == ["item_0", "item_1", "item_2"]
111
+
112
+
113
+ def test_auto_iterator_empty_result():
114
+ mock_list_function = MockListFunction(items_per_page=2, total_items=0)
115
+ iterator = AutoIterator(mock_list_function, limit=None, page_size=2, page_sort=[])
116
+
117
+ items = list(iterator)
118
+ assert len(items) == 0
119
+ assert mock_list_function.call_count == 1
120
+
121
+
122
+ def test_auto_iterator_first_method():
123
+ mock_list_function = MockListFunction(items_per_page=2, total_items=5)
124
+ iterator = AutoIterator(mock_list_function, limit=None, page_size=2, page_sort=[])
125
+
126
+ first_item = iterator.first()
127
+ assert first_item.name == "item_0"
128
+ assert mock_list_function.call_count == 1
129
+
130
+ # Calling first again should re-initialize and get the first item again
131
+ first_item = iterator.first()
132
+ assert first_item.name == "item_0"
133
+ assert mock_list_function.call_count == 2
134
+
135
+
136
+ def test_auto_iterator_first_method_empty():
137
+ mock_list_function = MockListFunction(items_per_page=2, total_items=0)
138
+ iterator = AutoIterator(mock_list_function, limit=None, page_size=2, page_sort=[])
139
+
140
+ first_item = iterator.first()
141
+ assert first_item is None
142
+ assert mock_list_function.call_count == 1
143
+
144
+
145
+ def test_auto_iterator_all_method():
146
+ mock_list_function = MockListFunction(items_per_page=2, total_items=5)
147
+ iterator = AutoIterator(mock_list_function, limit=None, page_size=2, page_sort=[])
148
+
149
+ all_items = iterator.all()
150
+ assert len(all_items) == 5
151
+ assert mock_list_function.call_count == 3
152
+ assert [item.name for item in all_items] == [
153
+ "item_0",
154
+ "item_1",
155
+ "item_2",
156
+ "item_3",
157
+ "item_4",
158
+ ]
159
+
160
+
161
+ def test_auto_iterator_all_method_empty():
162
+ mock_list_function = MockListFunction(items_per_page=2, total_items=0)
163
+ iterator = AutoIterator(mock_list_function, limit=None, page_size=2, page_sort=[])
164
+
165
+ all_items = iterator.all()
166
+ assert len(all_items) == 0
167
+ assert mock_list_function.call_count == 1
168
+
169
+
170
+ def test_auto_iterator_wrapper():
171
+ mock_list_function = MockListFunction(items_per_page=2, total_items=5)
172
+ wrapper = AutoIteratorWrapper(mock_list_function)
173
+ iterator = wrapper(limit=3, page_size=2, page_sort=["name"])
174
+
175
+ assert isinstance(iterator, AutoIterator)
176
+ assert iterator.limit == 3
177
+ assert iterator.page_size == 2
178
+ assert iterator.page_sort == ["name"]
179
+
180
+
181
+ def test_get_page_on_with_allowed_values():
182
+ mock_list_function = Mock()
183
+ mock_list_function.allowed_values = {("page_on",): {"id": "id", "name": "name"}}
184
+ mock_list_function.params_map = {"all": ["page_on"]}
185
+ assert get_page_on(mock_list_function) == ["id", "name"]
186
+
187
+
188
+ def test_get_page_on_without_allowed_values_but_in_params_map():
189
+ mock_list_function = Mock()
190
+ mock_list_function.allowed_values = {}
191
+ mock_list_function.params_map = {"all": ["page_on"]}
192
+ assert get_page_on(mock_list_function) == ["id"]
193
+
194
+
195
+ def test_get_page_on_not_in_params_map():
196
+ mock_list_function = Mock()
197
+ mock_list_function.allowed_values = {}
198
+ mock_list_function.params_map = {"all": []}
199
+ assert get_page_on(mock_list_function) == []
200
+
201
+
202
+ def test_determine_page_on_preference():
203
+ mock_list_function = Mock()
204
+ mock_list_function.allowed_values = {
205
+ ("page_on",): {"created": "created", "id": "id"}
206
+ }
207
+ mock_list_function.params_map = {"all": ["page_on"]}
208
+ assert _determine_page_on(mock_list_function) == ["created"]
209
+
210
+
211
+ def test_determine_page_on_default():
212
+ mock_list_function = Mock()
213
+ mock_list_function.allowed_values = {("page_on",): {"foo": "foo"}}
214
+ mock_list_function.params_map = {"all": ["page_on"]}
215
+ assert _determine_page_on(mock_list_function) == ["foo"]
216
+
217
+
218
+ def test_determine_page_on_not_implemented():
219
+ mock_list_function = Mock()
220
+ mock_list_function.allowed_values = {}
221
+ mock_list_function.params_map = {"all": []}
222
+ with pytest.raises(NotImplementedError):
223
+ _determine_page_on(mock_list_function)
224
+
225
+
226
+ def test_patch_endpoint():
227
+ mock_list_function = Mock()
228
+ patch_endpoint(mock_list_function)
229
+ assert hasattr(mock_list_function, "auto_paging_iter")
230
+ assert isinstance(mock_list_function.auto_paging_iter, AutoIteratorWrapper)
231
+
232
+
233
+ def test_handle_page_failure_pagination_key_error():
234
+ exc = ApiException(status=400, reason="Bad Request", http_resp=Mock())
235
+ exc.body = '{"error_message": "Invalid pagination key"}'
236
+ with pytest.raises(
237
+ NotImplementedError, match="Pagination not implemented on this key"
238
+ ):
239
+ _handle_page_failure(exc.body)
240
+
241
+
242
+ def test_handle_page_failure_other_400_error():
243
+ exc = ApiException(status=400, reason="Bad Request", http_resp=Mock())
244
+ exc.body = '{"error_message": "Some other error"}'
245
+ with pytest.raises(ApiException):
246
+ try:
247
+ raise exc
248
+ except Exception as exc:
249
+ _handle_page_failure(exc.body)
250
+
251
+
252
+ def test_handle_page_failure_no_body():
253
+ exc = ApiException(status=400, reason="Bad Request", http_resp=Mock())
254
+ exc.body = None
255
+ with pytest.raises(ApiException):
256
+ try:
257
+ raise exc
258
+ except Exception as exc:
259
+ _handle_page_failure(exc.body)
260
+
261
+
262
+ def test_handle_page_failure_invalid_json():
263
+ exc = ApiException(status=400, reason="Bad Request", http_resp=Mock())
264
+ exc.body = "invalid json"
265
+ with pytest.raises(ApiException):
266
+ try:
267
+ raise exc
268
+ except Exception as exc:
269
+ _handle_page_failure(exc.body)
270
+
271
+
272
+ def test_auto_iterator_api_exception_other_status():
273
+ mock_list_function = Mock()
274
+ mock_list_function.allowed_values = {("page_on",): {"foo": "foo"}}
275
+ mock_list_function.params_map = {"all": ["page_on"]}
276
+ mock_list_function.side_effect = ApiException(
277
+ status=500, reason="Internal Server Error"
278
+ )
279
+ iterator = AutoIterator(mock_list_function, limit=None, page_size=2, page_sort=[])
280
+
281
+ with pytest.raises(ApiException):
282
+ list(iterator)
283
+
284
+
285
+ def test_auto_iterator_repr():
286
+ mock_list_function = Mock(
287
+ __name__="mock_list_function",
288
+ allowed_values={("page_on",): {"id": "id"}},
289
+ params_map={"all": ["page_on"]},
290
+ )
291
+ iterator = AutoIterator(mock_list_function, limit=None, page_size=2, page_sort=[])
292
+ assert repr(iterator) == "<AutoIterator for mock_list_function>"
293
+
294
+
295
+ def test_auto_patch_endpoint():
296
+ mock_list_function = MockListFunction(items_per_page=2, total_items=5)
297
+
298
+ def wrap_list(*args, **kwargs):
299
+ return mock_list_function(**kwargs)
300
+
301
+ foo = Endpoint(
302
+ settings={
303
+ "response_type": (ListSSHResourcesResponse,),
304
+ "auth": ["token-valid"],
305
+ "endpoint_path": "/v1/ssh_resources",
306
+ "operation_id": "list_ssh_resources",
307
+ "http_method": "GET",
308
+ "servers": None,
309
+ },
310
+ params_map={
311
+ "all": [
312
+ "page_on",
313
+ "page_at_key",
314
+ "page_sort",
315
+ "search_direction",
316
+ ],
317
+ "required": [],
318
+ "nullable": [],
319
+ "enum": [
320
+ "page_sort",
321
+ "search_direction",
322
+ ],
323
+ "validation": [
324
+ "name",
325
+ "limit",
326
+ ],
327
+ },
328
+ root_map={
329
+ "validations": [],
330
+ "allowed_values": {("page_on,"): ["name"]},
331
+ "openapi_types": {},
332
+ "attribute_map": {},
333
+ "location_map": {},
334
+ "collection_format_map": {},
335
+ },
336
+ callable=wrap_list,
337
+ )
338
+
339
+ assert foo.auto_paging_iter is not None
340
+ assert next(foo.auto_paging_iter()).name == "item_0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: agilicus
3
- Version: 1.305.0
3
+ Version: 1.306.0
4
4
  Summary: Agilicus SDK
5
5
  License: MIT
6
6
  Author: Agilicus Devs
@@ -2,7 +2,7 @@ agilicus/.gitignore,sha256=TyHq6BCuVrFiqgUb1QAayLxWcBseKwEOoKJTQb_-iW8,5
2
2
  agilicus/.openapi-generator/FILES,sha256=DXwz0MJeKwW9W6-L-Mfel3mqKF_B0kJid1W73EM8X7o,129275
3
3
  agilicus/.openapi-generator/VERSION,sha256=LXsIFraL1muXBEww1sZWaewc9ji87Ih3gIa04Z37RYM,14
4
4
  agilicus/.openapi-generator-ignore,sha256=pu2PTide7pJtJ-DFLzDy0cTYQJRlrB-8RRH3zGLeUds,1040
5
- agilicus/__init__.py,sha256=wKcHA5i7adxUCWhmNwq5bn10OXInnp7vJvbK8UVpKt4,4137
5
+ agilicus/__init__.py,sha256=130H3LJRZOJa3OR8KdoowHj4qnKRGg6ainocRnwCE20,4310
6
6
  agilicus/access.py,sha256=UEHHhE3cCaCjxXQDjhKxQAoUEMWandygN0d-yEIIf8A,5457
7
7
  agilicus/admin.py,sha256=rPXaddSiGpq3MBMQyFagy2RAHPhZkKN8ZGkMuN-MZqg,9991
8
8
  agilicus/agilicus_api/__init__.py,sha256=RmgWcMhdjLQZTgjB6a8Joy1kwQRQhklwWpf3XuK7jZg,73056
@@ -73,9 +73,9 @@ agilicus/agilicus_api/api/users_api.py,sha256=wx8eoilVRiPysdhonffkjmv9OfmoOraWTL
73
73
  agilicus/agilicus_api/api/users_api_mock.py,sha256=8FL2tkK1zGGN_SuPxtZ7CX-B6gqfZaqq37TuY9ETVV0,20960
74
74
  agilicus/agilicus_api/api/whoami_api.py,sha256=bP9mGQqHRV8QAnWqPw7Nbjrjpn2iD57JwwDJmtJvnlA,7941
75
75
  agilicus/agilicus_api/api/whoami_api_mock.py,sha256=rlvZoWnMCqORMZBg7SOv6d3xp52kELdh6wXcCaIZ93w,346
76
- agilicus/agilicus_api/api_client.py,sha256=gfkdwZ3_e9bVPFmHJ7nYoQpDccvq2uKTmay4_NkC2oc,38845
76
+ agilicus/agilicus_api/api_client.py,sha256=IsH-RU6JbltsOsWvk39wrxJQWjXaujI3jq42Wk0DXqM,38845
77
77
  agilicus/agilicus_api/apis/__init__.py,sha256=ijG84bKeWq8lCvqXBtmWXrEnDMfw2t5qu5nQwgAyckU,2280
78
- agilicus/agilicus_api/configuration.py,sha256=c4eC8QIzvA2a3GqKKDPPVZR-xcdO21nhiWeS0NxNfeo,18447
78
+ agilicus/agilicus_api/configuration.py,sha256=ARuiW8Yjhg79MJcSvEWOXJpuNG9IXJT87ucXgY5WJgI,18447
79
79
  agilicus/agilicus_api/docs/APIKey.md,sha256=4cKuz4_l9HcEDnUrLwYbEnn9C2WoDayrjfrY1Ixgaf4,1747
80
80
  agilicus/agilicus_api/docs/APIKeyIntrospect.md,sha256=nJ-zkuFm3JMbWFDYYN_vYyQk1snGBtBvIxtCQxamhAU,1019
81
81
  agilicus/agilicus_api/docs/APIKeyIntrospectAuthorizationInfo.md,sha256=7RApOOLjvWQs5sw2jb25g7i3Kta1BiEY-s8VRXfppH8,725
@@ -2863,7 +2863,7 @@ agilicus/agilicus_api/test/test_x509_root_certificate.py,sha256=684W7MatZX4HjDCB
2863
2863
  agilicus/agilicus_api/test/test_x509_root_certificate_spec.py,sha256=iVMIlsCMevxkvbE83LOEDuSVFAF6lci545Ofa9YcSt4,2832
2864
2864
  agilicus/agilicus_api/test/test_x509_root_certificate_status.py,sha256=eUU7Yy12elYYGxVI0R1UbdJZjySsde3oMyuXBOFJsbQ,2846
2865
2865
  agilicus/agilicus_api/test/test_xss_settings.py,sha256=9pWZAyjWsOtFk21wPyrKXCveTHdftsgAXnUtetSOBq4,2746
2866
- agilicus/agilicus_api_README.md,sha256=yBq7bwVoA27PbwAU0tJCkIzE2viKV5jpLtzNd8dRJeM,182663
2866
+ agilicus/agilicus_api_README.md,sha256=xkeNoK4THBPSemYBPP7C85JpMEHaVa92B4gVp1Ex3H4,182663
2867
2867
  agilicus/aliases.ini,sha256=MxqiVo2f2xdUDVF1YDkNW36AIqN8hrYjlTVfraEUZXY,455
2868
2868
  agilicus/amq.py,sha256=yxi-YTbJPVl10s78Hlr1dmrQR63iaSIoROGVILzFPmE,1775
2869
2869
  agilicus/apps.py,sha256=_HUI-_nqhRKL1bRoNqEBzpLqb9oEBKi8wia3Kp07jP8,60886
@@ -2924,7 +2924,7 @@ agilicus/licensing/licensing_main.py,sha256=VzDuONgpCIPnGxWdTQzpVNKDc22tFZTXW65L
2924
2924
  agilicus/licensing/product_table_versions.py,sha256=Zk8L--z8wu6DPnbtYMGifc2J2KdNtnTBgyJv-CRAbr8,3038
2925
2925
  agilicus/logs.py,sha256=Y4XVcLctY-2O-Q_CXbJs9sAqu0NknHKSsqilKiDM_A0,804
2926
2926
  agilicus/lookups.py,sha256=MNmNsKpP7Fq_poLAnL9xo_iptFilKM9ziGLyIe8VKaw,669
2927
- agilicus/main.py,sha256=rolD8WwPCupA32e9YX5wu8WUAAWuo1XVBmGgRe7ui64,303731
2927
+ agilicus/main.py,sha256=DdSakkZEL6AH0dy4kL_WFxsfaxvXjHXYE4qwhDX2T44,303865
2928
2928
  agilicus/messages/__init__.py,sha256=cVqfaKUndO-AYfppkdFICM5WvYFFB1hRjXihFWmiGPQ,174
2929
2929
  agilicus/messages/messages.py,sha256=b2eO6BaWI9UZTLETcdy1NotyuNlKIJf6CS_TUzehuk4,9175
2930
2930
  agilicus/messages/messages_main.py,sha256=A0xucYwwUZFIuUc0bAyAqVwofErakmyawq5bwhZKcOU,1598
@@ -2938,10 +2938,11 @@ agilicus/output/table.py,sha256=GvWzDo_nfg-mBn3_3rFzvRCiYC_EnkEOUVIepYJwjG8,1334
2938
2938
  agilicus/output/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2939
2939
  agilicus/output/tests/column_builder_test.py,sha256=fKP4V5sqXtmEIr-Q0gWVSFdBqCUtugZkP6G5gML_T7I,2130
2940
2940
  agilicus/pagination/__init__.py,sha256=aQ9h8E0nkKwvhYY3LqRNlpDJNjcXgRm6SYCjXVcpOfQ,74
2941
- agilicus/pagination/input.py,sha256=k3_GOrYm2cDvYTVjDfGUBTHUo1M57OUOOP7aWYcp4_k,174
2941
+ agilicus/pagination/auto_iterator.py,sha256=CF0Qxii_Yund8ggFOa4Fst92hj3Nouh_5qXO5StuCMk,5171
2942
+ agilicus/pagination/input.py,sha256=lSyBTKxIG8Ag0MkrMHS0AaMlbHSMsBghrUfPjgYV3qE,287
2942
2943
  agilicus/pagination/pagination.py,sha256=4DtFTRkk1HlF6dbjVaXFk3GgbAzDqhlXHRVs9hhOh9A,2339
2943
2944
  agilicus/pagination/pagination_test.py,sha256=6s4ARvxt8ku93Fjr4s_vmthT4z9RoXPGwTQRf3hEHLA,2874
2944
- agilicus/patches.py,sha256=qTqLOgCAcFZPcPOkgfqMnK9bnqTXMvj_0ERsjRFcZug,1384
2945
+ agilicus/patches.py,sha256=DN47GvNmmpQY76iwk1-ssT_GERuzI9FCTXQPfqFXUlI,1861
2945
2946
  agilicus/permissions.py,sha256=uB65yuDFICp1N10m0cdUjgizx9MQzAbLbAsBSTw1Rcc,2117
2946
2947
  agilicus/policy/policies.py,sha256=eAy1iRlYKvkuc-10ssw_iuchY-I24LvtHiruvyzo5Pg,11440
2947
2948
  agilicus/policy/policy_main.py,sha256=W91CxqQP1ye9UjsiMqgZNeULMvrzMB5TiPJZW3hogPM,4573
@@ -2954,16 +2955,17 @@ agilicus/products/products.py,sha256=he27jN3MUyXBdTdV2HRyvUYb0zD3W1TGsuC7NHLKngQ
2954
2955
  agilicus/products/products_main.py,sha256=saa2-e5oeHW6D5AWPcld99KwgQ9nBY3hoW8Jz_5nfMQ,3421
2955
2956
  agilicus/regions.py,sha256=T2Xsp2L7eVORSKyYuBofMto3yp4QlnNI7MNqm48h0xM,13059
2956
2957
  agilicus/resource_helpers.py,sha256=pOHz2Nd7HjqU7GCepyKyBZC02gH38PvNKhx5hHOFsoE,1350
2957
- agilicus/resources.py,sha256=zXQc3G4s06TSNXxIK3H4J3xDE4FjLUSpujr5K5-kUpo,11255
2958
+ agilicus/resources.py,sha256=_tKu53Eb4PpjmwJ2yeLo_ycBPE5s3QLILBffPi_VsHw,11405
2958
2959
  agilicus/response.py,sha256=tI2-dAJwhBuuDplSsouuMmCmKHSwR_Mx71af8tgsuYo,468
2959
2960
  agilicus/rules/rules.py,sha256=gpu7g308fTlE0LVuBcUXikho6TBx4-kdPUM6mPmawdY,30980
2960
2961
  agilicus/rules/rules_main.py,sha256=aOH4mcxb4-_azgzcz5kuOSzI-CvLhCwq1rZxDvaoHe4,15026
2961
2962
  agilicus/scopes.py,sha256=OgPUksJSOSaJ3XcHPP8WJQ3e_p8B9wVmRXr-oZDfZP0,1344
2962
2963
  agilicus/service_configuration.py,sha256=WlsvTKA_bkle1PthJK0S96lpPK7GNr-BWWp8a_-MgtM,490
2963
2964
  agilicus/service_token.py,sha256=YDVFeBe9Yv0qYvfUenwnpGHuj2x1J06YUe5A_C8L6L4,7162
2964
- agilicus/ssh.py,sha256=La2FJJuPqhdU4jKo65rteOJ2sQ3PII6Z1gQoHr67wHs,3068
2965
+ agilicus/ssh.py,sha256=OnMHdq5TP-Aa4WMvoUkg6gsUyfNrdh5-DZTnSlvOOG4,3324
2965
2966
  agilicus/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2966
2967
  agilicus/tests/keyring_test.py,sha256=Uwp2VS2_NffYBgHAS9bXuXnIxRoK0_VOWaaYCZKv0lg,1452
2968
+ agilicus/tests/pagination/test_auto_iterator.py,sha256=hxT0sLecgqh2_gIOVobbdmlojbTjxMnRUc0Stw0zvPg,11129
2967
2969
  agilicus/tests/test_pop_utils.py,sha256=gdSMOmE0pNSDA0UgUWdbLKpFzUGwfBwkFSrk1p1JdSo,1083
2968
2970
  agilicus/tokens.py,sha256=JLileUHs5PcGjOdvQl-_9dv7DVtGa76nz1iUEIlivOU,20584
2969
2971
  agilicus/transfers.py,sha256=PYr_fW7dyXNUXzi5Wp5mUjZOvU7MbRzoN-D8Omo-YSQ,1523
@@ -2972,8 +2974,8 @@ agilicus/trusted_certs/trusted_certs_main.py,sha256=6dHHWXvNIcUa_nA9ptigL4Vibe4n
2972
2974
  agilicus/users.py,sha256=DusnnWKg4gkkKkdUjuz1NXpC6FKvE9xwHKdKm3kjHZo,44910
2973
2975
  agilicus/version.py,sha256=G9OFdL1v_4dLDfk6I6taDNypM5bbO-JHAwilsu9LYgg,23
2974
2976
  agilicus/whoami.py,sha256=kqghtWMgZOd2rhKmfguDwCTm6A3gNS8Kj-S2IBxBtl0,206
2975
- agilicus-1.305.0.dist-info/LICENSE.txt,sha256=Zq4tqiCroC2CVrBB_PWjapRdvpae23nljdiaSkOzUho,1061
2976
- agilicus-1.305.0.dist-info/METADATA,sha256=fyfL5uT3ZgT722aTiDfMhFDEEPZy_nMoDICczgVRqvQ,3838
2977
- agilicus-1.305.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
2978
- agilicus-1.305.0.dist-info/entry_points.txt,sha256=a66hGozzLkHu0IewFzIMbSAhMTNTddUaA2T3_16Gb_s,51
2979
- agilicus-1.305.0.dist-info/RECORD,,
2977
+ agilicus-1.306.0.dist-info/LICENSE.txt,sha256=Zq4tqiCroC2CVrBB_PWjapRdvpae23nljdiaSkOzUho,1061
2978
+ agilicus-1.306.0.dist-info/METADATA,sha256=bhBs8Abt5x_L965mnaBIPwWvZqIGLoSY3letvptNxXM,3838
2979
+ agilicus-1.306.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
2980
+ agilicus-1.306.0.dist-info/entry_points.txt,sha256=a66hGozzLkHu0IewFzIMbSAhMTNTddUaA2T3_16Gb_s,51
2981
+ agilicus-1.306.0.dist-info/RECORD,,