-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Convert
globus flows list
to use paginated call (#686)
`globus flows list` now uses a paginated call under a PagingWrapper. To support this, the command has a new argument `--limit`, which is a norm for any CLI commands which interact with paginated APIs. It applies to the paginator, not to the API calls. The limit is set, as with several other commands, to have a floor of 1 and a default of 25. There is no upper bound set at present. In order for `-Fjson` output to be usable, we need to set `json_converter=...` on the formatting call. There is a pre-built pattern for this for Transfer commands, but it is not portable to other APIs. Therefore, a new feature is added here to `PagingWrapper` to generate a value which can be passed here. Ideally the PagingWrapper could pick this up from the underlying `items_key` in the paginator being used, and this could be supported by the formatted_print codepath. However, that would grow the scope of this change and extends beyond our present needs. (Likely such a change alters the interface for PagingWrapper and perhaps even allows a paginator to be directly passed to the formatted_print function.) Testing for this change copies code from the globus-sdk testsuite to build out paginated responses. It would be better to share these, but that requires additional thought and design because the paginated response set does not trivially fit the existing `globus_sdk._testing` tools for data sharing. As additional changes included here, the `globus flows list` command has been changed in the following ways: - it passes `orderby=...` as a named parameter, not using `query_params` - it is no longer hidden (the changelog fragment for it is therefore reintroduced)
- Loading branch information
Showing
6 changed files
with
219 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
### Enhancements | ||
|
||
* A new command, `globus flows list`, allows users to list Flow objects in | ||
Globus Flows |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
from __future__ import annotations | ||
|
||
import datetime | ||
import uuid | ||
from typing import Any | ||
|
||
import pytest | ||
from globus_sdk._testing import register_response_set | ||
from responses import matchers | ||
|
||
OWNER_ID = "e061df5a-b7b9-4578-a73b-6d4a4edfd66e" | ||
|
||
|
||
# this builder is mostly copied from globus-sdk tests with minimal changes | ||
# | ||
# TODO: find a better way to share the paginated fixture data generation between these | ||
# two projects | ||
def generate_hello_world_example_flow(n: int) -> dict[str, Any]: | ||
flow_id = str(uuid.UUID(int=n)) | ||
base_time = datetime.datetime.fromisoformat("2021-10-18T19:19:35.967289+00:00") | ||
updated_at = created_at = base_time + datetime.timedelta(days=n) | ||
flow_user_scope = ( | ||
f"https://auth.globus.org/scopes/{flow_id}/" | ||
f"flow_{flow_id.replace('-', '_')}_user" | ||
) | ||
|
||
return { | ||
"action_url": f"https://flows.automate.globus.org/flows/{flow_id}", | ||
"administered_by": [], | ||
"api_version": "1.0", | ||
"created_at": created_at.isoformat(), | ||
"created_by": f"urn:globus:auth:identity:{OWNER_ID}", | ||
"definition": { | ||
"StartAt": "HelloWorld", | ||
"States": { | ||
"HelloWorld": { | ||
"ActionScope": ( | ||
"https://auth.globus.org/scopes/actions.globus.org/hello_world" | ||
), | ||
"ActionUrl": "https://actions.globus.org/hello_world", | ||
"End": True, | ||
"Parameters": {"echo_string": "Hello, World."}, | ||
"ResultPath": "$.Result", | ||
"Type": "Action", | ||
} | ||
}, | ||
}, | ||
"description": "A simple Flow...", | ||
"flow_administrators": [], | ||
"flow_owner": f"urn:globus:auth:identity:{OWNER_ID}", | ||
"flow_starters": [], | ||
"flow_url": f"https://flows.automate.globus.org/flows/{flow_id}", | ||
"flow_viewers": [], | ||
"globus_auth_scope": flow_user_scope, | ||
"globus_auth_username": f"{flow_id}@clients.auth.globus.org", | ||
"id": str(flow_id), | ||
"input_schema": { | ||
"additionalProperties": False, | ||
"properties": { | ||
"echo_string": {"description": "The string to echo", "type": "string"}, | ||
"sleep_time": {"type": "integer"}, | ||
}, | ||
"required": ["echo_string", "sleep_time"], | ||
"type": "object", | ||
}, | ||
"keywords": [], | ||
"log_supported": True, | ||
"principal_urn": f"urn:globus:auth:identity:{flow_id}", | ||
"runnable_by": [], | ||
"subtitle": "", | ||
"synchronous": False, | ||
"title": f"Hello, World (Example {n})", | ||
"types": ["Action"], | ||
"updated_at": updated_at.isoformat(), | ||
"user_role": "flow_viewer", | ||
"visible_to": [], | ||
} | ||
|
||
|
||
@pytest.fixture(autouse=True, scope="session") | ||
def setup_paginated_responses() -> None: | ||
register_response_set( | ||
"flows_list_paginated", | ||
{ | ||
"page0": dict( | ||
service="flows", | ||
path="/flows", | ||
json={ | ||
"flows": [generate_hello_world_example_flow(i) for i in range(20)], | ||
"limit": 20, | ||
"has_next_page": True, | ||
"marker": "fake_marker_0", | ||
}, | ||
match=[matchers.query_param_matcher({"orderby": "updated_at DESC"})], | ||
), | ||
"page1": dict( | ||
service="flows", | ||
path="/flows", | ||
json={ | ||
"flows": [ | ||
generate_hello_world_example_flow(i) for i in range(20, 40) | ||
], | ||
"limit": 20, | ||
"has_next_page": True, | ||
"marker": "fake_marker_1", | ||
}, | ||
match=[ | ||
matchers.query_param_matcher( | ||
{"orderby": "updated_at DESC", "marker": "fake_marker_0"} | ||
) | ||
], | ||
), | ||
"page2": dict( | ||
service="flows", | ||
path="/flows", | ||
json={ | ||
"flows": [ | ||
generate_hello_world_example_flow(i) for i in range(40, 60) | ||
], | ||
"limit": 20, | ||
"has_next_page": False, | ||
"marker": None, | ||
}, | ||
match=[ | ||
matchers.query_param_matcher( | ||
{"orderby": "updated_at DESC", "marker": "fake_marker_1"} | ||
) | ||
], | ||
), | ||
"auth_get_identities": dict( | ||
service="auth", | ||
path="/v2/api/identities", | ||
json={ | ||
"identities": [ | ||
{ | ||
"username": "shrek@globus.org", | ||
"name": "Shrek by William Steig", | ||
"id": OWNER_ID, | ||
"identity_provider": "c8abac57-560c-46c8-b386-f116ed8793d5", | ||
"organization": ( | ||
"Fairytales Whose Movie Adaptations Diverge " | ||
"Significantly From Their Source Material" | ||
), | ||
"status": "used", | ||
"email": "shrek@globus.org", | ||
} | ||
] | ||
}, | ||
), | ||
}, | ||
metadata={ | ||
"owner_id": OWNER_ID, | ||
"flow_owner": "shrek@globus.org", | ||
"num_pages": 3, | ||
"expect_markers": ["fake_marker_0", "fake_marker_1", None], | ||
"total_items": 60, | ||
}, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters