colacloud-cli 0.3.2__tar.gz → 0.3.4__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.
- colacloud_cli-0.3.4/.github/workflows/ci.yml +46 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/PKG-INFO +19 -5
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/README.md +18 -4
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/pyproject.toml +1 -1
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/api.py +42 -2
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/commands/colas.py +94 -9
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/formatters.py +10 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/tests/test_api.py +21 -1
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/tests/test_cli.py +31 -2
- colacloud_cli-0.3.4/tests/test_formatters.py +39 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/.gitignore +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/AGENTS.md +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/LICENSE +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/scripts/smoke_test.py +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/__init__.py +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/commands/__init__.py +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/commands/avas.py +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/commands/barcode.py +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/commands/config.py +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/commands/permittees.py +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/commands/processing_times.py +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/commands/production_reports.py +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/commands/usage.py +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/commands/utils.py +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/config.py +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/main.py +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/tests/__init__.py +0 -0
- {colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/tests/test_config.py +0 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
push:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: ci-${{ github.event.pull_request.head.ref || github.ref }}
|
|
16
|
+
cancel-in-progress: true
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
build:
|
|
20
|
+
name: Build & Validate
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
timeout-minutes: 15
|
|
23
|
+
env:
|
|
24
|
+
PYTHONPATH: src
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v6
|
|
27
|
+
|
|
28
|
+
- name: Set up Python
|
|
29
|
+
uses: actions/setup-python@v6
|
|
30
|
+
with:
|
|
31
|
+
python-version: "3.10"
|
|
32
|
+
|
|
33
|
+
- name: Install uv
|
|
34
|
+
uses: astral-sh/setup-uv@v8.1.0
|
|
35
|
+
|
|
36
|
+
- name: Install dependencies
|
|
37
|
+
run: uv sync
|
|
38
|
+
|
|
39
|
+
- name: Run tests
|
|
40
|
+
run: uv run pytest tests
|
|
41
|
+
|
|
42
|
+
- name: Ruff lint
|
|
43
|
+
run: uv run ruff check .
|
|
44
|
+
|
|
45
|
+
- name: Build package
|
|
46
|
+
run: uv build
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: colacloud-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: Command-line interface for the COLA Cloud API
|
|
5
5
|
Project-URL: Homepage, https://colacloud.us
|
|
6
6
|
Project-URL: Documentation, https://docs.colacloud.us/api-reference
|
|
@@ -100,8 +100,12 @@ cola colas list --date-from 2024-01-01 --date-to 2024-12-31
|
|
|
100
100
|
# Filter by ABV
|
|
101
101
|
cola colas list --product-type "distilled spirits" --abv-min 40 --abv-max 50
|
|
102
102
|
|
|
103
|
-
#
|
|
104
|
-
cola colas list --
|
|
103
|
+
# Filter by package and derived category
|
|
104
|
+
cola colas list --category Beer --derived-subcategory "Beer > Ale" \
|
|
105
|
+
--container-type can --volume-unit "fluid ounces" --volume-min 12 --volume-max 16
|
|
106
|
+
|
|
107
|
+
# Search generic text, including applicant/company names
|
|
108
|
+
cola colas list -q "molson coors"
|
|
105
109
|
|
|
106
110
|
# Pagination
|
|
107
111
|
cola colas list -q "bourbon" --limit 50 --page 2
|
|
@@ -117,14 +121,24 @@ cola colas list -q "whiskey" --json | jq '.data[].brand_name'
|
|
|
117
121
|
|
|
118
122
|
| Option | Description |
|
|
119
123
|
|--------|-------------|
|
|
120
|
-
| `-q, --query` |
|
|
121
|
-
| `--product-type` | Filter by type: `malt beverage`, `wine`, `distilled spirits
|
|
124
|
+
| `-q, --query` | Generic text query across brand, product, permit, applicant/company, and related text |
|
|
125
|
+
| `--product-type` | Filter by TTB type: `malt beverage`, `wine`, `distilled spirits`; can be used multiple times |
|
|
126
|
+
| `--category` | Filter by derived category: `Beer`, `Wine`, `Liquor`; can be used multiple times |
|
|
127
|
+
| `--derived-subcategory` | Filter by derived category path prefix, such as `Beer > Ale` |
|
|
122
128
|
| `--origin` | Filter by country/state |
|
|
129
|
+
| `--domestic-or-imported` | Filter by `domestic` or `imported` |
|
|
130
|
+
| `--status` | Filter by application status |
|
|
123
131
|
| `--brand` | Filter by brand name (partial match) |
|
|
132
|
+
| `--permit-number` | Filter by exact permit number |
|
|
133
|
+
| `--barcode` | Filter by exact main barcode value |
|
|
124
134
|
| `--date-from` | Minimum approval date (YYYY-MM-DD) |
|
|
125
135
|
| `--date-to` | Maximum approval date (YYYY-MM-DD) |
|
|
126
136
|
| `--abv-min` | Minimum ABV percentage |
|
|
127
137
|
| `--abv-max` | Maximum ABV percentage |
|
|
138
|
+
| `--volume-unit` | Package volume unit; required with `--volume-min` or `--volume-max` |
|
|
139
|
+
| `--volume-min` | Minimum package volume |
|
|
140
|
+
| `--volume-max` | Maximum package volume |
|
|
141
|
+
| `--container-type` | Derived container type; can be used multiple times |
|
|
128
142
|
| `--limit` | Results per page (max 100) |
|
|
129
143
|
| `--page` | Page number |
|
|
130
144
|
| `--json` | Output as JSON |
|
|
@@ -73,8 +73,12 @@ cola colas list --date-from 2024-01-01 --date-to 2024-12-31
|
|
|
73
73
|
# Filter by ABV
|
|
74
74
|
cola colas list --product-type "distilled spirits" --abv-min 40 --abv-max 50
|
|
75
75
|
|
|
76
|
-
#
|
|
77
|
-
cola colas list --
|
|
76
|
+
# Filter by package and derived category
|
|
77
|
+
cola colas list --category Beer --derived-subcategory "Beer > Ale" \
|
|
78
|
+
--container-type can --volume-unit "fluid ounces" --volume-min 12 --volume-max 16
|
|
79
|
+
|
|
80
|
+
# Search generic text, including applicant/company names
|
|
81
|
+
cola colas list -q "molson coors"
|
|
78
82
|
|
|
79
83
|
# Pagination
|
|
80
84
|
cola colas list -q "bourbon" --limit 50 --page 2
|
|
@@ -90,14 +94,24 @@ cola colas list -q "whiskey" --json | jq '.data[].brand_name'
|
|
|
90
94
|
|
|
91
95
|
| Option | Description |
|
|
92
96
|
|--------|-------------|
|
|
93
|
-
| `-q, --query` |
|
|
94
|
-
| `--product-type` | Filter by type: `malt beverage`, `wine`, `distilled spirits
|
|
97
|
+
| `-q, --query` | Generic text query across brand, product, permit, applicant/company, and related text |
|
|
98
|
+
| `--product-type` | Filter by TTB type: `malt beverage`, `wine`, `distilled spirits`; can be used multiple times |
|
|
99
|
+
| `--category` | Filter by derived category: `Beer`, `Wine`, `Liquor`; can be used multiple times |
|
|
100
|
+
| `--derived-subcategory` | Filter by derived category path prefix, such as `Beer > Ale` |
|
|
95
101
|
| `--origin` | Filter by country/state |
|
|
102
|
+
| `--domestic-or-imported` | Filter by `domestic` or `imported` |
|
|
103
|
+
| `--status` | Filter by application status |
|
|
96
104
|
| `--brand` | Filter by brand name (partial match) |
|
|
105
|
+
| `--permit-number` | Filter by exact permit number |
|
|
106
|
+
| `--barcode` | Filter by exact main barcode value |
|
|
97
107
|
| `--date-from` | Minimum approval date (YYYY-MM-DD) |
|
|
98
108
|
| `--date-to` | Maximum approval date (YYYY-MM-DD) |
|
|
99
109
|
| `--abv-min` | Minimum ABV percentage |
|
|
100
110
|
| `--abv-max` | Maximum ABV percentage |
|
|
111
|
+
| `--volume-unit` | Package volume unit; required with `--volume-min` or `--volume-max` |
|
|
112
|
+
| `--volume-min` | Minimum package volume |
|
|
113
|
+
| `--volume-max` | Maximum package volume |
|
|
114
|
+
| `--container-type` | Derived container type; can be used multiple times |
|
|
101
115
|
| `--limit` | Results per page (max 100) |
|
|
102
116
|
| `--page` | Page number |
|
|
103
117
|
| `--json` | Output as JSON |
|
|
@@ -181,26 +181,46 @@ class ColaCloudClient:
|
|
|
181
181
|
self,
|
|
182
182
|
query: str | None = None,
|
|
183
183
|
product_type: str | None = None,
|
|
184
|
+
category: str | None = None,
|
|
185
|
+
derived_subcategory: str | None = None,
|
|
184
186
|
origin: str | None = None,
|
|
187
|
+
domestic_or_imported: str | None = None,
|
|
188
|
+
status: str | None = None,
|
|
185
189
|
brand_name: str | None = None,
|
|
190
|
+
permit_number: str | None = None,
|
|
191
|
+
barcode_value: str | None = None,
|
|
186
192
|
approval_date_from: str | None = None,
|
|
187
193
|
approval_date_to: str | None = None,
|
|
188
194
|
abv_min: float | None = None,
|
|
189
195
|
abv_max: float | None = None,
|
|
196
|
+
volume_unit: str | None = None,
|
|
197
|
+
volume_min: float | None = None,
|
|
198
|
+
volume_max: float | None = None,
|
|
199
|
+
container_type: str | None = None,
|
|
190
200
|
page: int = 1,
|
|
191
201
|
per_page: int = 20,
|
|
192
202
|
) -> dict[str, Any]:
|
|
193
203
|
"""Search and filter COLAs.
|
|
194
204
|
|
|
195
205
|
Args:
|
|
196
|
-
query:
|
|
197
|
-
product_type: Filter by product
|
|
206
|
+
query: Text search query, including applicant/company names.
|
|
207
|
+
product_type: Filter by one or more TTB product types.
|
|
208
|
+
category: Filter by derived top-level category.
|
|
209
|
+
derived_subcategory: Filter by derived category path prefix.
|
|
198
210
|
origin: Filter by country/state.
|
|
211
|
+
domestic_or_imported: Filter by domestic/imported origin.
|
|
212
|
+
status: Filter by application status.
|
|
199
213
|
brand_name: Filter by brand name (partial match).
|
|
214
|
+
permit_number: Filter by exact permit number.
|
|
215
|
+
barcode_value: Filter by exact main barcode value.
|
|
200
216
|
approval_date_from: Filter by minimum approval date (YYYY-MM-DD).
|
|
201
217
|
approval_date_to: Filter by maximum approval date (YYYY-MM-DD).
|
|
202
218
|
abv_min: Filter by minimum ABV.
|
|
203
219
|
abv_max: Filter by maximum ABV.
|
|
220
|
+
volume_unit: Filter by volume unit. Required with volume_min/volume_max.
|
|
221
|
+
volume_min: Filter by minimum package volume.
|
|
222
|
+
volume_max: Filter by maximum package volume.
|
|
223
|
+
container_type: Filter by one or more derived container types.
|
|
204
224
|
page: Page number.
|
|
205
225
|
per_page: Results per page (max 100).
|
|
206
226
|
|
|
@@ -215,10 +235,22 @@ class ColaCloudClient:
|
|
|
215
235
|
params["q"] = query
|
|
216
236
|
if product_type:
|
|
217
237
|
params["product_type"] = product_type
|
|
238
|
+
if category:
|
|
239
|
+
params["category"] = category
|
|
240
|
+
if derived_subcategory:
|
|
241
|
+
params["derived_subcategory"] = derived_subcategory
|
|
218
242
|
if origin:
|
|
219
243
|
params["origin"] = origin
|
|
244
|
+
if domestic_or_imported:
|
|
245
|
+
params["domestic_or_imported"] = domestic_or_imported
|
|
246
|
+
if status:
|
|
247
|
+
params["status"] = status
|
|
220
248
|
if brand_name:
|
|
221
249
|
params["brand_name"] = brand_name
|
|
250
|
+
if permit_number:
|
|
251
|
+
params["permit_number"] = permit_number
|
|
252
|
+
if barcode_value:
|
|
253
|
+
params["barcode_value"] = barcode_value
|
|
222
254
|
if approval_date_from:
|
|
223
255
|
params["approval_date_from"] = approval_date_from
|
|
224
256
|
if approval_date_to:
|
|
@@ -227,6 +259,14 @@ class ColaCloudClient:
|
|
|
227
259
|
params["abv_min"] = abv_min
|
|
228
260
|
if abv_max is not None:
|
|
229
261
|
params["abv_max"] = abv_max
|
|
262
|
+
if volume_unit:
|
|
263
|
+
params["volume_unit"] = volume_unit
|
|
264
|
+
if volume_min is not None:
|
|
265
|
+
params["volume_min"] = volume_min
|
|
266
|
+
if volume_max is not None:
|
|
267
|
+
params["volume_max"] = volume_max
|
|
268
|
+
if container_type:
|
|
269
|
+
params["container_type"] = container_type
|
|
230
270
|
|
|
231
271
|
response = self._client.get("/colas", params=params)
|
|
232
272
|
return self._handle_response(response)
|
|
@@ -13,6 +13,12 @@ from colacloud_cli.formatters import (
|
|
|
13
13
|
)
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
def _join_multi(values: tuple[str, ...]) -> str | None:
|
|
17
|
+
parts = [part.strip() for value in values for part in value.split(",")]
|
|
18
|
+
joined = ",".join(part for part in parts if part)
|
|
19
|
+
return joined or None
|
|
20
|
+
|
|
21
|
+
|
|
16
22
|
@click.group(name="colas")
|
|
17
23
|
def colas_group():
|
|
18
24
|
"""Search and retrieve COLA records."""
|
|
@@ -23,13 +29,32 @@ def colas_group():
|
|
|
23
29
|
@click.option("-q", "--query", help="Full-text search query.")
|
|
24
30
|
@click.option(
|
|
25
31
|
"--product-type",
|
|
32
|
+
multiple=True,
|
|
26
33
|
type=click.Choice(
|
|
27
34
|
["malt beverage", "wine", "distilled spirits"], case_sensitive=False
|
|
28
35
|
),
|
|
29
|
-
help="Filter by product type.",
|
|
36
|
+
help="Filter by TTB product type. Can be used multiple times.",
|
|
37
|
+
)
|
|
38
|
+
@click.option(
|
|
39
|
+
"--category",
|
|
40
|
+
multiple=True,
|
|
41
|
+
type=click.Choice(["Beer", "Wine", "Liquor"], case_sensitive=False),
|
|
42
|
+
help="Filter by derived top-level category. Can be used multiple times.",
|
|
43
|
+
)
|
|
44
|
+
@click.option(
|
|
45
|
+
"--derived-subcategory",
|
|
46
|
+
help='Filter by derived category path prefix, e.g. "Beer > Ale".',
|
|
30
47
|
)
|
|
31
48
|
@click.option("--origin", help="Filter by origin (country/state).")
|
|
49
|
+
@click.option(
|
|
50
|
+
"--domestic-or-imported",
|
|
51
|
+
type=click.Choice(["domestic", "imported"], case_sensitive=False),
|
|
52
|
+
help="Filter by domestic/imported origin.",
|
|
53
|
+
)
|
|
54
|
+
@click.option("--status", help="Filter by application status.")
|
|
32
55
|
@click.option("--brand", "brand_name", help="Filter by brand name (partial match).")
|
|
56
|
+
@click.option("--permit-number", help="Filter by exact permit number.")
|
|
57
|
+
@click.option("--barcode", "barcode_value", help="Filter by exact main barcode value.")
|
|
33
58
|
@click.option(
|
|
34
59
|
"--date-from",
|
|
35
60
|
"approval_date_from",
|
|
@@ -42,6 +67,44 @@ def colas_group():
|
|
|
42
67
|
)
|
|
43
68
|
@click.option("--abv-min", type=float, help="Filter by minimum ABV.")
|
|
44
69
|
@click.option("--abv-max", type=float, help="Filter by maximum ABV.")
|
|
70
|
+
@click.option(
|
|
71
|
+
"--volume-unit",
|
|
72
|
+
type=click.Choice(
|
|
73
|
+
[
|
|
74
|
+
"beer barrels",
|
|
75
|
+
"fluid ounces",
|
|
76
|
+
"gallons",
|
|
77
|
+
"liters",
|
|
78
|
+
"milliliters",
|
|
79
|
+
"pints",
|
|
80
|
+
"quarts",
|
|
81
|
+
],
|
|
82
|
+
case_sensitive=False,
|
|
83
|
+
),
|
|
84
|
+
help="Filter by package volume unit. Required with --volume-min/--volume-max.",
|
|
85
|
+
)
|
|
86
|
+
@click.option("--volume-min", type=float, help="Filter by minimum package volume.")
|
|
87
|
+
@click.option("--volume-max", type=float, help="Filter by maximum package volume.")
|
|
88
|
+
@click.option(
|
|
89
|
+
"--container-type",
|
|
90
|
+
multiple=True,
|
|
91
|
+
type=click.Choice(
|
|
92
|
+
[
|
|
93
|
+
"bag",
|
|
94
|
+
"bottle",
|
|
95
|
+
"box",
|
|
96
|
+
"can",
|
|
97
|
+
"carton",
|
|
98
|
+
"cask",
|
|
99
|
+
"jug",
|
|
100
|
+
"keg",
|
|
101
|
+
"pod",
|
|
102
|
+
"pouch",
|
|
103
|
+
],
|
|
104
|
+
case_sensitive=False,
|
|
105
|
+
),
|
|
106
|
+
help="Filter by derived container type. Can be used multiple times.",
|
|
107
|
+
)
|
|
45
108
|
@click.option(
|
|
46
109
|
"--limit", "per_page", default=20, type=int, help="Results per page (max 100)."
|
|
47
110
|
)
|
|
@@ -49,13 +112,23 @@ def colas_group():
|
|
|
49
112
|
@click.option("--json", "as_json", is_flag=True, help="Output as JSON.")
|
|
50
113
|
def list_colas(
|
|
51
114
|
query: str | None,
|
|
52
|
-
product_type: str
|
|
115
|
+
product_type: tuple[str, ...],
|
|
116
|
+
category: tuple[str, ...],
|
|
117
|
+
derived_subcategory: str | None,
|
|
53
118
|
origin: str | None,
|
|
119
|
+
domestic_or_imported: str | None,
|
|
120
|
+
status: str | None,
|
|
54
121
|
brand_name: str | None,
|
|
122
|
+
permit_number: str | None,
|
|
123
|
+
barcode_value: str | None,
|
|
55
124
|
approval_date_from: str | None,
|
|
56
125
|
approval_date_to: str | None,
|
|
57
126
|
abv_min: float | None,
|
|
58
127
|
abv_max: float | None,
|
|
128
|
+
volume_unit: str | None,
|
|
129
|
+
volume_min: float | None,
|
|
130
|
+
volume_max: float | None,
|
|
131
|
+
container_type: tuple[str, ...],
|
|
59
132
|
per_page: int,
|
|
60
133
|
page: int,
|
|
61
134
|
as_json: bool,
|
|
@@ -69,28 +142,40 @@ def list_colas(
|
|
|
69
142
|
cola colas list -q "bourbon"
|
|
70
143
|
|
|
71
144
|
\b
|
|
72
|
-
# List
|
|
73
|
-
cola colas list --product-type wine --
|
|
145
|
+
# List wine or beer from California
|
|
146
|
+
cola colas list --product-type wine --product-type "malt beverage"
|
|
147
|
+
--origin california
|
|
74
148
|
|
|
75
149
|
\b
|
|
76
|
-
# Find
|
|
77
|
-
cola colas list --
|
|
150
|
+
# Find 12 oz canned beer
|
|
151
|
+
cola colas list --category Beer --container-type can
|
|
152
|
+
--volume-unit "fluid ounces" --volume-min 12 --volume-max 12
|
|
78
153
|
|
|
79
154
|
\b
|
|
80
|
-
# Search
|
|
81
|
-
cola colas list
|
|
155
|
+
# Search generic text, including applicant/company names
|
|
156
|
+
cola colas list -q "molson coors"
|
|
82
157
|
"""
|
|
83
158
|
try:
|
|
84
159
|
with get_client() as client:
|
|
85
160
|
result = client.list_colas(
|
|
86
161
|
query=query,
|
|
87
|
-
product_type=product_type,
|
|
162
|
+
product_type=_join_multi(product_type),
|
|
163
|
+
category=_join_multi(category),
|
|
164
|
+
derived_subcategory=derived_subcategory,
|
|
88
165
|
origin=origin,
|
|
166
|
+
domestic_or_imported=domestic_or_imported,
|
|
167
|
+
status=status,
|
|
89
168
|
brand_name=brand_name,
|
|
169
|
+
permit_number=permit_number,
|
|
170
|
+
barcode_value=barcode_value,
|
|
90
171
|
approval_date_from=approval_date_from,
|
|
91
172
|
approval_date_to=approval_date_to,
|
|
92
173
|
abv_min=abv_min,
|
|
93
174
|
abv_max=abv_max,
|
|
175
|
+
volume_unit=volume_unit,
|
|
176
|
+
volume_min=volume_min,
|
|
177
|
+
volume_max=volume_max,
|
|
178
|
+
container_type=_join_multi(container_type),
|
|
94
179
|
page=page,
|
|
95
180
|
per_page=min(per_page, 100),
|
|
96
181
|
)
|
|
@@ -494,6 +494,16 @@ def format_pagination(pagination: dict[str, Any], console: Console) -> None:
|
|
|
494
494
|
pages = pagination.get("pages", 1)
|
|
495
495
|
total = pagination.get("total", 0)
|
|
496
496
|
per_page = pagination.get("per_page", 20)
|
|
497
|
+
has_more = pagination.get("has_more")
|
|
498
|
+
|
|
499
|
+
if total is None:
|
|
500
|
+
msg = f"Showing page {page}"
|
|
501
|
+
if has_more is True:
|
|
502
|
+
msg += " (more results available)"
|
|
503
|
+
elif has_more is False:
|
|
504
|
+
msg += " (end of results)"
|
|
505
|
+
console.print(f"\n[dim]{msg}[/]")
|
|
506
|
+
return
|
|
497
507
|
|
|
498
508
|
# Calculate showing range
|
|
499
509
|
start = (page - 1) * per_page + 1
|
|
@@ -86,9 +86,19 @@ class TestListColas:
|
|
|
86
86
|
|
|
87
87
|
client.list_colas(
|
|
88
88
|
query="bourbon",
|
|
89
|
-
product_type="distilled spirits",
|
|
89
|
+
product_type="distilled spirits,wine",
|
|
90
|
+
category="Liquor,Wine",
|
|
91
|
+
derived_subcategory="Liquor > Whiskey",
|
|
90
92
|
origin="kentucky",
|
|
93
|
+
domestic_or_imported="domestic",
|
|
94
|
+
status="approved",
|
|
95
|
+
permit_number="KY-I-12345",
|
|
96
|
+
barcode_value="012345678905",
|
|
91
97
|
abv_min=40.0,
|
|
98
|
+
volume_unit="milliliters",
|
|
99
|
+
volume_min=375,
|
|
100
|
+
volume_max=750,
|
|
101
|
+
container_type="bottle,can",
|
|
92
102
|
)
|
|
93
103
|
|
|
94
104
|
request = route.calls[0].request
|
|
@@ -96,6 +106,16 @@ class TestListColas:
|
|
|
96
106
|
assert "product_type=distilled" in str(request.url)
|
|
97
107
|
assert "origin=kentucky" in str(request.url)
|
|
98
108
|
assert "abv_min=40" in str(request.url)
|
|
109
|
+
assert "category=Liquor%2CWine" in str(request.url)
|
|
110
|
+
assert "derived_subcategory=Liquor+%3E+Whiskey" in str(request.url)
|
|
111
|
+
assert "domestic_or_imported=domestic" in str(request.url)
|
|
112
|
+
assert "status=approved" in str(request.url)
|
|
113
|
+
assert "permit_number=KY-I-12345" in str(request.url)
|
|
114
|
+
assert "barcode_value=012345678905" in str(request.url)
|
|
115
|
+
assert "volume_unit=milliliters" in str(request.url)
|
|
116
|
+
assert "volume_min=375" in str(request.url)
|
|
117
|
+
assert "volume_max=750" in str(request.url)
|
|
118
|
+
assert "container_type=bottle%2Ccan" in str(request.url)
|
|
99
119
|
|
|
100
120
|
|
|
101
121
|
class TestGetCola:
|
|
@@ -44,7 +44,7 @@ class TestColasCommands:
|
|
|
44
44
|
@respx.mock
|
|
45
45
|
def test_colas_list(self, runner, api_key):
|
|
46
46
|
"""colas list returns results."""
|
|
47
|
-
respx.get("https://app.colacloud.us/api/v1/colas").mock(
|
|
47
|
+
route = respx.get("https://app.colacloud.us/api/v1/colas").mock(
|
|
48
48
|
return_value=httpx.Response(
|
|
49
49
|
200,
|
|
50
50
|
json={
|
|
@@ -67,9 +67,38 @@ class TestColasCommands:
|
|
|
67
67
|
)
|
|
68
68
|
)
|
|
69
69
|
|
|
70
|
-
result = runner.invoke(
|
|
70
|
+
result = runner.invoke(
|
|
71
|
+
cli,
|
|
72
|
+
[
|
|
73
|
+
"colas",
|
|
74
|
+
"list",
|
|
75
|
+
"-q",
|
|
76
|
+
"test",
|
|
77
|
+
"--product-type",
|
|
78
|
+
"wine",
|
|
79
|
+
"--product-type",
|
|
80
|
+
"malt beverage",
|
|
81
|
+
"--category",
|
|
82
|
+
"Beer",
|
|
83
|
+
"--container-type",
|
|
84
|
+
"can",
|
|
85
|
+
"--volume-unit",
|
|
86
|
+
"fluid ounces",
|
|
87
|
+
"--volume-min",
|
|
88
|
+
"12",
|
|
89
|
+
"--volume-max",
|
|
90
|
+
"16",
|
|
91
|
+
],
|
|
92
|
+
)
|
|
71
93
|
assert result.exit_code == 0
|
|
72
94
|
assert "Test Brand" in result.output
|
|
95
|
+
request_url = str(route.calls[0].request.url)
|
|
96
|
+
assert "product_type=wine%2Cmalt+beverage" in request_url
|
|
97
|
+
assert "category=Beer" in request_url
|
|
98
|
+
assert "container_type=can" in request_url
|
|
99
|
+
assert "volume_unit=fluid+ounces" in request_url
|
|
100
|
+
assert "volume_min=12" in request_url
|
|
101
|
+
assert "volume_max=16" in request_url
|
|
73
102
|
|
|
74
103
|
@respx.mock
|
|
75
104
|
def test_colas_list_json(self, runner, api_key):
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from rich.console import Console
|
|
2
|
+
|
|
3
|
+
from colacloud_cli.formatters import format_pagination
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def _render_pagination(pagination: dict) -> str:
|
|
7
|
+
console = Console(record=True, width=100)
|
|
8
|
+
format_pagination(pagination, console)
|
|
9
|
+
return console.export_text()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_format_pagination_handles_unknown_total_with_more_results():
|
|
13
|
+
output = _render_pagination(
|
|
14
|
+
{
|
|
15
|
+
"mode": "offset",
|
|
16
|
+
"page": 1,
|
|
17
|
+
"per_page": 3,
|
|
18
|
+
"total": None,
|
|
19
|
+
"pages": None,
|
|
20
|
+
"has_more": True,
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
assert "Showing page 1 (more results available)" in output
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_format_pagination_handles_unknown_total_at_end():
|
|
28
|
+
output = _render_pagination(
|
|
29
|
+
{
|
|
30
|
+
"mode": "offset",
|
|
31
|
+
"page": 2,
|
|
32
|
+
"per_page": 3,
|
|
33
|
+
"total": None,
|
|
34
|
+
"pages": None,
|
|
35
|
+
"has_more": False,
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
assert "Showing page 2 (end of results)" in output
|
|
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
|
{colacloud_cli-0.3.2 → colacloud_cli-0.3.4}/src/colacloud_cli/commands/production_reports.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|