Skip to content

Commit b5bb221

Browse files
authored
Refactor bunch size option (#241)
* Add page_size_option with legacy bunch_size support Switch from `--bunch-size` option to the meaningful option `--page-size`. The bunch size is now deprecated and will be removed some releases later. * Update CHANGELOG with new and deprecated options
1 parent 6e497fb commit b5bb221

File tree

2 files changed

+109
-10
lines changed

2 files changed

+109
-10
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66

77
## Unreleased
88

9+
# Added
10+
11+
- The `--page-size` option as a replacement for the now deprecated `--bunch-size` option.
12+
13+
##} Changed
14+
15+
- The `--bunch-size` option is now deprected and will be replaced with option `--page-size` some releases later.
16+
917
## [0.3.3] - 2025-08-14
1018

1119
### Added

src/audible_cli/decorators.py

Lines changed: 101 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import asyncio
22
import logging
33
from functools import partial, wraps
4+
from typing import Any, Callable
5+
from types import SimpleNamespace
46

57
import click
68
import httpx
9+
from click.core import Parameter, ParameterSource
710
from packaging.version import parse
811

912
from .config import Session
@@ -204,25 +207,113 @@ def callback(ctx: click.Context, param, value):
204207
return option
205208

206209

207-
def bunch_size_option(func=None, **kwargs):
210+
def page_size_option(
211+
func: Callable[..., Any] | None = None, **kwargs: Any
212+
) -> Callable[..., Any]:
213+
"""Create a Click option for page size with a legacy alias.
214+
215+
Adds a primary ``--page-size`` option and accepts the legacy
216+
``--bunch-size`` during a transition period. The value is validated to
217+
be within ``[10, 1000]``. If both flags are supplied, ``--page-size``
218+
takes precedence. The value is stored under both keys (``page_size``,
219+
``bunch_size``) to keep older commands compatible.
220+
"""
221+
# Primary option defaults
208222
kwargs.setdefault("type", click.IntRange(10, 1000))
209223
kwargs.setdefault("default", 1000)
210224
kwargs.setdefault("show_default", True)
225+
kwargs.setdefault("metavar", "[10-1000]")
211226
kwargs.setdefault(
212-
"help", ("How many library items should be requested per request. A "
213-
"lower size results in more requests to get the full library. "
214-
"A higher size can result in a TimeOutError on low internet "
215-
"connections.")
227+
"help",
228+
(
229+
"Number of items to request per API call (10–1000). Larger values "
230+
"reduce the number of requests but may cause timeouts or higher "
231+
"memory usage on slow connections. Tip: Use smaller values if you "
232+
"experience 408 timeouts or 429 rate limits."
233+
),
216234
)
217-
kwargs.setdefault("callback", add_param_to_session)
218-
kwargs.setdefault("expose_value", False)
219235

220-
option = click.option("--bunch-size", **kwargs)
236+
def _page_size_callback(
237+
ctx: click.Context, param: Parameter, value: int | None
238+
) -> None:
239+
"""Callback for ``--page-size``.
240+
241+
If the value came from the command line, always write it.
242+
If it's the default, only write it when the session does not already
243+
contain values (e.g., set by legacy ``--bunch-size``).
244+
"""
245+
if value is None:
246+
return
247+
248+
source = ctx.get_parameter_source("page_size")
249+
session = ctx.ensure_object(Session) # your app's Session
250+
251+
if source == ParameterSource.COMMANDLINE:
252+
# Explicit --page-size: always set/override.
253+
add_param_to_session(ctx, SimpleNamespace(name="page_size"), value)
254+
add_param_to_session(ctx, SimpleNamespace(name="bunch_size"), value)
255+
return
256+
257+
# Default value path: do not overwrite if legacy already populated.
258+
if "page_size" in session.params or "bunch_size" in session.params:
259+
# Skip to avoid clobbering a legacy value (or any pre-set value).
260+
return
261+
262+
# Neither key set yet → apply default to both keys.
263+
add_param_to_session(ctx, SimpleNamespace(name="page_size"), value)
264+
add_param_to_session(ctx, SimpleNamespace(name="bunch_size"), value)
265+
266+
kwargs["callback"] = _page_size_callback
267+
kwargs["expose_value"] = False
268+
269+
page_size = click.option("--page-size", **kwargs)
270+
271+
def _legacy_bunch_size_callback(
272+
ctx: click.Context, param: Parameter, value: int | None
273+
) -> None:
274+
"""Handle ``--bunch-size`` as a deprecated alias.
275+
276+
If ``--page-size`` was explicitly provided, ignore legacy and note it.
277+
Otherwise, store the legacy value under both keys and warn.
278+
"""
279+
if value is None:
280+
return
281+
282+
if ctx.get_parameter_source("page_size") == ParameterSource.COMMANDLINE:
283+
click.echo(
284+
"Note: --bunch-size is deprecated and ignored because --page-size was provided.",
285+
err=True,
286+
)
287+
return
288+
289+
click.echo(
290+
"Warning: --bunch-size is deprecated. Please use --page-size.",
291+
err=True,
292+
)
293+
add_param_to_session(ctx, SimpleNamespace(name="page_size"), value)
294+
add_param_to_session(ctx, SimpleNamespace(name="bunch_size"), value)
295+
296+
legacy = click.option(
297+
"--bunch-size",
298+
type=click.IntRange(10, 1000),
299+
default=None, # only active when explicitly provided
300+
hidden=True, # keep it out of --help
301+
callback=_legacy_bunch_size_callback,
302+
expose_value=False,
303+
)
304+
305+
def decorator(f: Callable[..., Any]) -> Callable[..., Any]:
306+
# Order doesn't matter now; guards in callbacks prevent overwrites.
307+
return page_size(legacy(f))
221308

222309
if callable(func):
223-
return option(func)
310+
return decorator(func)
224311

225-
return option
312+
return decorator
313+
314+
315+
# Backward-compat alias for old imports
316+
bunch_size_option = page_size_option
226317

227318

228319
def start_date_option(func=None, **kwargs):

0 commit comments

Comments
 (0)