Skip to main content

A utility package for Caspian projects

Project description

Caspian Utils (casp)

HTML-first utilities for Caspian applications.

caspian-utils is the shared Python runtime package behind Caspian templates, components, layouts, RPC handlers, and supporting utilities. This repository is not a full application starter, so this README documents the package surface that exists here.

  • PyPI package: caspian-utils
  • Python package: casp
  • Python requirement: >=3.14

Installation

pip install caspian-utils

Core Model

Caspian is HTML-first.

  • write UI in .html
  • use native Jinja syntax for server-rendered values and control flow
  • define reusable components in Python
  • import components with @import comments inside HTML
  • render components with <x-component-name /> tags
  • place child routes in layouts with a real HTML <slot />
  • render pages and layouts from Python with helpers in casp.layout

There is no Caspian-only template syntax layer. Use standard Jinja {{ ... }} and {% ... %} directly.

HTML-First Components

Define a component in Python

from casp.component_decorator import component


@component
def AlertBox(title: str, children: str = "", class_name: str = "") -> str:
    return f"""
    <section class="alert {class_name}">
        <h2>{title}</h2>
        <div>{children}</div>
    </section>
    """

Import and use it in HTML

<!-- @import { AlertBox } from "../components/ui" -->

<main class="space-y-4">
  <x-alert-box title="Saved">
    <p>Your settings were updated.</p>
  </x-alert-box>
</main>

Alias imports when needed

<!-- @import { AlertBox as Notice } from "../components/ui" -->

<div>
  <x-notice title="Heads up" />
</div>

Import and tag rules:

  • AlertBox becomes <x-alert-box>
  • aliases also convert to kebab-case, so Notice becomes <x-notice>
  • grouped imports use <!-- @import { A, B as C } from "..." -->
  • single imports use <!-- @import ComponentName from "..." -->
  • paths are resolved relative to the current template or component directory

Example: <!-- @import { AlertBox } from "../components/ui" --> resolves AlertBox from ../components/ui/AlertBox.py.

Rendering Pages

Use casp.layout to render HTML templates relative to a Python file.

from casp.layout import render_page


def get_dashboard() -> str:
    return render_page(__file__, {
        "pageTitle": "Dashboard",
        "stats": ["Projects", "Tasks", "Alerts"],
    })
<!-- app/dashboard/index.html -->
<!-- @import { AlertBox } from "../components/ui" -->

<main class="space-y-6">
  <h1>{{ pageTitle }}</h1>

  <x-alert-box title="Welcome back" class="rounded border p-4">
    <p>Rendered through an imported Python component.</p>
  </x-alert-box>

  <ul>
    {% for label in stats %}
      <li>{{ label }}</li>
    {% endfor %}
  </ul>
</main>

casp.layout also exposes render_layout(), render(), load_template(), compile_template(), and layout discovery helpers for nested layout flows.

Nested Layouts

Layouts are authored as HTML and use a real <slot /> element as the child-route outlet.

<!-- app/layout.html -->
<html>
  <head>
    <title>{{ metadata.title }}</title>
  </head>
  <body>
    <slot />
  </body>
</html>

During nested layout rendering, Caspian parses the layout HTML and replaces real <slot> elements with the current child page or nested layout. Escaped documentation text such as &lt;slot /&gt; is not treated as a layout outlet.

If a layout needs shared props or metadata, add a sibling layout.py:

from casp.layout import Metadata

metadata = Metadata(title="Dashboard")


def layout():
    return {
        "shell_class": "dashboard-shell",
    }

Those props are available in layout.html as {{ layout.shell_class }}. The installed layout runtime supports sync or async layout() results, but layout work should stay focused on shared subtree props or metadata.

Template Syntax

Caspian templates use native Jinja:

  • {{ value }} for interpolation
  • {% if condition %}...{% endif %} for conditionals
  • {% for item in items %}...{% endfor %} for loops
  • filters such as {{ children | safe }}

There is no additional Caspian template language on top of Jinja.

Template Constraints

