Metadata-Version: 2.4
Name: caspian-utils
Version: 0.3.6
Summary: A utility package for Caspian projects
Home-page: https://github.com/TheSteelNinjaCode/caspian_utils
Author: Jefferson Abraham
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.14
Description-Content-Type: text/markdown
Requires-Dist: fastapi==0.138.0
Requires-Dist: jinja2==3.1.6
Requires-Dist: beautifulsoup4==4.15.0
Requires-Dist: slowapi==0.1.10
Requires-Dist: python-multipart==0.0.32
Requires-Dist: httpx==0.28.1
Requires-Dist: cuid2==2.0.1
Requires-Dist: python-ulid==3.1.0
Dynamic: author
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# 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

```bash
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

```py
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

```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

```html
<!-- @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.

```py
from casp.layout import render_page


def get_dashboard() -> str:
    return render_page(__file__, {
        "pageTitle": "Dashboard",
        "stats": ["Projects", "Tasks", "Alerts"],
    })
```

```html
<!-- 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.

```html
<!-- 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`:

```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.

```py
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](https://github.com/TheSteelNinjaCode/caspian_utils)

## License

MIT

## Author

Jefferson Abraham
