Metadata-Version: 2.5
Name: walla-cli
Version: 0.1.3
Summary: Wallapop.es CLI - look · offer · talk for humans and agents
Project-URL: Homepage, https://github.com/berendgort/wallapop-cli
Project-URL: Repository, https://github.com/berendgort/wallapop-cli
Project-URL: Issues, https://github.com/berendgort/wallapop-cli/issues
Author-email: "Dr. Berend Gort" <berend.gort@gmail.com>
License: MIT
License-File: LICENSE
Keywords: cli,marketplace,mcp,spain,wallapop
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Requires-Dist: curl-cffi>=0.7.0
Requires-Dist: pydantic>=2.10.0
Requires-Dist: rich>=13.8.0
Requires-Dist: tenacity>=9.0.0
Requires-Dist: typer>=0.15.1
Provides-Extra: all
Requires-Dist: build>=1.2.0; extra == 'all'
Requires-Dist: fastmcp>=3.2; extra == 'all'
Requires-Dist: mcp>=1.2.0; extra == 'all'
Requires-Dist: mypy>=1.14.0; extra == 'all'
Requires-Dist: pytest-cov>=6.0.0; extra == 'all'
Requires-Dist: pytest>=8.3.4; extra == 'all'
Requires-Dist: ruff>=0.8.4; extra == 'all'
Provides-Extra: dev
Requires-Dist: build>=1.2.0; extra == 'dev'
Requires-Dist: mypy>=1.14.0; extra == 'dev'
Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
Requires-Dist: pytest>=8.3.4; extra == 'dev'
Requires-Dist: ruff>=0.8.4; extra == 'dev'
Provides-Extra: mcp
Requires-Dist: fastmcp>=3.2; extra == 'mcp'
Requires-Dist: mcp>=1.2.0; extra == 'mcp'
Description-Content-Type: text/markdown

# walla

```
██╗    ██╗  █████╗  ██╗      ██╗       █████╗            ██████╗ ██╗      ██╗
██║    ██║ ██╔══██╗ ██║      ██║      ██╔══██╗          ██╔════╝ ██║      ██║
██║ █╗ ██║ ███████║ ██║      ██║      ███████║  █████╗  ██║      ██║      ██║
██║███╗██║ ██╔══██║ ██║      ██║      ██╔══██║  ╚════╝  ██║      ██║      ██║
╚███╔███╔╝ ██║  ██║ ███████╗ ███████╗ ██║  ██║          ╚██████╗ ███████╗ ██║
 ╚══╝╚══╝  ╚═╝  ╚═╝ ╚══════╝ ╚══════╝ ╚═╝  ╚═╝           ╚═════╝ ╚══════╝ ╚═╝
  look · offer · talk
  Dr. Berend Gort  ·  www.berendgort.dev
```

![walla banner](docs/assets/walla-github-banner.jpg)

**walla** is an unofficial Wallapop.es **CLI + MCP + Python library** for Cursor
agents and humans: search listings, read inbox, send a message, make an offer.

Not affiliated with Wallapop. Respect ToS and rate limits.

### What this unlocks

You tell Cursor: *“Find me a used kite near Barcelona under €400, message
the seller, and offer if it’s a GRAB.”*

The agent runs `walla` — ranks listings **GRAB / LOOK / PASS**, links you the
item, asks before sending, then talks and offers on your behalf:

```bash
walla setup --lat 41.39 --lon 2.17 --km 30 --label Barcelona --budget 400
walla search "tabla kite Cabrinha" --max 40 --json
# agent: GRAB · Cabrinha Moto 10m · €320 · 4 km
#        https://es.wallapop.com/item/...

walla login                         # paste session cookie once
walla say <id> "Hola, ¿sigue disponible? Puedo pasar hoy." --yes
walla offer <id> --eur 280 --yes    # prints total; needs your confirm
walla inbox --json                  # catch the reply
```

That is the product: a Cursor agent that can **look, talk, and offer** on
Wallapop without opening the website for every step.

