walla-cli 0.1.8__tar.gz → 0.1.9__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.
- {walla_cli-0.1.8 → walla_cli-0.1.9}/PKG-INFO +13 -5
- {walla_cli-0.1.8 → walla_cli-0.1.9}/README.md +12 -4
- walla_cli-0.1.9/docs/assets/walla-demo-poster.jpg +0 -0
- walla_cli-0.1.9/docs/assets/walla-demo.mp4 +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/pyproject.toml +1 -1
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_sell.py +28 -0
- walla_cli-0.1.9/uv.lock +2644 -0
- walla_cli-0.1.9/walla/__init__.py +7 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/account/sell.py +31 -3
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/cli/banner.py +12 -8
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/cli/main.py +2 -3
- walla_cli-0.1.8/walla/__init__.py +0 -7
- {walla_cli-0.1.8 → walla_cli-0.1.9}/.cursor/rules/quality.mdc +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/.github/workflows/ci.yml +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/.gitignore +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/AGENTS.md +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/LICENSE +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/docs/WIRE.md +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/docs/assets/walla-github-banner.jpg +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/docs/code_quality.md +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/docs/data_engineering_standards.md +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/docs/mcp.md +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/docs/objective_function.md +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/docs/rate_limit_analysis.md +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/fixtures/categories.json +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/fixtures/item_detail.json +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/fixtures/offer_buyer_request.json +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/fixtures/search_bicicleta.json +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/fixtures/sell_item_request.json +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/fixtures/wire_contracts.json +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/scripts/check_code_quality.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/scripts/dogfood_run.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/scripts/probe_rate.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/skills/walla/SKILL.md +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/skills/walla-buy/SKILL.md +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/skills/walla-sell/SKILL.md +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_account.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_account_more.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_catch.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_chat_open.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_cli_json.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_core.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_desk.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_edges.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_export.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_http_more.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_live.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_negotiate.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_parsers.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_polite.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_regressions.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_search_api.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_session_store.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_shortlist.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_verdict.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/tests/test_wire_contracts.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/account/__init__.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/account/actions.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/account/chat.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/account/cookies.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/account/desk.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/account/inbox.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/account/login.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/account/offer_wire.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/account/prompt.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/account/sell_wire.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/account/session_store.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/cli/__init__.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/cli/catch.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/cli/cmd_account.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/cli/cmd_desk.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/cli/cmd_look.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/cli/cmd_ops.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/cli/cmd_sell.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/cli/console.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/core/__init__.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/core/envelope.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/core/errors.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/core/exceptions.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/core/human_fix.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/core/instruct.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/core/path.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/http/__init__.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/http/client.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/http/headers.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/http/polite.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/hunter/__init__.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/hunter/converge.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/hunter/export.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/hunter/export_pdf.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/hunter/negotiate.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/hunter/profile_store.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/hunter/pursuits.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/hunter/shortlist.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/hunter/stack.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/hunter/verdict.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/hunter/watches.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/mcp/__init__.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/mcp/_entry.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/mcp/server.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/models/__init__.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/models/account.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/models/listing.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/models/profile.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/search/__init__.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/search/api.py +0 -0
- {walla_cli-0.1.8 → walla_cli-0.1.9}/walla/search/parse.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: walla-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.9
|
|
4
4
|
Summary: Wallapop.es CLI - look · offer · talk · sell for humans and agents
|
|
5
5
|
Project-URL: Homepage, https://github.com/berendgort/wallapop-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/berendgort/wallapop-cli
|
|
@@ -55,12 +55,20 @@ Description-Content-Type: text/markdown
|
|
|
55
55
|
Dr. Berend Gort · www.berendgort.dev
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-

