current-cli 0.1.35__tar.gz → 0.1.36__tar.gz
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.
- {current_cli-0.1.35 → current_cli-0.1.36}/PKG-INFO +1 -1
- {current_cli-0.1.35 → current_cli-0.1.36}/current_cli/build.py +7 -1
- {current_cli-0.1.35 → current_cli-0.1.36}/current_cli/schema.py +4 -0
- {current_cli-0.1.35 → current_cli-0.1.36}/current_cli/schema.yml +25 -2
- {current_cli-0.1.35 → current_cli-0.1.36}/llms.txt +9 -2
- {current_cli-0.1.35 → current_cli-0.1.36}/pyproject.toml +1 -1
- {current_cli-0.1.35 → current_cli-0.1.36}/tests/test_requests.py +34 -0
- {current_cli-0.1.35 → current_cli-0.1.36}/.gitignore +0 -0
- {current_cli-0.1.35 → current_cli-0.1.36}/README.md +0 -0
- {current_cli-0.1.35 → current_cli-0.1.36}/current_cli/__init__.py +0 -0
- {current_cli-0.1.35 → current_cli-0.1.36}/current_cli/config.py +0 -0
- {current_cli-0.1.35 → current_cli-0.1.36}/current_cli/docs.py +0 -0
- {current_cli-0.1.35 → current_cli-0.1.36}/current_cli/http.py +0 -0
- {current_cli-0.1.35 → current_cli-0.1.36}/current_cli/main.py +0 -0
- {current_cli-0.1.35 → current_cli-0.1.36}/scripts/bump_version.py +0 -0
- {current_cli-0.1.35 → current_cli-0.1.36}/tests/__init__.py +0 -0
- {current_cli-0.1.35 → current_cli-0.1.36}/tests/conftest.py +0 -0
- {current_cli-0.1.35 → current_cli-0.1.36}/tests/test_auth.py +0 -0
- {current_cli-0.1.35 → current_cli-0.1.36}/tests/test_bump_version.py +0 -0
- {current_cli-0.1.35 → current_cli-0.1.36}/tests/test_command_tree.py +0 -0
- {current_cli-0.1.35 → current_cli-0.1.36}/tests/test_docs.py +0 -0
|
@@ -16,9 +16,14 @@ def _make_callback(op: Operation):
|
|
|
16
16
|
for param in op.path_params:
|
|
17
17
|
path = path.replace("{" + param.name + "}", str(kwargs.pop(param.name)))
|
|
18
18
|
|
|
19
|
-
params: dict[str, str] = {}
|
|
19
|
+
params: dict[str, str | list[str]] = {}
|
|
20
20
|
for param in op.query_params:
|
|
21
21
|
value = kwargs.pop(param.name, None)
|
|
22
|
+
# click gives a repeatable option an empty tuple, not None, when
|
|
23
|
+
# it is absent; treat that as "not given" so it never becomes an
|
|
24
|
+
# empty query key.
|
|
25
|
+
if param.is_array:
|
|
26
|
+
value = list(value) if value else None
|
|
22
27
|
if value is None and param.name == "workspace":
|
|
23
28
|
value = config.get("default_workspace")
|
|
24
29
|
if value is None:
|
|
@@ -48,6 +53,7 @@ def _make_command(op: Operation) -> click.Command:
|
|
|
48
53
|
click.Option(
|
|
49
54
|
[f"--{param.name.replace('_', '-')}"],
|
|
50
55
|
required=False,
|
|
56
|
+
multiple=param.is_array,
|
|
51
57
|
help=param.description or None,
|
|
52
58
|
)
|
|
53
59
|
)
|
|
@@ -21,6 +21,9 @@ class Parameter:
|
|
|
21
21
|
location: str # "path" or "query"
|
|
22
22
|
required: bool
|
|
23
23
|
description: str
|
|
24
|
+
# An array query param is sent as the repeated key the API reads with
|
|
25
|
+
# getlist (?fields=a&fields=b), so its option has to be repeatable too.
|
|
26
|
+
is_array: bool = False
|
|
24
27
|
|
|
25
28
|
|
|
26
29
|
@dataclass(frozen=True)
|
|
@@ -90,6 +93,7 @@ def extract_operations(spec: dict) -> list[Operation]:
|
|
|
90
93
|
location=raw["in"],
|
|
91
94
|
required=raw.get("required", False),
|
|
92
95
|
description=raw.get("description", ""),
|
|
96
|
+
is_array=raw.get("schema", {}).get("type") == "array",
|
|
93
97
|
)
|
|
94
98
|
if param.location == "path":
|
|
95
99
|
path_params.append(param)
|
|
@@ -1841,12 +1841,17 @@ paths:
|
|
|
1841
1841
|
get:
|
|
1842
1842
|
operationId: projects_projects_inventory_retrieve
|
|
1843
1843
|
description: |-
|
|
1844
|
-
Page current field values, optionally narrowed to named keys
|
|
1844
|
+
Page current field values, optionally narrowed to named keys and
|
|
1845
|
+
to projects whose values match.
|
|
1845
1846
|
|
|
1846
1847
|
The full project list serializes every field of every project —
|
|
1847
1848
|
megabytes at production scale. This page is the compact census a
|
|
1848
1849
|
chat agent can scan: identity plus the keys it asked for, no
|
|
1849
|
-
timeline, no provenance.
|
|
1850
|
+
timeline, no provenance.
|
|
1851
|
+
|
|
1852
|
+
Filter here rather than page-and-sift: a caller that reads every
|
|
1853
|
+
page and picks the matches by eye miscounts, and "total" under a
|
|
1854
|
+
filter is the count it was really after. See state.list_projects.
|
|
1850
1855
|
parameters:
|
|
1851
1856
|
- in: query
|
|
1852
1857
|
name: fields
|
|
@@ -1855,6 +1860,16 @@ paths:
|
|
|
1855
1860
|
items:
|
|
1856
1861
|
type: string
|
|
1857
1862
|
description: Field keys to keep; omit to return every current value
|
|
1863
|
+
- in: query
|
|
1864
|
+
name: filter
|
|
1865
|
+
schema:
|
|
1866
|
+
type: array
|
|
1867
|
+
items:
|
|
1868
|
+
type: string
|
|
1869
|
+
description: Keep only projects whose current value matches, as 'key:value'
|
|
1870
|
+
(for example 'status:Active'). Repeat for more fields; repeating one key
|
|
1871
|
+
accepts any of its values. An option matches by label, value, or ID. 'total'
|
|
1872
|
+
counts the matching projects.
|
|
1858
1873
|
- in: query
|
|
1859
1874
|
name: limit
|
|
1860
1875
|
schema:
|
|
@@ -1865,6 +1880,14 @@ paths:
|
|
|
1865
1880
|
schema:
|
|
1866
1881
|
type: integer
|
|
1867
1882
|
description: Number of projects to skip (default 0)
|
|
1883
|
+
- in: query
|
|
1884
|
+
name: values
|
|
1885
|
+
schema:
|
|
1886
|
+
type: string
|
|
1887
|
+
enum:
|
|
1888
|
+
- ids
|
|
1889
|
+
- labels
|
|
1890
|
+
description: Read option values as labels (default) or as option IDs
|
|
1868
1891
|
- in: query
|
|
1869
1892
|
name: workspace
|
|
1870
1893
|
schema:
|
|
@@ -617,19 +617,26 @@ Options:
|
|
|
617
617
|
|
|
618
618
|
### current projects inventory retrieve
|
|
619
619
|
|
|
620
|
-
Page current field values, optionally narrowed to named keys
|
|
620
|
+
Page current field values, optionally narrowed to named keys and
|
|
621
|
+
to projects whose values match.
|
|
621
622
|
|
|
622
623
|
The full project list serializes every field of every project —
|
|
623
624
|
megabytes at production scale. This page is the compact census a
|
|
624
625
|
chat agent can scan: identity plus the keys it asked for, no
|
|
625
|
-
timeline, no provenance.
|
|
626
|
+
timeline, no provenance.
|
|
627
|
+
|
|
628
|
+
Filter here rather than page-and-sift: a caller that reads every
|
|
629
|
+
page and picks the matches by eye miscounts, and "total" under a
|
|
630
|
+
filter is the count it was really after. See state.list_projects.
|
|
626
631
|
|
|
627
632
|
GET /api/projects/projects/inventory/
|
|
628
633
|
|
|
629
634
|
Options:
|
|
630
635
|
- `--fields` - Field keys to keep; omit to return every current value
|
|
636
|
+
- `--filter` - Keep only projects whose current value matches, as 'key:value' (for example 'status:Active'). Repeat for more fields; repeating one key accepts any of its values. An option matches by label, value, or ID. 'total' counts the matching projects.
|
|
631
637
|
- `--limit` - Max projects per page (default 100, max 200)
|
|
632
638
|
- `--offset` - Number of projects to skip (default 0)
|
|
639
|
+
- `--values` - Read option values as labels (default) or as option IDs
|
|
633
640
|
- `--workspace` - Workspace UUID
|
|
634
641
|
|
|
635
642
|
### current projects list
|
|
@@ -60,6 +60,40 @@ def test_create_sends_json_body(cli, runner, transport_factory):
|
|
|
60
60
|
assert json.loads(request.content) == {"name": "Order beams", "workspace": "w1"}
|
|
61
61
|
|
|
62
62
|
|
|
63
|
+
def test_array_query_param_repeats(cli, runner, transport_factory):
|
|
64
|
+
"""An array param must repeat its key, the shape the API reads with
|
|
65
|
+
getlist — one AND-ed filter per --filter."""
|
|
66
|
+
transport = transport_factory(ok({}))
|
|
67
|
+
|
|
68
|
+
result = runner.invoke(
|
|
69
|
+
cli,
|
|
70
|
+
[
|
|
71
|
+
"projects",
|
|
72
|
+
"inventory",
|
|
73
|
+
"retrieve",
|
|
74
|
+
"--workspace",
|
|
75
|
+
"ws-uuid",
|
|
76
|
+
"--filter",
|
|
77
|
+
"status:Active",
|
|
78
|
+
"--filter",
|
|
79
|
+
"site_type:Garden Style",
|
|
80
|
+
],
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
assert result.exit_code == 0, result.output
|
|
84
|
+
params = transport.requests[0].url.params
|
|
85
|
+
assert params.get_list("filter") == ["status:Active", "site_type:Garden Style"]
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_array_query_param_is_absent_when_not_given(cli, runner, transport_factory):
|
|
89
|
+
transport = transport_factory(ok({}))
|
|
90
|
+
|
|
91
|
+
result = runner.invoke(cli, ["projects", "inventory", "retrieve", "--workspace", "ws-uuid"])
|
|
92
|
+
|
|
93
|
+
assert result.exit_code == 0, result.output
|
|
94
|
+
assert "filter" not in transport.requests[0].url.params
|
|
95
|
+
|
|
96
|
+
|
|
63
97
|
def test_default_workspace_fallback(cli, runner, transport_factory):
|
|
64
98
|
config.set_value("default_workspace", "default-ws")
|
|
65
99
|
transport = transport_factory(ok({}))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|