Server functions
wybthon.server_functions¶
server_functions
¶
Server functions: Python that runs on the server, called from the browser like any async def.
Decorate a module-level async def with
server_function, and calling it from a
component sends its arguments to the server, runs it there, and returns
its result, as Solid 2.0's "use server" does:
from dataclasses import dataclass
from wybthon import server_function
@dataclass
class Todo:
id: int
title: str
@server_function
async def list_todos(done: bool = False) -> list[Todo]:
from app.server.db import database # never imported in the browser
return [Todo(*row) for row in database().execute("select id, title from todos where done = ?", [done])]
- On the server (while a page renders, or in another server function), the call runs the function directly.
- In the browser, the build has removed the function's body and every
import only that body used, so neither reaches the page. The call
posts its arguments to
{base}_wyb/fn/{module}:{name}and awaits the answer. Arguments and results cross in Wybthon's wire format (wybthon._wire): JSON plus dataclasses, enums, tuples, sets, dates,Decimal,UUID, and bytes. On the server, every argument is rebuilt and validated from the function's own annotations, so a client can't send anything the function didn't declare; a mismatch is a 400. - Errors. An exception the function raises arrives in the browser as
ServerErrorwith the exception's type name. Its message is sent in development, and in production only for aServerErrorthe function raised itself, so internals don't leak. - Responses. Raise or return
redirect,reload, orrespondto navigate, revalidate queries, or set the status and headers. - Mutations revalidate. A POST call (the default) is treated as a
mutation: when it completes, the browser revalidates every
queryon the page, unless the function named what it changed withrespond(value, revalidate=[...]).@server_function(method="GET")declares a read, which revalidates nothing; a server function wrapped inqueryis a GET automatically. - The request.
get_request_eventreturns the request the call came in with, so a server function can read cookies and headers and callset_cookieorhttp_header.
Server functions need a server: a project with server = true in its
wybthon.toml, served by wyb dev, wyb serve, or
wybthon.asgi under any ASGI server.
Classes:
| Name | Description |
|---|---|
ServerResponse |
Base of the responses a server function may raise or return. |
Redirect |
Navigate to |
Reload |
Revalidate queries without navigating (see |
Respond |
A result with a status, headers, or revalidation keys (see |
ServerFunction |
A function that runs on the server; returned by |
Functions:
| Name | Description |
|---|---|
redirect |
A redirect, for a server function, query, or form action to raise or return. |
reload |
Revalidate queries on the current page without navigating. |
respond |
Return |
set_transport |
Send browser-side server function calls through |
server_function |
Make an |
Attributes:
| Name | Type | Description |
|---|---|---|
FN_PATH |
Where server functions are served, under the app's base path. |
FN_PATH
module-attribute
¶
Where server functions are served, under the app's base path.
ServerResponse
¶
Redirect
¶
Reload
¶
Respond
¶
ServerFunction
¶
A function that runs on the server; returned by server_function.
Call it like the function it wraps: await save(todo).
Attributes:
| Name | Type | Description |
|---|---|---|
id |
The function's id, |
|
method |
Method
|
|
redirect
¶
redirect(url: str, status: int = 302, *, revalidate: str | list[str] | None = None, headers: dict[str, str] | None = None) -> Redirect
A redirect, for a server function, query, or form action to raise or return.
In the browser, the router navigates to url (replacing the history
entry); a JavaScript-free form post gets a 303 to it. Raised from a
query while a page renders on the server, it becomes the page's
response. revalidate names the queries to refetch first; by default
a redirect from a mutation revalidates everything the next page reads.
reload
¶
reload(*, revalidate: str | list[str] | None = None, headers: dict[str, str] | None = None) -> Reload
Revalidate queries on the current page without navigating.
revalidate names query keys (or key prefixes); omit it to
revalidate every query on the page.
respond
¶
set_transport
¶
set_transport(transport: Transport | None, *, base: str | None = None) -> None
Send browser-side server function calls through transport (tests and tools).
wybthon.testing.serve uses it to connect components rendered in
CPython to an in-process ASGI app. With a transport set, calls are
made remotely even outside a browser. None restores the default.
server_function
¶
server_function(fn: Callable[P, Awaitable[R]]) -> ServerFunction[P, R]
server_function(*, method: Method = 'POST') -> Callable[[Callable[P, Awaitable[R]]], ServerFunction[P, R]]
Make an async def run on the server, wherever it's called from.
Use it bare (@server_function) for a mutation, called with POST, or
with method="GET" for a read. See
wybthon.server_functions for the whole
contract.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
Any
|
The |
None
|
method
|
Method
|
|
'POST'
|
Returns:
| Type | Description |
|---|---|
Any
|
A |
Any
|
signature. |
handle
async
¶
handle(event: RequestEvent, fn_id: str, method: str, query: str, headers: dict[str, str], body: bytes) -> tuple[int, dict[str, str], bytes, ServerFunction[..., Any] | None, Any]
Run a server function for an HTTP request.
Returns (status, headers, body, function, outcome). outcome is
the raw result or exception, for the caller's form-post handling.
What's in this module¶
Server functions and the responses they return. Everything here is exported from wybthon, as are FormData and UploadedFile, what a form action receives.
| Name | Description |
|---|---|
server_function |
@server_function or @server_function(method="GET"): make an async def run on the server. |
ServerFunction |
What the decorator returns; id is module:qualname, and url the URL the browser calls. |
redirect |
Navigate (or answer a page or a form post with a redirect). |
reload |
Revalidate queries without navigating. |
respond |
Return a value with a status, headers, or the query keys a call changed. |
See also¶
- Concepts: Full-stack apps
- ASGI
- Request:
get_request_event,http_header, andset_cookie