walla-cli 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,204 @@
1
+ Metadata-Version: 2.5
2
+ Name: walla-cli
3
+ Version: 0.1.0
4
+ Summary: Wallapop.es CLI - look · offer · talk for humans and agents
5
+ Project-URL: Homepage, https://github.com/berendgort/wallapop-cli
6
+ Project-URL: Repository, https://github.com/berendgort/wallapop-cli
7
+ Project-URL: Issues, https://github.com/berendgort/wallapop-cli/issues
8
+ Author-email: "Dr. Berend Gort" <berend.gort@gmail.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: cli,marketplace,mcp,spain,wallapop
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Requires-Python: >=3.10
21
+ Requires-Dist: curl-cffi>=0.7.0
22
+ Requires-Dist: pydantic>=2.10.0
23
+ Requires-Dist: rich>=13.8.0
24
+ Requires-Dist: tenacity>=9.0.0
25
+ Requires-Dist: typer>=0.15.1
26
+ Provides-Extra: all
27
+ Requires-Dist: build>=1.2.0; extra == 'all'
28
+ Requires-Dist: fastmcp>=3.2; extra == 'all'
29
+ Requires-Dist: mcp>=1.2.0; extra == 'all'
30
+ Requires-Dist: mypy>=1.14.0; extra == 'all'
31
+ Requires-Dist: pytest-cov>=6.0.0; extra == 'all'
32
+ Requires-Dist: pytest>=8.3.4; extra == 'all'
33
+ Requires-Dist: ruff>=0.8.4; extra == 'all'
34
+ Provides-Extra: dev
35
+ Requires-Dist: build>=1.2.0; extra == 'dev'
36
+ Requires-Dist: mypy>=1.14.0; extra == 'dev'
37
+ Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
38
+ Requires-Dist: pytest>=8.3.4; extra == 'dev'
39
+ Requires-Dist: ruff>=0.8.4; extra == 'dev'
40
+ Provides-Extra: mcp
41
+ Requires-Dist: fastmcp>=3.2; extra == 'mcp'
42
+ Requires-Dist: mcp>=1.2.0; extra == 'mcp'
43
+ Description-Content-Type: text/markdown
44
+
45
+ # walla
46
+
47
+ ```
48
+ ██╗ ██╗ █████╗ ██╗ ██╗ █████╗ ██████╗ ██╗ ██╗
49
+ ██║ ██║ ██╔══██╗ ██║ ██║ ██╔══██╗ ██╔════╝ ██║ ██║
50
+ ██║ █╗ ██║ ███████║ ██║ ██║ ███████║ █████╗ ██║ ██║ ██║
51
+ ██║███╗██║ ██╔══██║ ██║ ██║ ██╔══██║ ╚════╝ ██║ ██║ ██║
52
+ ╚███╔███╔╝ ██║ ██║ ███████╗ ███████╗ ██║ ██║ ╚██████╗ ███████╗ ██║
53
+ ╚══╝╚══╝ ╚═╝ ╚═╝ ╚══════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═╝
54
+ look · offer · talk
55
+ Dr. Berend Gort · www.berendgort.dev
56
+ ```
57
+
58
+ ![walla banner](docs/assets/walla-github-banner.jpg)
59
+
60
+ **walla** is an unofficial Wallapop.es **CLI + MCP + Python library** for Cursor
61
+ agents and humans: search listings, read inbox, send a message, make an offer.
62
+
63
+ Not affiliated with Wallapop. Respect ToS and rate limits.
64
+
65
+ ### What this unlocks
66
+
67
+ You tell Cursor: *“Find me a used kite near Barcelona under €400, message
68
+ the seller, and offer if it’s a GRAB.”*
69
+
70
+ The agent runs `walla` — ranks listings **GRAB / LOOK / PASS**, links you the
71
+ item, asks before sending, then talks and offers on your behalf:
72
+
73
+ ```bash
74
+ walla setup --lat 41.39 --lon 2.17 --km 30 --label Barcelona --budget 400
75
+ walla search "tabla kite Cabrinha" --max 40 --json
76
+ # agent: GRAB · Cabrinha Moto 10m · €320 · 4 km
77
+ # https://es.wallapop.com/item/...
78
+
79
+ walla login # paste session cookie once
80
+ walla say <id> "Hola, ¿sigue disponible? Puedo pasar hoy." --yes
81
+ walla offer <id> --eur 280 --yes # prints total; needs your confirm
82
+ walla inbox --json # catch the reply
83
+ ```
84
+
85
+ That is the product: a Cursor agent that can **look, talk, and offer** on
86
+ Wallapop without opening the website for every step.
87
+
88
+ **Quality bar (enforced in CI):**
89
+
90
+ - [`docs/code_quality.md`](docs/code_quality.md) — Korotkevich / Tourist bar
91
+ - [`docs/data_engineering_standards.md`](docs/data_engineering_standards.md) — Gray / Stonebraker bar
92
+ - [`docs/WIRE.md`](docs/WIRE.md) — captured consumer API
93
+ - [`docs/rate_limit_analysis.md`](docs/rate_limit_analysis.md) — polite spacing
94
+
95
+ ---
96
+
97
+ ## For AI agents (mandatory protocol)
98
+
99
+ If the user pasted this GitHub link (or this README), **follow this section exactly**.
100
+
101
+ ### Goal
102
+
103
+ Look, offer, and talk on wallapop.es using the `walla` package. Speak briefly.
104
+ Link listings as `https://es.wallapop.com/item/<web_slug>`. Verdicts:
105
+ **GRAB / LOOK / PASS**.
106
+
107
+ ### Bootstrap
108
+
109
+ 1. Install from this clone:
110
+ ```bash
111
+ pipx install 'walla-cli[mcp]'
112
+ # from clone: pipx install -e '.[mcp]'
113
+ ```
114
+ 2. `walla doctor --json` — read `auth.session` and `network.reachable`.
115
+ **Never** print tokens or cookies.
116
+ 3. If no session: ask the human to run `walla login` and paste
117
+ `__Secure-next-auth.session-token` from es.wallapop.com (Cookie-Editor).
118
+ Agents may pass it non-interactively: `walla login --cookie '<value>' --json`.
119
+ 4. Do the ask with `walla … --json` and narrate in prose.
120
+
121
+ Optional MCP:
122
+
123
+ ```json
124
+ {
125
+ "mcpServers": {
126
+ "walla": { "command": "walla-mcp" }
127
+ }
128
+ }
129
+ ```
130
+
131
+ ### Operating loop
132
+
133
+ | Ask | Command |
134
+ |-----|---------|
135
+ | Look | `walla search "tabla kite" --max 40 --json` then `walla item <id> --json` |
136
+ | Talk | `walla inbox --json` · `walla thread <id> --json` · `walla say <id> "…" --yes` |
137
+ | Offer | `walla offer <id> --eur 180 --yes` |
138
+
139
+ Rules:
140
+
141
+ - Reads are safe. `say` / `offer` need `--yes` / `confirm=true`. Name listing + euros.
142
+ - If they only asked to look, do not send.
143
+ - Ambiguous match: ask once with candidates.
144
+ - In-person offers outside pickup radius: refuse.
145
+ - Envelope: `ok`, `api_version`, `data` or `error` / `error_type` / `retryable`.
146
+
147
+ `walla instruct --json` returns this recipe.
148
+
149
+ ---
150
+
151
+ ## Install
152
+
153
+ ```bash
154
+ git clone git@github.com:berendgort/wallapop-cli.git
155
+ cd wallapop-cli
156
+ pipx install 'walla-cli[mcp]' # or: pipx install -e '.[mcp]'
157
+ walla setup --lat 41.39 --lon 2.17 --km 30 --label Barcelona --json
158
+ walla login # paste __Secure-next-auth.session-token
159
+ walla doctor --json
160
+ ```
161
+
162
+ ## CLI
163
+
164
+ | Command | Role |
165
+ |---------|------|
166
+ | `walla setup` / `profile` | Home point, radius, budget |
167
+ | `walla search` / `item` / `categories` | Look |
168
+ | `walla watch add\|list\|check` | Local saved searches |
169
+ | `walla login` / `logout` / `whoami` | Session (paste cookie; optional `--password`) |
170
+ | `walla inbox` / `thread` / `say` | Talk |
171
+ | `walla offer` | Offer (prints total, needs `--yes`) |
172
+ | `walla fav list\|add\|rm` | Favorites |
173
+ | `walla instruct` / `doctor` | Agent recipe + health |
174
+
175
+ ## Develop
176
+
177
+ ```bash
178
+ pip install -e '.[dev,mcp]'
179
+ pytest -q -m 'not live'
180
+ pytest -m live # hits Wallapop; needs network
181
+ ruff check .
182
+ mypy walla
183
+ python scripts/check_code_quality.py
184
+ ```
185
+
186
+ | Layer | Path | Role |
187
+ |-------|------|------|
188
+ | Models | `walla/models/` | Pydantic only |
189
+ | HTTP | `walla/http/` | curl_cffi + polite |
190
+ | Core | `walla/core/` | Envelope, errors, human_fix |
191
+ | Search | `walla/search/` | Look |
192
+ | Account | `walla/account/` | Session, inbox, offer |
193
+ | Hunter | `walla/hunter/` | Profile, watches, verdicts |
194
+ | CLI / MCP | `walla/cli/` · `walla/mcp/` | Entrypoints |
195
+
196
+ Read [`AGENTS.md`](AGENTS.md) before extending.
197
+
198
+ ## Disclaimer
199
+
200
+ Unofficial. Not affiliated with Wallapop. Personal / research use.
201
+
202
+ ## License
203
+
204
+ MIT
@@ -0,0 +1,46 @@
1
+ walla/__init__.py,sha256=CyY4P8n33vxvTrs7-BxqV5pRvez9DvkXHo3ELPc8GA4,136
2
+ walla/account/__init__.py,sha256=IiEPza1OmTKtxc5ROaa180mxrNnbzuUSEnDr--63cew,642
3
+ walla/account/actions.py,sha256=JSI4Anj8wcbI4ZonkQ3DHE8t_58115fdC40wxm4WTMs,4437
4
+ walla/account/cookies.py,sha256=IfZQG-DtyFoFYvLutjeaWHEGiGGXW3WR7zI508p0h28,2985
5
+ walla/account/inbox.py,sha256=Kh7DoU3XPstas8Vq9iHzBJr26fHe7Q9AiSbGZCMzKJY,4983
6
+ walla/account/login.py,sha256=uyllsSH5nHPwqEvN8SmiA1xlQS6lC8Fe14nGnm-GNjg,7710
7
+ walla/account/prompt.py,sha256=vS7VE4O1P3HSrfXQSO9sWPbKxdzoHrvJq9MYjMisQOk,1678
8
+ walla/account/session_store.py,sha256=zV9BMkv5MzPL2e2iyXVWsh7Ib7tpRyy8VPDe4mGLsT0,904
9
+ walla/cli/__init__.py,sha256=FNjXRaqT2swXeycsAIinAnZef_EJVaOjD50x2bN8Mq4,118
10
+ walla/cli/banner.py,sha256=fL8_ysab0X0OTHzez-HwlB_wbTsVtrTBJ5uzXoFMDSM,1689
11
+ walla/cli/catch.py,sha256=35-UPkeLheC7VEul5IvNIb8zWcYG4lmAJ5rC2lYpiuE,1159
12
+ walla/cli/cmd_account.py,sha256=W17Czf9En0h5rqIMFxOJC-KpHAmT11UFaX3MHzLvobU,5510
13
+ walla/cli/cmd_look.py,sha256=PQUMCS73L6ZFbktxTWRrp8IhbJrrF_cVCVi8jOhMVY4,5041
14
+ walla/cli/cmd_ops.py,sha256=A5A2BF-KkjLTzj1zqolQoaeldcvPwSfvVrmghoNHqUQ,3477
15
+ walla/cli/console.py,sha256=x9tdiCTw2ObLkHVHSWPCCfZBnt361twI5Kd6XY636qo,150
16
+ walla/cli/main.py,sha256=9v_tpnpUdMz_T7rkwWN7fDojSG5CRQPK3b9MX0YRQkY,904
17
+ walla/core/__init__.py,sha256=kBMCGF-T8i7sZMhNFa8FfPKk3WxgyTScxbvOWAKeVIU,249
18
+ walla/core/envelope.py,sha256=fuOt-MePHLf_kjjOASo5tI5Rn52F501cSEEO5lAdrxU,1211
19
+ walla/core/errors.py,sha256=ecgLwF8Kj5CYBMu9qllKo6_xx55HOhtcJOPQ_PeoJNU,3125
20
+ walla/core/exceptions.py,sha256=9XvBg3UgeMdf1SMRG1cAEJ_uNBwq9_3j8o08qhHgnbo,1502
21
+ walla/core/human_fix.py,sha256=vO7cdP89QRsXGns2HA49V0h6kfxt_-iJX4-6h4QrGXQ,746
22
+ walla/core/instruct.py,sha256=q9fRmbm0FLpC6LtaSQyLQ2_cpbOHsM0DOecE27vPh90,1992
23
+ walla/core/path.py,sha256=e4mXBTWTWfo5CAnUCU_-dtc-aLKq2Qgx8oArIA4_IBg,639
24
+ walla/http/__init__.py,sha256=DOX7fh7rELVOAk79vOtbT17mzb2TP9ZvO8RYoBRzFMo,283
25
+ walla/http/client.py,sha256=jjW_hiddZVRUt0HJcZ56GHBR20Y9olyYYPgSlDPEPYI,4975
26
+ walla/http/headers.py,sha256=MvOlVb2AyXjogh_YR4sRsLjujqwLutEwX15paJgXBDg,835
27
+ walla/http/polite.py,sha256=mcFrM33rSUdFCnP-IGIoyhv9DQXGRmOU0tTmjthfQg8,3085
28
+ walla/hunter/__init__.py,sha256=Owth0gw66E-oB7fXfcFoD87UP-Mr3pkD8-1X0yrDgZM,443
29
+ walla/hunter/profile_store.py,sha256=pFP1-0RssJvhcqcSAEUEZHPQOWw2UPRrhoc4WLq3Tg4,1596
30
+ walla/hunter/verdict.py,sha256=aeB4188R96lY9hEy9gGNxhAODpd1S7CL3bIQyUWNAgk,1465
31
+ walla/hunter/watches.py,sha256=BQw-BaLd4iBE5O2jDstT_y5v1yndpa12B9ThdRAlWYU,1495
32
+ walla/mcp/__init__.py,sha256=wwkrAWL7wVgWdBpU7Ec8Ih-eiGZMcvQjtx5WwFvtc6E,130
33
+ walla/mcp/_entry.py,sha256=ZQwyTHjGsoHVOxIF7-Q_DSh-x1clsD-cLvMqAxMiVQ8,337
34
+ walla/mcp/server.py,sha256=ZhqEbkBo4CFpxdGplt7rX5IISItk6-I-OpvbnTQXr3s,4241
35
+ walla/models/__init__.py,sha256=aZpliNuyQ6ein3Racqulaq91Fcz1nWYM0_l7NodqN54,397
36
+ walla/models/account.py,sha256=vTzQQcDe32Q8ZlWNJlm2UBts4d7pZQs8ZMprl9LXiTo,997
37
+ walla/models/listing.py,sha256=7y9pEknX2POJYR9koczON87A5dcBbpqYseHflPOvzfw,1123
38
+ walla/models/profile.py,sha256=BIXrr7LldXYTtynHIQWafgwt7pLAeN3cD64v5mhO6sQ,774
39
+ walla/search/__init__.py,sha256=RxCmZLqpTs7UUdnCu3n57SZhoMi2BD817HJc6yLLTFg,349
40
+ walla/search/api.py,sha256=Ft8SQkMG9vxC1bXurR-Ix1SjHG9qeq-LgfkfPZkLV5I,2327
41
+ walla/search/parse.py,sha256=a6bv9pRntDWxuSeBMzZZa_pQSdG-HVD3YraIysRDb8k,5407
42
+ walla_cli-0.1.0.dist-info/METADATA,sha256=MWDX1jpPmAHGoPdUGNRUOzTV3dzUakPAgJ03jJPeqDA,7546
43
+ walla_cli-0.1.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
44
+ walla_cli-0.1.0.dist-info/entry_points.txt,sha256=HK9fabdyMSTUWLhfOLkmOBHsBWxPbJ1sxttV1v1bk3o,121
45
+ walla_cli-0.1.0.dist-info/licenses/LICENSE,sha256=DLgwTKF-cmcVGGzdAv6zze9YvY5df8hUywZdH5l4kik,1072
46
+ walla_cli-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.32.4
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ walla = walla.cli.main:cli
3
+ walla-mcp = walla.mcp._entry:run
4
+ walla-mcp-http = walla.mcp._entry:run_http
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dr. Berend Gort
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.