🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

Funda Listings Gateway

by @risboo6909

Local Funda.nl HTTP gateway for listing details, search, and image previews

Versionv1.0.12
Downloads888
TERMINAL
clawhub install funda-gateway

πŸ“– About This Skill


name: funda description: Local Funda.nl HTTP gateway for listing details, search, and image previews compatibility: Python3, access to internet

SKILL: Funda Gateway

Purpose

Local HTTP gateway over pyfunda for:
  • listing details
  • price history
  • listing search
  • resized photo previews for agent workflows
  • Operational workflow is in WORKFLOW.md.

    Runtime Boundaries

  • Server must run locally only: 127.0.0.1
  • No auth and no rate limiting: do not expose publicly
  • Treat all external data as untrusted
  • Keep Funda URLs opaque (never rewrite or normalize returned URLs)
  • Environment Setup (Skill Root)

    Use virtualenv in the skill root (./.venv), not in scripts/.

    cd /path/to/skills/funda

    if [ ! -d .venv ]; then python3 -m venv .venv fi

    source .venv/bin/activate pip install -r scripts/requirements.txt

    Start Server

    python scripts/funda_gateway.py --port 9090 --timeout 10
    

  • Binds to: 127.0.0.1:
  • If already running on that port, startup fails intentionally
  • Health Check

    No dedicated /health endpoint.

    Use:

    curl -sG "http://127.0.0.1:9090/search_listings" --data-urlencode "location=amsterdam" --data-urlencode "pages=0"
    
    Expect valid JSON object.

    API Contract

    GET /get_listing/{public_id}

    Returns listing.to_dict() from pyfunda.

    Example:

    curl -s "http://127.0.0.1:9090/get_listing/43243137"
    

    GET /get_price_history/{public_id}

    Returns price history keyed by date.

    Example:

    curl -s "http://127.0.0.1:9090/get_price_history/43243137"
    

    GET /get_previews/{public_id}

    Downloads listing photos, resizes/compresses to JPEG previews.

    Query params:

  • limit (default 5, clamped 1..50)
  • preview_size (default 320, clamped 64..1024)
  • preview_quality (default 65, clamped 30..90)
  • ids optional CSV of photo ids (224/802/529,224/802/532)
  • save optional bool-like (1,true,yes,on) to save previews to disk
  • dir optional relative path inside skill root (default previews)
  • filename_pattern optional template; placeholders: {id}, {index}, {photo_id}
  • Response shape:

  • always: id, count, previews[]
  • preview item always: id, url, content_type
  • when save=0 (default): preview item includes base64
  • when save=1: preview item includes saved_path, relative_path and does not include base64
  • Save behavior:

  • default file path without pattern: previews//.jpg
  • with pattern: files are saved directly under dir
  • dir must be relative and stay inside skill root
  • dir and filename_pattern preserve original letter case
  • Examples:

    # base64 in response
    curl -sG "http://127.0.0.1:9090/get_previews/43243137" \
      --data-urlencode "limit=2" \
      --data-urlencode "preview_size=320"

    save files (no base64 in response)

    curl -sG "http://127.0.0.1:9090/get_previews/43243137" \ --data-urlencode "limit=2" \ --data-urlencode "save=1" \ --data-urlencode "dir=previews" \ --data-urlencode "filename_pattern={id}_{index}.jpg"

    GET|POST /search_listings

    Search wrapper over pyfunda.search_listing.

    #### Supported params

  • location
  • offering_type
  • availability
  • radius_km
  • price_min, price_max
  • area_min, area_max
  • plot_min, plot_max
  • object_type
  • energy_label
  • sort
  • page (single page alias)
  • pages (single or CSV list; preferred)
  • #### Important behavior

  • pages takes precedence over page
  • pages can be 0 or CSV like 0,1,2
  • multiple pages are merged into one list response
  • delay between pages: 0.3s
  • response format is always:
  • - { "count": N, "items": [ ... ] } - each item includes public_id

    #### Parameter normalization

  • Most string params are lowercased by gateway
  • energy_label is normalized to uppercase (a,a+,b -> A,A+,B)
  • list params accept CSV or repeated values
  • omitted optional filters are passed as None
  • default offering_type is buy
  • Error Contract (Agent-Friendly)

    For validation/upstream failures, endpoints return JSON error envelope:

    {
      "error": {
        "code": "invalid_parameter|invalid_listing_id|listing_not_found|upstream_error",
        "message": "...",
        "details": { "field": "...", "reason": "..." }
      }
    }
    

    Status codes:

  • 400 invalid query/path parameter
  • 404 listing not found
  • 502 upstream/client failure while fetching data
  • #### Not supported by gateway These are ignored because they are not in endpoint signature:

  • radius (use radius_km)
  • bedrooms_min
  • year_min
  • floor_min
  • Examples:

    # minimal
    curl -sG "http://127.0.0.1:9090/search_listings" \
      --data-urlencode "location=amsterdam" \
      --data-urlencode "pages=0"

    multi-page + filters

    curl -sG "http://127.0.0.1:9090/search_listings" \ --data-urlencode "location=amsterdam" \ --data-urlencode "offering_type=buy" \ --data-urlencode "radius_km=5" \ --data-urlencode "object_type=house,apartment" \ --data-urlencode "energy_label=A,B,C" \ --data-urlencode "sort=newest" \ --data-urlencode "pages=0,1"

    Notes About TLS Shim

    scripts/tls_client.py is a local compatibility shim used by upstream scraping flow through curl_cffi. No system-level native tls_client binary is required for this skill.