scrapebadger-cli 0.24.2__tar.gz → 0.25.0__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.
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/PKG-INFO +1 -1
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/pyproject.toml +1 -1
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/facebook.py +31 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/perplexity.py +33 -11
- scrapebadger_cli-0.25.0/tests/test_perplexity_strict_country.py +36 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/uv.lock +1 -1
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/.gitignore +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/README.md +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/__init__.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/client.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/__init__.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/agent.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/airbnb.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/aliexpress.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/amazon.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/apartments.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/app_store.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/asos.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/auth.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/baidu.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/bestbuy.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/bing.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/booking.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/chatgpt.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/depop.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/duckduckgo.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/ebay.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/etsy.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/gemini.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/google.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/google_play.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/gumtree.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/idealista.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/immobiliare.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/init.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/instagram.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/leboncoin.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/linkedin.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/loopnet.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/naver.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/onboarding.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/realtor.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/reddit.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/redfin.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/stream.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/target.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/tiktok.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/twitter.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/vinted.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/wallapop.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/walmart.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/web.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/yahoo.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/yandex.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/youtube.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/zillow.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/config.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/main.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/output.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/results.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/views.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/tests/test_agent_features.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/tests/test_google_light_search.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/tests/test_naver.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/tests/test_tiktok_pagination.py +0 -0
- {scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/tests/test_vinted_image_search.py +0 -0
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/facebook.py
RENAMED
|
@@ -112,6 +112,37 @@ def locations(
|
|
|
112
112
|
render(data, fmt, fields)
|
|
113
113
|
|
|
114
114
|
|
|
115
|
+
@app.command(name="resolve-location")
|
|
116
|
+
def resolve_location(
|
|
117
|
+
query: str | None = typer.Argument(
|
|
118
|
+
None, help="Town, city, postcode or address (e.g. 'Durham', 'DH1 3LE')"
|
|
119
|
+
),
|
|
120
|
+
latitude: float | None = typer.Option(None, "--lat", help="Resolve this point instead"),
|
|
121
|
+
longitude: float | None = typer.Option(None, "--lng"),
|
|
122
|
+
country: str | None = typer.Option(
|
|
123
|
+
None, "--country", help="ISO country hint for an ambiguous name (e.g. gb)"
|
|
124
|
+
),
|
|
125
|
+
fmt: str = FMT,
|
|
126
|
+
fields: str | None = FIELDS,
|
|
127
|
+
) -> None:
|
|
128
|
+
"""Resolve a town/postcode/coordinates to a Marketplace location id (free).
|
|
129
|
+
|
|
130
|
+
Pass the returned place_id as --location on marketplace-search/category.
|
|
131
|
+
"""
|
|
132
|
+
params = {
|
|
133
|
+
k: v
|
|
134
|
+
for k, v in {
|
|
135
|
+
"query": query,
|
|
136
|
+
"latitude": latitude,
|
|
137
|
+
"longitude": longitude,
|
|
138
|
+
"country": country,
|
|
139
|
+
}.items()
|
|
140
|
+
if v is not None
|
|
141
|
+
}
|
|
142
|
+
data = api_get("/v1/facebook/marketplace/locations/resolve", params)
|
|
143
|
+
render(data, fmt, fields)
|
|
144
|
+
|
|
145
|
+
|
|
115
146
|
@app.command()
|
|
116
147
|
def categories(
|
|
117
148
|
fmt: str = FMT,
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/perplexity.py
RENAMED
|
@@ -10,20 +10,38 @@ app = typer.Typer(no_args_is_help=True)
|
|
|
10
10
|
FMT = typer.Option("json", "--output", "-o", help="Output format: json, csv, table, markdown")
|
|
11
11
|
FIELDS = typer.Option(None, "--fields", "-f", help="Comma-separated fields to include")
|
|
12
12
|
COUNTRY = typer.Option("US", "--country", "-c", help="ISO-3166 alpha-2 egress country")
|
|
13
|
+
ASK_COUNTRY = typer.Option(
|
|
14
|
+
"US",
|
|
15
|
+
"--country",
|
|
16
|
+
"-c",
|
|
17
|
+
help="ISO-3166 alpha-2 market. Best-effort: another market may answer "
|
|
18
|
+
"(the response `country` says which) unless --strict-country is set",
|
|
19
|
+
)
|
|
20
|
+
STRICT = typer.Option(
|
|
21
|
+
False,
|
|
22
|
+
"--strict-country",
|
|
23
|
+
help="Answer only from an exit in --country; fails with 503 country_unavailable "
|
|
24
|
+
"(not billed) when none answers in time",
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _strict(params: dict, strict_country: bool) -> dict:
|
|
29
|
+
return {**params, "strict_country": True} if strict_country else params
|
|
13
30
|
|
|
14
31
|
|
|
15
32
|
@app.command()
|
|
16
33
|
def ask(
|
|
17
34
|
prompt: str = typer.Argument(..., help="Prompt to send to perplexity.ai (max 4096 chars)"),
|
|
18
|
-
country: str =
|
|
35
|
+
country: str = ASK_COUNTRY,
|
|
19
36
|
focus: str = typer.Option("web", "--focus", help="Retrieval focus: web, scholar or social"),
|
|
37
|
+
strict_country: bool = STRICT,
|
|
20
38
|
fmt: str = FMT,
|
|
21
39
|
fields: str | None = FIELDS,
|
|
22
40
|
) -> None:
|
|
23
41
|
"""Ask the real perplexity.ai and get the grounded answer with its cited sources."""
|
|
24
42
|
data = api_get(
|
|
25
43
|
"/v1/perplexity/ask",
|
|
26
|
-
{"prompt": prompt, "country": country, "focus": focus},
|
|
44
|
+
_strict({"prompt": prompt, "country": country, "focus": focus}, strict_country),
|
|
27
45
|
)
|
|
28
46
|
render(data, fmt, fields)
|
|
29
47
|
|
|
@@ -39,21 +57,25 @@ def brand_visibility(
|
|
|
39
57
|
competitors: str | None = typer.Option(
|
|
40
58
|
None, "--competitors", help="Comma-separated competitor names"
|
|
41
59
|
),
|
|
42
|
-
country: str =
|
|
60
|
+
country: str = ASK_COUNTRY,
|
|
61
|
+
strict_country: bool = STRICT,
|
|
43
62
|
fmt: str = FMT,
|
|
44
63
|
fields: str | None = FIELDS,
|
|
45
64
|
) -> None:
|
|
46
65
|
"""Score how a brand appears in a real Perplexity answer (AEO/GEO)."""
|
|
47
66
|
data = api_get(
|
|
48
67
|
"/v1/perplexity/brand-visibility",
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
68
|
+
_strict(
|
|
69
|
+
{
|
|
70
|
+
"prompt": prompt,
|
|
71
|
+
"brand": brand,
|
|
72
|
+
"domain": domain,
|
|
73
|
+
"aliases": aliases,
|
|
74
|
+
"competitors": competitors,
|
|
75
|
+
"country": country,
|
|
76
|
+
},
|
|
77
|
+
strict_country,
|
|
78
|
+
),
|
|
57
79
|
)
|
|
58
80
|
render(data, fmt, fields)
|
|
59
81
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from unittest.mock import Mock
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
CliRunner = pytest.importorskip("typer.testing").CliRunner
|
|
6
|
+
perplexity = pytest.importorskip(
|
|
7
|
+
"scrapebadger_cli.commands.perplexity", reason="CLI is tested with its own installed package"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _invoke(monkeypatch, args):
|
|
12
|
+
call = Mock(return_value={})
|
|
13
|
+
monkeypatch.setattr(perplexity, "api_get", call)
|
|
14
|
+
monkeypatch.setattr(perplexity, "render", Mock())
|
|
15
|
+
result = CliRunner().invoke(perplexity.app, args)
|
|
16
|
+
assert result.exit_code == 0, result.output
|
|
17
|
+
return call.call_args.args
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_ask_omits_strict_country_by_default(monkeypatch):
|
|
21
|
+
path, params = _invoke(monkeypatch, ["ask", "q", "--country", "DE"])
|
|
22
|
+
assert path == "/v1/perplexity/ask"
|
|
23
|
+
assert params["country"] == "DE" and "strict_country" not in params
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_ask_strict_country(monkeypatch):
|
|
27
|
+
_, params = _invoke(monkeypatch, ["ask", "q", "--country", "DE", "--strict-country"])
|
|
28
|
+
assert params["strict_country"] is True
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_brand_strict_country(monkeypatch):
|
|
32
|
+
path, params = _invoke(
|
|
33
|
+
monkeypatch, ["brand", "q", "--brand", "Nike", "-c", "JP", "--strict-country"]
|
|
34
|
+
)
|
|
35
|
+
assert path == "/v1/perplexity/brand-visibility"
|
|
36
|
+
assert params["strict_country"] is True and params["country"] == "JP"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/aliexpress.py
RENAMED
|
File without changes
|
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/apartments.py
RENAMED
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/app_store.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/bestbuy.py
RENAMED
|
File without changes
|
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/booking.py
RENAMED
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/chatgpt.py
RENAMED
|
File without changes
|
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/duckduckgo.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/google_play.py
RENAMED
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/gumtree.py
RENAMED
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/idealista.py
RENAMED
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/immobiliare.py
RENAMED
|
File without changes
|
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/instagram.py
RENAMED
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/leboncoin.py
RENAMED
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/linkedin.py
RENAMED
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/loopnet.py
RENAMED
|
File without changes
|
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/onboarding.py
RENAMED
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/realtor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/twitter.py
RENAMED
|
File without changes
|
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/wallapop.py
RENAMED
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/walmart.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scrapebadger_cli-0.24.2 → scrapebadger_cli-0.25.0}/src/scrapebadger_cli/commands/youtube.py
RENAMED
|
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
|