Some compiler rules are important when writing templates:

  • every page, layout, and component must render exactly one top-level HTML element
  • unknown <x-...> tags raise an error unless the component has been imported
  • async components are supported by the component pipeline
  • authored PulsePoint scripts should be plain <script> tags inside the single root; the runtime can rewrite them for browser execution

These constraints exist because Caspian injects pp-component metadata into the rendered root element.

RPC Helpers

The package also includes the server-side RPC decorator and related request/serialization utilities.

from casp.rpc import rpc


@rpc(require_auth=True, limits="30/minute")
async def save_profile(name: str):
    return {"ok": True, "name": name}

casp.rpc includes:

  • RPC registration
  • auth-aware decorators
  • rate limiting
  • serialization for common Python objects
  • FastAPI-oriented request and response helpers

Auth Policy

casp.auth provides the framework runtime for sessions, route checks, decorators, CSRF helpers, and OAuth providers. Application auth policy should live in an app-owned src/lib/auth/auth_config.py file, where the app builds AuthSettings and applies them during startup with configure_auth(...).

Keep route privacy, redirects, and RBAC policy in that app config file instead of changing casp.auth.

Main Modules

Module Purpose
casp.layout Load, compile, and render pages and nested layouts with native Jinja and parser-based <slot /> replacement
casp.html_native BeautifulSoup-backed fragment parsing helpers used by layout and component transforms
casp.component_decorator @component, component loading, and HTML rendering helpers
casp.components_compiler Parse @import directives and transform <x-...> component tags
casp.html_attrs Attribute rendering, prop alias normalization, and Tailwind class merge helpers
casp.scripts_type Rewrite authored PulsePoint scripts for browser runtime execution
casp.rpc RPC decorator, registration, serialization, and request handling helpers
casp.streaming Server-Sent Events helpers including SSE
casp.auth Auth settings, session helpers, decorators, OAuth providers, and route checks
casp.runtime_security Safe public-file serving, security headers, and production secret checks
casp.cache_handler Page cache helpers
casp.state_manager Request-scoped and session-backed state helpers
casp.validate Validation and sanitization helpers for strings, IDs, files, dates, and numbers
casp.caspian_config Config loading and file index helpers

Included Dependencies

This release currently installs utilities commonly used by Caspian apps, including:

  • fastapi
  • jinja2
  • beautifulsoup4
  • slowapi
  • python-multipart
  • httpx
  • cuid2
  • python-ulid

See setup.py for the pinned versions in this release.

Repository

TheSteelNinjaCode/caspian_utils

License

MIT

Author

Jefferson Abraham

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

caspian_utils-0.3.5.tar.gz (51.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

caspian_utils-0.3.5-py3-none-any.whl (53.3 kB view details)

Uploaded Python 3

File details

Details for the file caspian_utils-0.3.5.tar.gz.

File metadata

  • Download URL: caspian_utils-0.3.5.tar.gz
  • Upload date:
  • Size: 51.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for caspian_utils-0.3.5.tar.gz
Algorithm Hash digest
SHA256 2917d924a861d5154ae1435556b66a6255840f44ab521d3333e3e368963a1b7b
MD5 8c1a243986d1c22bd0e950c22209f7f3
BLAKE2b-256 e2a6445f6018981e7acf75e625d79e7c6e0a74e276dcd468f192fe387146803f

See more details on using hashes here.

File details

Details for the file caspian_utils-0.3.5-py3-none-any.whl.

File metadata

  • Download URL: caspian_utils-0.3.5-py3-none-any.whl
  • Upload date:
  • Size: 53.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for caspian_utils-0.3.5-py3-none-any.whl
Algorithm Hash digest
SHA256 5a24aa8dbd0922166eac89f876fcd2f42c19c17a4d78056cd31bd6d5947552cf
MD5 87b9186f648997ce187a1c5575d5102c
BLAKE2b-256 6db7ec2b033ab93e8e82954da249fa9bfc956667fefdd01be41056288aad2cbe

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page