Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add page limit #16

Merged
merged 2 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
Release History
===============

1.0.5 (2023-11-01)
------------------

- Add page limit

1.0.4 (2023-09-29)
------------------

Expand Down
2 changes: 1 addition & 1 deletion cybsi/__version__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "1.0.4"
__version__ = "1.0.5"
__title__ = "cybsi-cloud-sdk"
__description__ = "Cybsi Cloud development kit"
__license__ = "Apache License 2.0"
Expand Down
4 changes: 4 additions & 0 deletions cybsi/cloud/auth/api_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ def filter(
revoked: Optional[bool] = None,
description: Optional[str] = None,
cursor: Optional[Cursor] = None,
limit: Optional[int] = None,
) -> Page["APIKeyView"]:
"""Get API keys.

Expand All @@ -122,6 +123,7 @@ def filter(
revoked: Revocation flag.
description: Key description.
cursor: Page cursor.
limit: Page limit.
Return:
Page with API-Key common views and next page cursor.
Raises:
Expand All @@ -131,6 +133,8 @@ def filter(
params: JsonObject = {}
if cursor is not None:
params["cursor"] = str(cursor)
if limit is not None:
params["limit"] = limit
if revoked is not None:
params["revoked"] = bool(revoked)
if description is not None:
Expand Down
4 changes: 4 additions & 0 deletions cybsi/cloud/auth/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def filter(
*,
parent_id: Optional[int] = None,
cursor: Optional[Cursor] = None,
limit: Optional[int] = None,
) -> Page["ResourceView"]:
"""Get resources.

