Skip to content

Commit 8645904

Browse files
Slim JSON output for agent-friendly context (~6x smaller)
Strip listings to essential fields (id, heading, price, location, url, date, brand) by default. Full API response available via --raw flag.
1 parent 223c69d commit 8645904

File tree

2 files changed

+28
-5
lines changed

2 files changed

+28
-5
lines changed

blocket_cli/cli.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ def main():
3030
@click.option("-n", "--limit", type=int, help="Max results to show")
3131
@click.option("-p", "--page", type=int, default=1, help="Page number")
3232
@click.option("-o", "--output", type=click.Choice(["table", "json", "jsonl"]), default="table", help="Output format")
33-
def search(query: str, location: str | None, category: str | None, price_min: int | None, price_max: int | None, sort: str | None, limit: int | None, page: int, output: str):
33+
@click.option("--raw", is_flag=True, help="Output full API response (default: slim agent-friendly fields)")
34+
def search(query: str, location: str | None, category: str | None, price_min: int | None, price_max: int | None, sort: str | None, limit: int | None, page: int, output: str, raw: bool):
3435
"""Search listings on Blocket.
3536
3637
\b
@@ -46,7 +47,7 @@ def search(query: str, location: str | None, category: str | None, price_min: in
4647
price_min=price_min, price_max=price_max,
4748
sort=sort_map.get(sort, sort) if sort else None, page=page,
4849
)
49-
format.print_results(data, output=output, limit=limit)
50+
format.print_results(data, output=output, limit=limit, raw=raw)
5051
except Exception as e:
5152
click.echo(f"Error: {e}", err=True)
5253
sys.exit(1)

blocket_cli/format.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,35 @@
44

55
import json
66
import sys
7+
from datetime import datetime, timezone
78
from typing import Any
89

910

1011
def _json_compact(data: Any) -> str:
1112
return json.dumps(data, ensure_ascii=False, separators=(",", ":"))
1213

1314

14-
def print_results(data: dict, *, output: str = "table", limit: int | None = None) -> None:
15+
def _slim(doc: dict) -> dict:
16+
"""Strip a listing to agent-essential fields."""
17+
price = doc.get("price", {})
18+
out: dict[str, Any] = {
19+
"id": doc.get("id"),
20+
"heading": doc.get("heading"),
21+
"price": price.get("amount"),
22+
"currency": price.get("currency_code", "SEK"),
23+
"location": doc.get("location"),
24+
"url": doc.get("canonical_url"),
25+
}
26+
ts = doc.get("timestamp")
27+
if ts:
28+
out["date"] = datetime.fromtimestamp(ts / 1000, tz=timezone.utc).strftime("%Y-%m-%d")
29+
for extra in doc.get("extras", []):
30+
if extra.get("id") == "brand" and extra.get("values"):
31+
out["brand"] = extra["values"][0]
32+
return out
33+
34+
35+
def print_results(data: dict, *, output: str = "table", limit: int | None = None, raw: bool = False) -> None:
1536
"""Print search results."""
1637
docs = data.get("docs", [])
1738
total = data.get("metadata", {}).get("result_size", {}).get("match_count", len(docs))
@@ -20,12 +41,13 @@ def print_results(data: dict, *, output: str = "table", limit: int | None = None
2041
docs = docs[:limit]
2142

2243
if output == "json":
23-
print(_json_compact({"total": total, "results": docs}))
44+
results = docs if raw else [_slim(d) for d in docs]
45+
print(_json_compact({"total": total, "results": results}))
2446
return
2547

2648
if output == "jsonl":
2749
for doc in docs:
28-
print(_json_compact(doc))
50+
print(_json_compact(doc if raw else _slim(doc)))
2951
return
3052

3153
if not docs:

0 commit comments

Comments
 (0)