Extend defhandler with :path/:method/:csrf, migrate 12 ref endpoints to SX
defhandler now supports keyword options for public route registration: (defhandler name :path "/..." :method :post :csrf false (&key) body) Infrastructure: forms.sx parses options, HandlerDef stores path/method/csrf, register_route_handlers() mounts path-based handlers as app routes. New IO primitives (boundary.sx "Web interop" section): now, sleep, request-form, request-json, request-header, request-content-type. First migration: 12 reference API endpoints from Python f-string SX to declarative .sx handlers in sx/sx/handlers/ref-api.sx. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -221,18 +221,29 @@ class Island:
|
||||
|
||||
@dataclass
|
||||
class HandlerDef:
|
||||
"""A declarative fragment handler defined in an .sx file.
|
||||
"""A declarative handler defined in an .sx file.
|
||||
|
||||
Created by ``(defhandler name (&key param...) body)``.
|
||||
The body is evaluated in a sandboxed environment with only
|
||||
s-expression primitives available.
|
||||
Created by ``(defhandler name :path "/..." :method :get (&key param...) body)``.
|
||||
|
||||
When ``path`` is set, the handler is registered as a public route.
|
||||
When ``path`` is None, it's an internal fragment handler (legacy behaviour).
|
||||
"""
|
||||
name: str
|
||||
params: list[str] # keyword parameter names
|
||||
body: Any # unevaluated s-expression body
|
||||
closure: dict[str, Any] = field(default_factory=dict)
|
||||
path: str | None = None # public route path (None = internal fragment only)
|
||||
method: str = "get" # HTTP method (get, post, put, patch, delete)
|
||||
csrf: bool = True # CSRF protection enabled
|
||||
|
||||
@property
|
||||
def is_route(self) -> bool:
|
||||
"""True if this handler has a public route path."""
|
||||
return self.path is not None
|
||||
|
||||
def __repr__(self):
|
||||
if self.path:
|
||||
return f"<handler:{self.name} {self.method.upper()} {self.path}>"
|
||||
return f"<handler:{self.name}({', '.join(self.params)})>"
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user