Metadata-Version: 2.4
Name: pytypehintweb
Version: 0.0.1
Summary: Framework-free browser form layer for pytypehint
Author: Beltran Offerrall
License-Expression: MIT
Project-URL: Homepage, https://github.com/offerrall/pytypehintweb
Project-URL: Repository, https://github.com/offerrall/pytypehintweb
Project-URL: Issues, https://github.com/offerrall/pytypehintweb/issues
Keywords: forms,type-hints,dataclasses,schema,web,html
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: JavaScript
Classifier: Topic :: Software Development :: User Interfaces
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pytypehint>=0.0.6
Provides-Extra: demo
Requires-Dist: fastapi; extra == "demo"
Requires-Dist: uvicorn; extra == "demo"
Requires-Dist: python-multipart; extra == "demo"
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: mypy; extra == "test"
Dynamic: license-file

# pytypehintweb

`pytypehintweb` is a framework-free browser form layer for
[`pytypehint`](https://github.com/offerrall/pytypehint). It converts compiled
Python type schemas into self-contained, JSON-serializable form plans and
renders them with plain JavaScript widgets. The browser runtime also consumes
hand-written plans or plans from another backend, so Python is not required at
render time. Everything around the form — routing, static-file delivery,
authentication, submission, function execution — belongs to the host
application. (For the whole request/response cycle instead of the rendering
layer, see [FuncToWeb](https://github.com/offerrall/FuncToWeb).)

Pre-1.0: the API is still settling, so breaking changes are expected between
releases.

## Features

- Self-contained, JSON-serializable plans from plain functions, dataclass types
  or compiled `Signature`/`Struct` schemas — and hand-written plans need no
  Python.
- Framework-free browser runtime (plain HTML, CSS and JS modules), with widgets
  usable directly or from a plan; browser files ship inside the Python package
  under `pytypehintweb.STATIC`.
- `str`, `int`, `float`, `date`, `time`, `bool` and `enum` composing through lists,
  optional fields, unions and nested dataclasses, with constraints, static choices,
  integer sliders, and configurable validation messages and labels.
- `file` fields (single or `list[File]`) that mint an upload reference the host
  redeems through its own channel.
- Centralized plan normalization and validation before any widget is built, and
  `plain` / `inline` / `wrapped` union transport.
- Plan text is always rendered as text, never parsed as markup.

## Installation

```bash
pip install pytypehintweb            # library
pip install "pytypehintweb[demo]"    # + the local demo (pytypehintweb-demo)
```

```bash
# Demo with all widgets, served by a local HTTP server on port 8000:
pytypehintweb-demo
```

There is no npm package: the browser modules live under `pytypehintweb.STATIC`
and can be served by any static-file mount.

## Quick start

```python
from typing import Annotated

from pytypehint import Label, Min
from pytypehintweb import plan_of


def create_user(
    username: Annotated[str, Min(3), Label("Username")],
    age: Annotated[int, Min(0), Label("Age")],
) -> None:
    pass


plan = plan_of(create_user)
```

`plan_of()` returns ordinary Python dictionaries and lists — a single, fully
expanded, self-contained document where every non-conditional property is present
with an explicit value (`default` appears exactly when `hasDefault` is true),
carrying a top-level `"v": 1`:

```json
{
  "v": 1,
  "kind": "form",
  "name": "create_user",
  "description": null,
  "fields": [
    {
      "name": "username",
      "label": "Username",
      "description": null,
      "optional": false,
      "enabled": true,
      "hasDefault": false,
      "node": {
        "kind": "str",
        "options": {
          "minLength": 3,
          "maxLength": null,
          "pattern": null,
          "patternMessage": "Invalid format",
          "minMessage": "Must contain at least {value} characters",
          "maxMessage": "Must contain at most {value} characters",
          "placeholder": null,
          "password": false,
          "rows": null,
          "choices": null
        }
      }
    },
    {
      "name": "age",
      "label": "Age",
      "description": null,
      "optional": false,
      "enabled": true,
      "hasDefault": false,
      "node": {
        "kind": "int",
        "options": {
          "min": 0,
          "max": null,
          "multipleOf": null,
          "step": null,
          "slider": false,
          "showValue": false,
          "placeholder": null,
          "choices": null,
          "safeMessage": "Must be a safe integer",
          "invalidMessage": "Enter a valid integer",
          "minMessage": "Must be at least {value}",
          "maxMessage": "Must be at most {value}",
          "multipleOfMessage": "Must be a multiple of {value}",
          "increaseLabel": "Increase",
          "decreaseLabel": "Decrease"
        }
      }
    }
  ]
}
```

Transporting that document to the browser and compiling it with `compileForm()`
is walked through end to end in [Getting started](docs/getting-started.md).

## Documentation

- [Getting started](docs/getting-started.md) — the end-to-end tutorial.
- [Plan contract](docs/plan.md) — the plan format, every property and invariant.
- [Python API](docs/python.md) — `plan_of()`, `WebConfig`, annotation mappings.
- [JavaScript API](docs/javascript.md) — `compileForm()`, widgets, reading,
  accessibility, styling.
- [Architecture](docs/architecture.md) — layers and which layer owns each rule.
- [Testing](docs/testing.md) — how to run the suites and what they guarantee.
- [Current limitations](docs/limitations.md).
