Skip to content

Commit

Permalink
Adding support --order and --order_by for list operations (#506)
Browse files Browse the repository at this point in the history
## 📝 Description

Adds --order_by and --order to filtering operations.

## ✔️ How to Test

Tested using command line. 

Ex.
`linode-cli linodes list --order_by label --order desc`
`linode-cli linodes list --order_by label`
  • Loading branch information
amisiorek-akamai authored Aug 14, 2023
1 parent ba57de8 commit 6a088ac
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 9 deletions.
23 changes: 14 additions & 9 deletions linodecli/api_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ def _build_filter_header(
if p.name in parsed_args_dict:
del parsed_args_dict[p.name]

# check for order_by and order
order_by = parsed_args_dict.pop("order_by")
order = parsed_args_dict.pop("order") or "asc"

# The "+and" list to be used in the filter header
filter_list = []

Expand All @@ -161,15 +165,16 @@ def _build_filter_header(
new_filters = [{k: j} for j in v] if isinstance(v, list) else [{k: v}]
filter_list.extend(new_filters)

if len(filter_list) < 1:
return None

return json.dumps(
# Only use +and if there are multiple attributes to filter on
{"+and": filter_list}
if len(filter_list) > 1
else filter_list[0]
)
result = {}
if len(filter_list) > 0:
if len(filter_list) == 1:
result = filter_list[0]
else:
result["+and"] = filter_list
if order_by is not None:
result["+order_by"] = order_by
result["+order"] = order
return json.dumps(result) if len(result) > 0 else None


def _build_request_url(ctx, operation, parsed_args) -> str:
Expand Down
17 changes: 17 additions & 0 deletions linodecli/baked/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import json
import platform
import re
import sys
from getpass import getpass
from os import environ, path
from typing import List, Tuple
Expand Down Expand Up @@ -322,11 +323,13 @@ def process_response_json(

def _add_args_filter(self, parser):
# build args for filtering
filterable_args = []
for attr in self.response_model.attrs:
if not attr.filterable:
continue

expected_type = TYPES[attr.datatype]
filterable_args.append(attr.name)
if expected_type == list:
parser.add_argument(
"--" + attr.name,
Expand All @@ -341,6 +344,20 @@ def _add_args_filter(self, parser):
type=expected_type,
metavar=attr.name,
)
# Add --order_by and --order argument
parser.add_argument(
"--order_by",
choices=filterable_args,
help="Attribute to order the results by - must be filterable.",
required="--order" in sys.argv,
)

parser.add_argument(
"--order",
choices=["asc", "desc"],
default="asc",
help="Either “asc” or “desc”. Defaults to “asc”. Requires +order_by",
)

def _add_args_post_put(self, parser) -> List[Tuple[str, str]]:
list_items = []
Expand Down
77 changes: 77 additions & 0 deletions tests/unit/test_api_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ def test_build_filter_header(self, list_operation):
SimpleNamespace(
filterable_result="bar",
filterable_list_result=["foo", "bar"],
order_by=None,
order=None,
),
)

Expand All @@ -188,6 +190,8 @@ def test_build_filter_header_single(self, list_operation):
list_operation,
SimpleNamespace(
filterable_result="bar",
order_by=None,
order=None,
),
)

Expand All @@ -203,6 +207,8 @@ def test_build_filter_header_single_list(self, list_operation):
list_operation,
SimpleNamespace(
filterable_list_result=["foo", "bar"],
order_by=None,
order=None,
),
)

Expand All @@ -218,6 +224,77 @@ def test_build_filter_header_single_list(self, list_operation):
== result
)

def test_build_filter_header_order_by(self, list_operation):
result = api_request._build_filter_header(
list_operation,
SimpleNamespace(
filterable_result="bar",
filterable_list_result=["foo", "bar"],
order_by="baz",
order=None,
),
)

assert (
json.dumps(
{
"+and": [
{"filterable_result": "bar"},
{"filterable_list_result": "foo"},
{"filterable_list_result": "bar"},
],
"+order_by": "baz",
"+order": "asc",
}
)
== result
)

def test_build_filter_header_order(self, list_operation):
result = api_request._build_filter_header(
list_operation,
SimpleNamespace(
filterable_result="bar",
filterable_list_result=["foo", "bar"],
order_by="baz",
order="desc",
),
)

assert (
json.dumps(
{
"+and": [
{"filterable_result": "bar"},
{"filterable_list_result": "foo"},
{"filterable_list_result": "bar"},
],
"+order_by": "baz",
"+order": "desc",
}
)
== result
)

def test_build_filter_header_only_order(self, list_operation):
result = api_request._build_filter_header(
list_operation,
SimpleNamespace(
order_by="baz",
order="desc",
),
)

assert (
json.dumps(
{
"+order_by": "baz",
"+order": "desc",
}
)
== result
)

def test_do_request_get(self, mock_cli, list_operation):
mock_response = Mock(status_code=200, reason="OK")

Expand Down

0 comments on commit 6a088ac

Please sign in to comment.