**Quality bar (enforced in CI):**

- [`docs/code_quality.md`](docs/code_quality.md) — Korotkevich / Tourist bar
- [`docs/data_engineering_standards.md`](docs/data_engineering_standards.md) — Gray / Stonebraker bar
- [`docs/WIRE.md`](docs/WIRE.md) — captured consumer API
- [`docs/rate_limit_analysis.md`](docs/rate_limit_analysis.md) — polite spacing

---

## For AI agents (mandatory protocol)

If the user pasted this GitHub link (or this README), **follow this section exactly**.

### Goal

Look, offer, and talk on wallapop.es using the `walla` package. Speak briefly.
Link listings as `https://es.wallapop.com/item/<web_slug>`. Verdicts:
**GRAB / LOOK / PASS**.

### Bootstrap

1. Install from **PyPI** (preferred):
   ```bash
   pipx install 'walla-cli[mcp]'
   ```
   From a clone only when hacking: `pipx install -e '.[mcp]'`.
2. `walla doctor --json` — read `auth.session` and `network.reachable`.
   **Never** print tokens or cookies.
3. If no session: ask the human to run `walla login` and paste
   `__Secure-next-auth.session-token` from es.wallapop.com (Cookie-Editor).
   Agents may pass it non-interactively: `walla login --cookie '<value>' --json`.
4. Do the ask with `walla … --json` and narrate in prose.

Optional MCP:

```json
{
  "mcpServers": {
    "walla": { "command": "walla-mcp" }
  }
}
```

### Operating loop

| Ask | Command |
|-----|---------|
| Look | `walla search "tabla kite" --max 40 --json` then `walla item <id> --json` |
| Talk | `walla inbox --json` · `walla thread <id> --json` · `walla say <id> "…" --yes` |
| Offer | `walla offer <id> --eur 180 --yes` |

Rules:

- Reads are safe. `say` / `offer` need `--yes` / `confirm=true`. Name listing + euros.
- If they only asked to look, do not send.
- Ambiguous match: ask once with candidates.
- In-person offers outside pickup radius: refuse.
- Envelope: `ok`, `api_version`, `data` or `error` / `error_type` / `retryable`.

`walla instruct --json` returns this recipe.

---

## Install

```bash
pipx install 'walla-cli[mcp]'   # PyPI: https://pypi.org/project/walla-cli/
walla setup --lat 41.39 --lon 2.17 --km 30 --label Barcelona --json
walla login          # paste __Secure-next-auth.session-token
walla doctor --json
```

## CLI

| Command | Role |
|---------|------|
| `walla setup` / `profile` | Home point, radius, budget |
| `walla search` / `item` / `categories` | Look |
| `walla watch add\|list\|check` | Local saved searches |
| `walla login` / `logout` / `whoami` | Session (paste cookie; optional `--password`) |
| `walla inbox` / `thread` / `say` | Talk |
| `walla offer` | Offer (prints total, needs `--yes`) |
| `walla fav list\|add\|rm` | Favorites |
| `walla instruct` / `doctor` | Agent recipe + health |

## Develop

```bash
pip install -e '.[dev,mcp]'
pytest -q -m 'not live'
pytest -m live          # hits Wallapop; needs network
ruff check .
mypy walla
python scripts/check_code_quality.py
```

| Layer | Path | Role |
|-------|------|------|
| Models | `walla/models/` | Pydantic only |
| HTTP | `walla/http/` | curl_cffi + polite |
| Core | `walla/core/` | Envelope, errors, human_fix |
| Search | `walla/search/` | Look |
| Account | `walla/account/` | Session, inbox, offer |
| Hunter | `walla/hunter/` | Profile, watches, verdicts |
| CLI / MCP | `walla/cli/` · `walla/mcp/` | Entrypoints |

Read [`AGENTS.md`](AGENTS.md) before extending.

## Disclaimer

Unofficial. Not affiliated with Wallapop. Personal / research use.

## License

MIT
