Server Actions (RPC)

Call Python functions directly from your browser. Caspian bridges your backend logic to the frontend with built-in Streaming, Rate Limiting, RBAC, File Uploads, and Auto-Serialization.

Core Features

Native Streaming Support

Just use yield in your Python function. Caspian automatically detects generators and streams data via Server-Sent Events (SSE). Perfect for AI Agents, LLM token streaming, and long-running jobs.

Secure & Private

Built-in CSRF protection and Origin validation. Functions are private by default until decorated with @rpc.

Smart Rate Limiting

Define hierarchical limits (e.g., "20/hour") per function, or fallback to global environment defaults.

Role-Based Access

Restrict actions to specific user roles or authenticated sessions with a single argument.

Auto-Serialization

Returns Pydantic models, Dataclasses, or Prisma objects directly. JSON conversion is automatic.

Defining Actions (Backend)

The @rpc() decorator configures access control, limits, and behavior.

src/app/actions.py
from casp.rpc import rpc
import asyncio

# 1. Basic Action (JSON Response)
@rpc()
def get_status():
    return {"status": "ok", "uptime": 99.9}

# 2. Secure & Rate Limited Action
@rpc(
    require_auth=True, 
    allowed_roles=["admin"],
    limits="5/minute"
)
def delete_user(user_id: int):
    return db.delete(user_id)

# 3. Streaming Action (AsyncGenerator)
@rpc()
async def stream_ai_response(prompt: str):
    # Automatic SSE streaming when 'yield' is detected
    async for chunk in openai.stream(prompt):
        yield chunk

Calling Actions (Frontend)

Use pp.rpc(name, data, options). For streaming, simply provide the onStream callback.

<script>
async function handleAction() {
  try {
      // 1. Standard Call (Returns Promise)
      const data = await pp.rpc('get_status');
      console.log(data.status);

      // 2. Streaming Call (Event Driven)
      await pp.rpc('stream_ai_response', { prompt: "Hello" }, {
          onStream: (chunk) => {
              console.log("Received:", chunk);
          },
          onStreamComplete: () => {
              console.log("Stream Finished");
          }
      });
  } catch (err) {
      // Handles 401, 403, 429 automatically
      console.error("RPC Error:", err);
  }
}

Example 1: Secure Todo App

A classic CRUD application demonstrating database integration, serialization, and state updates.

Example 2: Streaming AI Chat

A real-time chat interface showing how to stream text tokens from the backend using generators.

Example 3: File Uploads

Secure file uploads with automatic progress tracking using the onUploadProgress callback.