|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
Demo music: [Funkee Monkeee](https://mixkit.co/free-stock-music/funkee-monkeee-1140/) by Michael Ramir C.
|
|
61
|
+
([Mixkit Stock Music Free License](https://mixkit.co/license/#musicFree)).
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
**walla** turns Claude, GPT, or Cursor into a Wallapop helper that actually
|
|
64
|
+
*does* the work for you. You drop a few photos and answer a couple of
|
|
65
|
+
questions; the agent publishes the listing. When buyers message, it reads
|
|
66
|
+
the chats, replies for you, and negotiates down to your minimum price —
|
|
67
|
+
then shows you the best deal. You only open the Wallapop app to accept.
|
|
68
|
+
No typing chats. No babysitting the inbox.
|
|
69
|
+
|
|
70
|
+
Unofficial Wallapop.es CLI + MCP + Python library. Not affiliated with
|
|
71
|
+
Wallapop. Respect ToS and rate limits.
|
|
64
72
|
|
|
65
73
|
### What this unlocks
|
|
66
74
|
|
|
@@ -11,12 +11,20 @@
|
|
|
11
11
|
Dr. Berend Gort · www.berendgort.dev
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-

|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
Demo music: [Funkee Monkeee](https://mixkit.co/free-stock-music/funkee-monkeee-1140/) by Michael Ramir C.
|
|
17
|
+
([Mixkit Stock Music Free License](https://mixkit.co/license/#musicFree)).
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
**walla** turns Claude, GPT, or Cursor into a Wallapop helper that actually
|
|
20
|
+
*does* the work for you. You drop a few photos and answer a couple of
|
|
21
|
+
questions; the agent publishes the listing. When buyers message, it reads
|
|
22
|
+
the chats, replies for you, and negotiates down to your minimum price —
|
|
23
|
+
then shows you the best deal. You only open the Wallapop app to accept.
|
|
24
|
+
No typing chats. No babysitting the inbox.
|
|
25
|
+
|
|
26
|
+
Unofficial Wallapop.es CLI + MCP + Python library. Not affiliated with
|
|
27
|
+
Wallapop. Respect ToS and rate limits.
|
|
20
28
|
|
|
21
29
|
### What this unlocks
|
|
22
30
|
|
|
Binary file
|
|
Binary file
|
|
@@ -14,6 +14,7 @@ from walla.account.sell_wire import (
|
|
|
14
14
|
build_item_body,
|
|
15
15
|
missing_sell_fields,
|
|
16
16
|
)
|
|
17
|
+
from walla.core.exceptions import WallaHTTPError
|
|
17
18
|
|
|
18
19
|
ROOT = Path(__file__).resolve().parents[1]
|
|
19
20
|
FIXTURE = ROOT / "fixtures" / "sell_item_request.json"
|
|
@@ -130,6 +131,9 @@ def test_publish_listing_mocked(tmp_path: Path) -> None:
|
|
|
130
131
|
{"step": {"id": "listing"}},
|
|
131
132
|
]
|
|
132
133
|
fake_http.get.return_value = {}
|
|
134
|
+
listing = MagicMock()
|
|
135
|
+
listing.url = "https://es.wallapop.com/item/test-item-99"
|
|
136
|
+
listing.web_slug = "test-item-99"
|
|
133
137
|
with (
|
|
134
138
|
patch("walla.account.sell._auth_client", return_value=fake_http),
|
|
135
139
|
patch("walla.account.sell.upload_pictures", return_value=1),
|
|
@@ -137,6 +141,7 @@ def test_publish_listing_mocked(tmp_path: Path) -> None:
|
|
|
137
141
|
"walla.account.sell.create_listing",
|
|
138
142
|
return_value={"id": "abc123", "flags": {}},
|
|
139
143
|
),
|
|
144
|
+
patch("walla.account.sell.get_item", return_value=listing),
|
|
140
145
|
):
|
|
141
146
|
out = publish_listing(
|
|
142
147
|
[photo],
|
|
@@ -150,6 +155,7 @@ def test_publish_listing_mocked(tmp_path: Path) -> None:
|
|
|
150
155
|
)
|
|
151
156
|
assert out["id"] == "abc123"
|
|
152
157
|
assert out["photos"] == 1
|
|
158
|
+
assert out["url"] == "https://es.wallapop.com/item/test-item-99"
|
|
153
159
|
assert fake_http.post.call_count == 5
|
|
154
160
|
|
|
155
161
|
|
|
@@ -217,6 +223,9 @@ def test_publish_listing_two_photos(tmp_path: Path) -> None:
|
|
|
217
223
|
fake_resp.text = ""
|
|
218
224
|
fake_session = MagicMock()
|
|
219
225
|
fake_session.request.return_value = fake_resp
|
|
226
|
+
listing = MagicMock()
|
|
227
|
+
listing.url = "https://es.wallapop.com/item/test-item-99"
|
|
228
|
+
listing.web_slug = "test-item-99"
|
|
220
229
|
with (
|
|
221
230
|
patch("walla.account.sell._auth_client", return_value=fake_http),
|
|
222
231
|
patch("walla.account.sell.upload_pictures", return_value=2),
|
|
@@ -224,6 +233,7 @@ def test_publish_listing_two_photos(tmp_path: Path) -> None:
|
|
|
224
233
|
"walla.account.sell.create_listing",
|
|
225
234
|
return_value={"id": "abc123", "flags": {}},
|
|
226
235
|
),
|
|
236
|
+
patch("walla.account.sell.get_item", return_value=listing),
|
|
227
237
|
patch("walla.account.sell._auth_headers", return_value={}),
|
|
228
238
|
patch("walla.account.sell.requests.Session", return_value=fake_session),
|
|
229
239
|
patch("walla.account.sell.CurlMime") as mime_cls,
|
|
@@ -243,9 +253,27 @@ def test_publish_listing_two_photos(tmp_path: Path) -> None:
|
|
|
243
253
|
weight_kg=2,
|
|
244
254
|
)
|
|
245
255
|
assert out["photos"] == 2
|
|
256
|
+
assert out["url"] == "https://es.wallapop.com/item/test-item-99"
|
|
246
257
|
fake_session.request.assert_called()
|
|
247
258
|
|
|
248
259
|
|
|
260
|
+
def test_public_item_url_uses_slug_not_hash() -> None:
|
|
261
|
+
from walla.account.sell import _public_item_url
|
|
262
|
+
|
|
263
|
+
listing = MagicMock()
|
|
264
|
+
listing.url = ""
|
|
265
|
+
listing.web_slug = "escritorio-madera-1309402890"
|
|
266
|
+
with patch("walla.account.sell.get_item", return_value=listing):
|
|
267
|
+
assert _public_item_url("x6qq0n82pe6y").endswith(
|
|
268
|
+
"/item/escritorio-madera-1309402890"
|
|
269
|
+
)
|
|
270
|
+
with patch(
|
|
271
|
+
"walla.account.sell.get_item",
|
|
272
|
+
side_effect=WallaHTTPError("down", status_code=500),
|
|
273
|
+
):
|
|
274
|
+
assert _public_item_url("x6qq0n82pe6y").endswith("/item/x6qq0n82pe6y")
|
|
275
|
+
|
|
276
|
+
|
|
249
277
|
def test_assert_item_body_errors() -> None:
|
|
250
278
|
with pytest.raises(ValueError, match="missing"):
|
|
251
279
|
assert_item_body({})
|