Files
2dph/docker/serve
T
eSlider 63d3be0e19 build(ci): uv toolchain, release-please semver; feat(skills): vendor tools self-contained (no symlinks, relative refs)
- bin/db/psql-yq + bin/web/search + tools/{yamlout,websearch} vendored as real files
- bin/db/ssh-tunnel added (OnlyOffice VM pg on 5433)
- skills reference local bin/ paths; no agent-skills/abs links in git
- pyproject.toml + uv.lock; CI installs via uv sync --frozen
- release-please auto-tags semver from conventional commits when green
- LICENSE MIT, badges/mermaid README
2026-08-10 21:24:42 +01:00

49 lines
1.6 KiB
Python

#!/usr/bin/env python3
"""serve - tiny read-only HTTP wrapper over bin/kb/search.
serve [port] default 8630, binds 127.0.0.1
GET /health -> {"status":"ok"}
GET /search?q=... -> YAML from kb/search (transparent, cached by client)
"""
from __future__ import annotations
import json
import sys
import urllib.parse
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8630
class Handler(BaseHTTPRequestHandler):
def log_message(self, *args): # keep stdout clean
pass
def do_GET(self): # noqa: N802
url = urllib.parse.urlparse(self.path)
if url.path.rstrip("/") == "/health":
self._json({"status": "ok"})
return
if url.path.rstrip("/") == "/search":
q = urllib.parse.parse_qs(url.query).get("q", [""])[0]
if not q:
self._json({"error": "q required"}, code=400)
return
self._json({"query": q, "note": "search via bin/kb/search is offline; rewire to ladybug reads"})
return
self._json({"error": "not found"}, code=404)
def _json(self, obj, code=200):
body = json.dumps(obj, ensure_ascii=False).encode()
self.send_response(code)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
if __name__ == "__main__":
server = ThreadingHTTPServer(("127.0.0.1", PORT), Handler)
print(f"serve: 127.0.0.1:{PORT}", file=sys.stderr)
server.serve_forever()