PyxlePyxle/Docs

Runtime API Reference

The pyxle.runtime module provides decorators and error classes used in .pyxl files. These are automatically available in the Python section of every .pyxl file -- you do not need to import them (the compiler injects the import).

@server

Marks an async function as a page data loader.

@server
async def load_page(request):
    return {"key": "value"}

Behaviour:

  • Attaches __pyxle_loader__ = True to the function (no wrapping)
  • The function must be async (enforced at compile time)
  • Receives a Starlette `Request` object
  • Must return a JSON-serializable dict
  • Can return a (dict, int) tuple to set the HTTP status code
  • Only one @server function is allowed per .pyxl file

Request object properties:

Property Type Description
request.path_params dict URL path parameters from dynamic routes
request.query_params QueryParams URL query string parameters
request.headers Headers HTTP request headers
request.cookies dict Request cookies
request.url URL Full request URL
request.method str HTTP method
request.state State Mutable state for middleware to attach data

@action

Marks an async function as a server action callable from React components.

@action
async def create_item(request):
    body = await request.json()
    return {"id": 1, "name": body["name"]}

Behaviour:

  • Attaches __pyxle_action__ = True to the function (no wrapping)
  • The function must be async
  • Receives a Starlette Request object
  • Must return a JSON-serializable dict
  • Multiple @action functions are allowed per .pyxl file
  • Accessible via POST /api/__actions/{page_path}/{action_name}
  • Protected by CSRF middleware by default

Client response format:

// Success
{ "ok": true, "id": 1, "name": "Item" }

// Error (from ActionError)
{ "ok": false, "error": "Error message" }

LoaderError

Exception class for structured loader errors. Triggers the nearest error.pyxl boundary.

from pyxle.runtime import LoaderError

@server
async def load_page(request):
    raise LoaderError("Not found", status_code=404, data={"id": 42})

Constructor:

LoaderError(message: str, status_code: int = 500, data: dict | None = None)
Parameter Type Default Description
message str (required) Error message displayed in the error boundary
status_code int 500 HTTP response status code
data dict | None None Additional JSON-serializable context

Properties:

Property Type Description
.message str The error message
.status_code int HTTP status code
.data dict Additional context (empty dict if None was passed)

ActionError

Exception class for structured action errors. Returns a JSON error response to the client.

from pyxle.runtime import ActionError

@action
async def update_item(request):
    raise ActionError("Validation failed", status_code=400, data={"field": "name"})

Constructor:

ActionError(message: str, status_code: int = 400, data: dict | None = None)
Parameter Type Default Description
message str (required) Error message sent to the client
status_code int 400 HTTP response status code
data dict | None None Additional JSON-serializable payload

Properties:

Property Type Description
.message str The error message
.status_code int HTTP status code
.data dict Additional data (empty dict if None was passed)

Document <head> elements

Pyxle offers two ways to contribute elements to the document <head>: the <Head> component (recommended) and the HEAD Python variable (lower-level alternative). Both are merged with automatic deduplication.

Imported from pyxle/client, usable anywhere in your JSX tree:

import { Head } from 'pyxle/client';

export default function Page({ data }) {
  return (
    <>
      <Head>
        <title>{data.title}</title>
        <meta name="description" content={data.description} />
        <link rel="canonical" href={data.canonicalUrl} />
      </Head>
      {/* ... */}
    </>
  );
}

See Head Management for the full pattern (layouts, deduplication, reusable SEO components, etc.).

HEAD variable (lower-level alternative)

Not part of pyxle.runtime but available in every .pyxl file. The HEAD variable is extracted at compile time by the parser; use it for fully-static head metadata that doesn't need React context, or for pages without a JSX component.

Static form:

# String
HEAD = '<title>Page Title</title>'

# List of strings
HEAD = ['<title>Page Title</title>', '<meta name="description" content="..." />']

Dynamic form (callable):

def HEAD(data):
    return f'<title>{data["title"]}</title>'

The callable receives the loader's return value. Must return a string or list of strings synchronously. For most dynamic head content, the <Head> component with normal JSX interpolation is simpler and more flexible.

Explicit imports

While the compiler auto-injects @server and @action, you can also import explicitly:

from pyxle.runtime import server, action, LoaderError, ActionError

This is useful for type checking and IDE support.