From 097d0861c4f0e1958abd4beeea60b2acd705517c Mon Sep 17 00:00:00 2001 From: Ekaropolus Date: Thu, 18 Sep 2025 15:53:16 -0600 Subject: [PATCH] Adding format routes --- pxy_agents_coral/formatters.py | 84 ++++++++++++++++++++++++++++++++++ pxy_agents_coral/urls.py | 9 ++-- pxy_dashboard/middleware.py | 5 ++ 3 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 pxy_agents_coral/formatters.py diff --git a/pxy_agents_coral/formatters.py b/pxy_agents_coral/formatters.py new file mode 100644 index 0000000..d25422a --- /dev/null +++ b/pxy_agents_coral/formatters.py @@ -0,0 +1,84 @@ +from __future__ import annotations +import json +import requests +from django.http import JsonResponse, HttpRequest +from django.views.decorators.csrf import csrf_exempt +from django.views.decorators.http import require_http_methods + +def _post_json(url: str, payload: dict, timeout: float = 60.0) -> dict: + r = requests.post(url, json=payload, timeout=timeout) + r.raise_for_status() + return r.json() + +def _base(request: HttpRequest) -> str: + return request.build_absolute_uri("/")[:-1] + +@csrf_exempt +@require_http_methods(["GET", "POST"]) +def format_sami(request: HttpRequest): + """ + Body: {"payload": {...}} where payload matches SAMI RunRequest. + Calls /api/agents/execute and returns {"text": "...", ...original...} + """ + try: + body = json.loads(request.body.decode("utf-8") or "{}") + except Exception: + body = {} + payload = body.get("payload") or {} + + data = _post_json(f"{_base(request)}/api/agents/execute", + {"agent": "sami", "payload": payload}) + + # Build text + try: + beta = data.get("beta"); r2 = data.get("r2") + resid = data.get("residuals") or [] + top = sorted(resid, key=lambda x: x.get("rank", 1e9))[:3] + lines = [] + if beta is not None and r2 is not None: + lines.append(f"SAMI run: β={beta:.3f}, R²={r2:.3f}") + for c in top: + lines.append(f"{c.get('rank')}. {c.get('city')}: {c.get('sami', 0):+0.2f}") + if data.get("share_url"): + lines.append("") + lines.append(data["share_url"]) + text = "\n".join(lines) if lines else "SAMI results ready." + data["text"] = text + except Exception: + pass + + return JsonResponse(data, safe=False) + +@csrf_exempt +@require_http_methods(["GET", "POST"]) +def format_sites(request: HttpRequest): + """ + Body: {"payload": {...}} where payload matches SiteSearchRequest. + Calls /api/agents/execute and returns {"text": "...", ...original...} + """ + try: + body = json.loads(request.body.decode("utf-8") or "{}") + except Exception: + body = {} + payload = body.get("payload") or {} + + data = _post_json(f"{_base(request)}/api/agents/execute", + {"agent": "sites", "payload": payload}) + + # Build text + try: + city = data.get("city"); business = data.get("business") + cands = data.get("candidates") or [] + top = cands[:3] + lines = [f"Top sites for {business} in {city}:"] + for i, c in enumerate(top, 1): + lines.append(f"{i}. score={c.get('score',0):.2f} @ ({c.get('lat',0):.5f},{c.get('lon',0):.5f})") + # include useful links if present + for k in ("share_url", "isochrones_geojson_url", "candidates_geojson_url"): + if data.get(k): + lines.append(data[k]) + data["text"] = "\n".join(lines) + except Exception: + pass + + return JsonResponse(data, safe=False) diff --git a/pxy_agents_coral/urls.py b/pxy_agents_coral/urls.py index 451f330..24ee5f9 100644 --- a/pxy_agents_coral/urls.py +++ b/pxy_agents_coral/urls.py @@ -1,7 +1,10 @@ from django.urls import path -from . import views +from .formatters import format_sami, format_sites +from .views import agents_list, agents_execute urlpatterns = [ - path('api/agents/list', views.agents_list, name='agents_list'), - path('api/agents/execute', views.agents_execute, name='agents_execute'), + path("api/agents/list", agents_list, name="agents_list"), + path("api/agents/execute", agents_execute, name="agents_execute"), + path("api/agents/format/sami", format_sami, name="agents_format_sami"), + path("api/agents/format/sites", format_sites, name="agents_format_sites"), ] diff --git a/pxy_dashboard/middleware.py b/pxy_dashboard/middleware.py index c580abb..ccde4ab 100644 --- a/pxy_dashboard/middleware.py +++ b/pxy_dashboard/middleware.py @@ -124,6 +124,11 @@ EXEMPT_URLS += [ re.compile(r"^api/agents/execute$"), ] +EXEMPT_URLS += [ + re.compile(r"^api/agents/format/sami$"), + re.compile(r"^api/agents/format/sites$"), +] + class LoginRequiredMiddleware(MiddlewareMixin):