Expand All @@ -23,6 +24,7 @@ def filter(
Args:
parent_id: identifier of parent resource. It must be greater than 0.
cursor: Page cursor.
limit: Page limit.
Return:
Page with resource common views and next page cursor.
Raises:
Expand All @@ -38,6 +40,8 @@ def filter(
params["parentID"] = parent_id
if cursor is not None:
params["cursor"] = str(cursor)
if limit is not None:
params["limit"] = limit
resp = self._connector.do_get(path=self._path, params=params)
page = Page(self._connector.do_get, resp, ResourceView)
return page
Expand Down
16 changes: 14 additions & 2 deletions cybsi/cloud/iocean/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,18 @@ def update(self, collection_id: str, tag: Tag, *, schema_id: Optional[str]):
self._connector.do_patch(url, tag=tag, json=body)

def filter(
self, *, cursor: Optional[Cursor] = None
self,
*,
cursor: Optional[Cursor] = None,
limit: Optional[int] = None,
) -> Page["CollectionCommonView"]:
"""Get collections.

Note:
Calls `GET /iocean/collections`.
Args:
cursor: Page cursor.
limit: Page limit.
Return:
Page with collection views and next page cursor.
Raises:
Expand All @@ -121,6 +125,8 @@ def filter(
params: JsonObject = {}
if cursor is not None:
params["cursor"] = str(cursor)
if limit is not None:
params["limit"] = limit
resp = self._connector.do_get(path=_PATH, params=params)
return Page(self._connector.do_get, resp, CollectionCommonView)

Expand Down Expand Up @@ -221,14 +227,18 @@ async def update(self, collection_id: str, tag: Tag, *, schema_id: Optional[str]
await self._connector.do_patch(url, tag=tag, json=body)

async def filter(
self, *, cursor: Optional[Cursor] = None
self,
*,
cursor: Optional[Cursor] = None,
limit: Optional[int] = None,
) -> AsyncPage["CollectionCommonView"]:
"""Get collections.

Note:
Calls `GET /iocean/collections`.
Args:
cursor: Page cursor.
limit: Page limit.
Return:
Page with collection views and next page cursor.
Raises:
Expand All @@ -238,6 +248,8 @@ async def filter(
params: JsonObject = {}
if cursor is not None:
params["cursor"] = str(cursor)
if limit is not None:
params["limit"] = limit
resp = await self._connector.do_get(path=_PATH, params=params)
return AsyncPage(self._connector.do_get, resp, CollectionCommonView)

Expand Down
36 changes: 32 additions & 4 deletions cybsi/cloud/iocean/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,11 @@ def delete(
self._connector.do_delete(path=path, params=params)

def filter(
self, *, collection_id: str, cursor: Optional[Cursor] = None
self,
*,
collection_id: str,
cursor: Optional[Cursor] = None,
limit: Optional[int] = None,
) -> Tuple[Page["ObjectView"], Optional[Cursor]]:
"""Get objects from the collection.

Expand All @@ -135,6 +139,7 @@ def filter(
Args:
collection_id: Collection identifier.
cursor: Page cursor.
limit: Page limit.
Return:
Page with object views. The page contains next page cursor.
Changes cursor. The cursor can be used to call :meth:`changes`.
Expand All @@ -148,14 +153,20 @@ def filter(
params: JsonObject = {}
if cursor is not None:
params["cursor"] = str(cursor)
if limit is not None:
params["limit"] = limit
path = _PATH.format(collection_id)
resp = self._connector.do_get(path=path, params=params)
return Page(self._connector.do_get, resp, ObjectView), _extract_changes_cursor(
resp
)

def changes(
self, *, collection_id: str, cursor: Cursor
self,
*,
collection_id: str,
cursor: Cursor,
limit: Optional[int] = None,
) -> Page["ObjectChangeView"]:
"""Get objects changes from the collection.

Expand All @@ -168,6 +179,7 @@ def changes(
obtained when requesting objects :meth:`filter`.
Subsequent calls should use cursor property of the page
returned by :meth:`changes`.
limit: Page limit.
Return:
Page with changes.
Warning:
Expand All @@ -189,6 +201,8 @@ def changes(
* :attr:`~cybsi.cloud.error.SemanticErrorCodes.CursorOutOfRange`
"""
params: JsonObject = {"cursor": cursor}
if limit is not None:
params["limit"] = limit
path = _PATH.format(collection_id) + "/changes"
resp = self._connector.do_get(path=path, params=params)
return Page(self._connector.do_get, resp, ObjectChangeView)
Expand Down Expand Up @@ -271,7 +285,11 @@ async def delete(
await self._connector.do_delete(path=path, params=params)

async def filter(
self, *, collection_id: str, cursor: Optional[Cursor] = None
self,
*,
collection_id: str,
cursor: Optional[Cursor] = None,
limit: Optional[int] = None,
) -> Tuple[AsyncPage["ObjectView"], Optional[Cursor]]:
"""Get objects from the collection.

Expand All @@ -280,6 +298,7 @@ async def filter(
Args:
collection_id: Collection identifier.
cursor: Page cursor.
limit: Page limit.
Return:
Page with object views. The page contains next page cursor.
Changes cursor. The cursor can be used to call :meth:`changes`.
Expand All @@ -293,14 +312,20 @@ async def filter(
params: JsonObject = {}
if cursor is not None:
params["cursor"] = str(cursor)
if limit is not None:
params["limit"] = limit
path = _PATH.format(collection_id)
resp = await self._connector.do_get(path=path, params=params)
return AsyncPage(
self._connector.do_get, resp, ObjectView
), _extract_changes_cursor(resp)

async def changes(
self, *, collection_id: str, cursor: Cursor
self,
*,
collection_id: str,
cursor: Cursor,
limit: Optional[int] = None,
) -> AsyncPage["ObjectChangeView"]:
"""Get objects changes from the collection.

Expand All @@ -313,6 +338,7 @@ async def changes(
obtained when requesting objects :meth:`filter`.
Subsequent calls should use cursor property of the page
returned by :meth:`changes`.
limit: Page limit.
Return:
Page with changes.
Warning:
Expand All @@ -334,6 +360,8 @@ async def changes(
* :attr:`~cybsi.cloud.error.SemanticErrorCodes.CursorOutOfRange`
"""
params: JsonObject = {"cursor": cursor}
if limit is not None:
params["limit"] = limit
path = _PATH.format(collection_id) + "/changes"
resp = await self._connector.do_get(path=path, params=params)
return AsyncPage(self._connector.do_get, resp, ObjectChangeView)
Expand Down
8 changes: 8 additions & 0 deletions cybsi/cloud/iocean/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,15 @@ def filter(
self,
*,
cursor: Optional[Cursor] = None,
limit: Optional[int] = None,
) -> Page["SchemaCommonView"]:
"""Get an object schemas filtration list.

Note:
Calls `GET /iocean/schemas`.
Args:
cursor: Page cursor.
limit: Page limit.
Returns:
Page with schema common views and next page cursor.
Raises:
Expand All @@ -101,6 +103,8 @@ def filter(
params: JsonObject = {}
if cursor is not None:
params["cursor"] = str(cursor)
if limit is not None:
params["limit"] = limit
resp = self._connector.do_get(path=_PATH, params=params)
return Page(self._connector.do_get, resp, SchemaCommonView)

Expand Down Expand Up @@ -181,13 +185,15 @@ async def filter(
self,
*,
cursor: Optional[Cursor] = None,
limit: Optional[int] = None,
) -> AsyncPage["SchemaCommonView"]:
"""Get an object schemas filtration list.

Note:
Calls `GET /iocean/schemas`.
Args:
cursor: Page cursor.
limit: Page limit.
Returns:
Page with schema common views and next page cursor.
Raises:
Expand All @@ -198,6 +204,8 @@ async def filter(
params: JsonObject = {}
if cursor is not None:
params["cursor"] = str(cursor)
if limit is not None:
params["limit"] = limit
resp = await self._connector.do_get(path=_PATH, params=params)
return AsyncPage(self._connector.do_get, resp, SchemaCommonView)

Expand Down
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ instructions for getting the most out of Cybsi Cloud SDK.

user/install
user/quickstart
user/pagination
user/examples
user/advanced
user/authentication
Expand Down
27 changes: 27 additions & 0 deletions docs/user/pagination.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.. _pagination:

Pagination
==========

You'll often need to work with collections of elements API provides.

Cybsi Cloud SDK provides two ways to traverse collections.

The **first** way is pages traversing.
This approach fits for cases when you need to get page's properties i.e. cursor.
For walking by page elements just iterate through the page.

.. literalinclude:: ../../examples/pagination_manual.py

The **second** way is elements traversing. This approach allows you to iterate through
collections without working with pages. To work with collections as with iterator use `chain_pages`.

.. literalinclude:: ../../examples/get_collection_objects_chained.py

Limit
-----

You can define page limit. Backend returns the specified maximum number of elements per page.
Backend overrides this value if limit is not set or value is out of bounds.

.. literalinclude:: ../../examples/page_limit.py
20 changes: 20 additions & 0 deletions examples/page_limit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env python3
from typing import Optional

from cybsi.cloud import Client, Config
from cybsi.cloud.auth import ResourceView
from cybsi.cloud.pagination import Page

if __name__ == "__main__":
config = Config(api_key="the cryptic string")

with Client(config) as client:
page: Optional[Page[ResourceView]] = client.auth.resources.filter(limit=3)
while page:
# Got page with maximum of 3 elements
# Page is iterable
for item in page:
# Do something with an item
pass
# Fetch next page
page = page.next_page()
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "cybsi-cloud-sdk"
version = "1.0.4"
version = "1.0.5"
description = "Cybsi Cloud development kit"
authors = ["Cybsi Cloud developers"]
license = "Apache License 2.0"
Expand Down Expand Up @@ -41,7 +41,7 @@ extend_skip = ["__init__.py"]
[tool.tbump]

[tool.tbump.version]
current = "1.0.4"
current = "1.0.5"

regex = '''
^
Expand Down