diff --git a/cnctcli/api/products.py b/cnctcli/api/products.py index ee56a634..78ed2a22 100644 --- a/cnctcli/api/products.py +++ b/cnctcli/api/products.py @@ -6,11 +6,11 @@ import click import requests - from cnctcli.api.utils import ( format_http_status, get_headers, handle_http_error, + parse_content_range, ) @@ -53,12 +53,13 @@ def get_products(endpoint, api_key, query, limit, offset): if query: url = f'{url}?{query}' res = requests.get( - f'{endpoint}/products', + url, params={'limit': limit, 'offset': offset}, headers=get_headers(api_key), ) if res.status_code == 200: - return res.json() + content_range = res.headers.get('Content-Range') + return res.json(), parse_content_range(content_range) handle_http_error(res) diff --git a/cnctcli/api/utils.py b/cnctcli/api/utils.py index 32b4241e..001064ca 100644 --- a/cnctcli/api/utils.py +++ b/cnctcli/api/utils.py @@ -1,4 +1,5 @@ import platform +from collections import namedtuple from http import HTTPStatus import click @@ -6,6 +7,9 @@ from cnctcli import get_version +ContentRange = namedtuple('ContentRange', ('first', 'last', 'count')) + + def _get_user_agent(): version = get_version() pimpl = platform.python_implementation() @@ -41,3 +45,12 @@ def handle_http_error(res): raise click.ClickException(f'{status}: {code} - {message}') raise click.ClickException(f'{status}: unexpected error.') + + +def parse_content_range(value): + if not value: + return + _, info = value.split() + first_last, count = info.split('/') + first, last = first_last.split('-') + return ContentRange(int(first), int(last), int(count)) diff --git a/cnctcli/commands/product.py b/cnctcli/commands/product.py index c34e69d2..d369e5e5 100644 --- a/cnctcli/commands/product.py +++ b/cnctcli/commands/product.py @@ -63,7 +63,7 @@ def cmd_list_products(config, query, page_size, always_continue): has_more = True while has_more: - products = get_products( + products, pagination = get_products( config.active.endpoint, config.active.api_key, query, @@ -77,11 +77,16 @@ def cmd_list_products(config, query, page_size, always_continue): click.echo( f"{prod['id']} - {prod['name']}" ) - if not always_continue: - if not continue_or_quit(): - return + if pagination: + has_more = pagination.last < pagination.count - 1 + else: + has_more = len(products) == page_size + + if has_more: + if not always_continue: + if not continue_or_quit(): + return - has_more = len(products) == page_size offset += page_size diff --git a/requirements/dev.txt b/requirements/dev.txt index 27e8f5b0..ce3b7f96 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,4 +1,5 @@ click==7.1.2 openpyxl>=2.5.14 setuptools-scm==4.1.2 -tqdm==4.48.2 \ No newline at end of file +tqdm==4.48.2 +requests==2.21.0