Metadata-Version: 2.4
Name: citry
Version: 0.4.6
Summary: Fully typed frontend framework for Python with server events and Alpine.js, inspired by Vue and Livewire
Author-email: Juro Oravec <juraj.oravec.josefson@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://citry.dev
Project-URL: Repository, https://github.com/citry-dev/citry
Project-URL: Changelog, https://github.com/citry-dev/citry/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/citry-dev/citry/issues
Keywords: citry,components,frontend,html,web development,templating,template engine
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: <4.0,>=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: citry-core==1.6.1
Requires-Dist: wrapt>=1.16
Requires-Dist: markupsafe>=2.1
Requires-Dist: typing-extensions>=4.10
Requires-Dist: tomli>=2.0; python_version < "3.11"
Requires-Dist: tzdata>=2026.3
Provides-Extra: analysis-ty
Requires-Dist: ty==0.0.73; extra == "analysis-ty"
Provides-Extra: watcher-watchfiles
Requires-Dist: watchfiles>=1.0; extra == "watcher-watchfiles"
Provides-Extra: watcher-watchdog
Requires-Dist: watchdog>=4.0; extra == "watcher-watchdog"
Dynamic: license-file

<!-- Absolute URL so the logo also renders on PyPI, which serves this README from
     outside the repository and cannot resolve a repo-relative path. -->
<img src="https://raw.githubusercontent.com/citry-dev/citry/main/docs/assets/citry-wordmark.png" alt="Citry" width="170">

# Citry: a fully typed frontend framework for Python

[![PyPI - Version](https://img.shields.io/pypi/v/citry)](https://pypi.org/project/citry/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/citry)](https://pypi.org/project/citry/)
[![License](https://img.shields.io/pypi/l/citry)](https://github.com/citry-dev/citry/blob/main/LICENSE)
[![CI](https://github.com/citry-dev/citry/actions/workflows/repo--check.yml/badge.svg)](https://github.com/citry-dev/citry/actions/workflows/repo--check.yml)
[![Docs](https://img.shields.io/badge/docs-citry.dev-8a2be2)](https://citry.dev/)
[![Discord](https://img.shields.io/badge/Discord-join%20chat-5865F2?logo=discord&logoColor=white)](https://discord.gg/NaQ8QPyHtD)

Citry is a fully typed frontend framework for Python with server events and
Alpine.js. One component can own its HTML, browser behavior, CSS, translations,
and Python event handlers, so you can build an interactive interface without
maintaining a separate frontend application. It is inspired by Vue and
Livewire.

Citry works with FastAPI, Django, Flask, Starlette, ASGI, and WSGI
applications.

**Citry 0.4 is the public beta.** It supports Python 3.10 through 3.14.

[Read the docs](https://citry.dev/docs/) ·
[Try the playground](https://citry.dev/playground/) ·
[Explore examples](https://citry.dev/examples/) ·
[Install the VS Code extension](https://marketplace.visualstudio.com/items?itemName=citry-dev.citry) ·
[Browse Citry UI](https://citry.dev/ui-library/)

## Start with one component

Install Citry:

```console
python -m pip install citry
```

Or add it to a `uv` project:

```console
uv add citry
```

Define a component in ordinary Python. Typed inputs catch misspellings and
missing values, while `template_data()` chooses exactly what the template can
read:

```citry
from citry import Component


class Welcome(Component):
    class Kwargs:
        name: str
        messages: list[str]

    def template_data(self, kwargs, slots):
        return {
            "name": kwargs.name,
            "messages": kwargs.messages,
        }

    def css_data(self, kwargs, slots):
        return {"accent": "tomato"}

    template = """
      <section class="welcome">
        <h1>Welcome back, {{ name }}!</h1>
        <ul>
          <li c-for="message in messages">
            {{ message }}
          </li>
          <li c-empty>Nothing new yet.</li>
        </ul>
      </section>
    """

    css = """
      .welcome {
        border-top: 3px solid var(--accent);
      }
    """


html = str(
    Welcome(
        name="Ada",
        messages=["Build finished", "Report ready"],
    )
)
```

Components compose through HTML-like tags. Static inputs look like ordinary
HTML attributes; prefix an input with `c-` when its value is a Python
expression:

```citry-html
<main>
  <c-Welcome name="Ada" c-messages="user.inbox" />
</main>
```

That is most of the template language:

1. `<c-Name>` renders a component or a built-in control-flow tag.
2. A `c-` attribute evaluates a Python expression.

Continue with the
[step-by-step tutorial](https://citry.dev/getting-started/installation/) or
read the [template syntax guide](https://citry.dev/syntax/).

## Build the whole interface in Python

Citry gives each part of an interface a clear home:

| What you need | What Citry provides |
| --- | --- |
| Reusable UI | Components, typed inputs, slots, composition, and error boundaries |
| Browser behavior | Alpine expressions, component JavaScript, CSS, and managed assets |
| Python interactions | Server events, forms, persistent State, and targeted HTML updates |
| Internationalization | Fluent catalogs, locale-aware formatting, and server/browser translations |
| Production control | Caching, HTML fragments, strict CSP support, CSRF hooks, and debug tooling |
| Editor help | Highlighting, completion, navigation, diagnostics, and safe formatting |

Learn these features through the
[component guides](https://citry.dev/concepts/components/),
[Events documentation](https://citry.dev/events/), and
[advanced guides](https://citry.dev/advanced/js-and-css-dependencies/).

Need ready-made application components? Install
[Citry UI](https://citry.dev/ui-library/) for accessible forms, dialogs,
navigation, feedback, data display, theming, and translated default labels:

```console
python -m pip install citry-ui
```

## Connect a web application

Mount Citry on the web framework that already serves your application. For
example, with FastAPI or Starlette:

```python
from citry import citry
from citry.contrib.fastapi import mount


mount(app, citry)
citry.initialize()
```

Citry includes adapters for:

| Host | Integration |
| --- | --- |
| FastAPI / Starlette | `citry.contrib.fastapi.mount()` |
| Django | `citry.contrib.django.urlpatterns()` |
| Flask | `citry.contrib.flask.mount()` |
| Any ASGI application | `citry.contrib.asgi.asgi_app()` |
| Any WSGI application | `citry.contrib.wsgi.wsgi_app()` |

The [web-framework guide](https://citry.dev/web-frameworks/) shows the right
startup and routing setup for each host.

Want a complete project instead of an integration excerpt? Copy the
[FastAPI starter](https://github.com/citry-dev/citry/tree/citry%400.4.6/examples/starters/fastapi)
or choose from the
[standalone, Django, Flask, ASGI, and WSGI starter matrix](https://github.com/citry-dev/citry/tree/citry%400.4.6/examples).
The collection also includes complete Project Board and
[HTMX integration](https://github.com/citry-dev/citry/tree/citry%400.4.6/examples/demos/htmx)
demos. Each project has its own dependencies, lockfile, and tests. Every web
starter includes a browser interaction powered by Citry Events. The HTMX demo
uses HTMX for every request and page update.

## Use the editor and command line

The free
[Citry extension for VS Code](https://marketplace.visualstudio.com/items?itemName=citry-dev.citry)
understands the HTML, Python, JavaScript, CSS, and Fluent inside a component.
It provides completion, hover help, navigation, references, diagnostics, and
safe formatting. The same extension is available from
[Open VSX](https://open-vsx.org/extension/citry-dev/citry).

Citry also installs a command-line checker:

```console
citry check --static
```

Point it at an application for registered component contracts and template
data:

```console
citry --app myproject.app:citry_app check
```

See the [VS Code guide](https://citry.dev/ide/vscode/) and
[CLI reference](https://citry.dev/cli/) for setup and CI usage.

## Performance

The current benchmark renders a large page with about 350 Citry component
markers and 986 KB of output, including browser runtimes and the component
ownership graph:

![Citry vs Django vs django-components rendering a large page. Lower is better.](https://raw.githubusercontent.com/citry-dev/citry/main/docs/assets/benchmark.png)

- Compared with django-components, Citry is about 12% slower on the first
  render and 24% faster once warm.
- Compared with a bare Django template, Citry's warm render takes about 3.5
  times as long while also running its component lifecycle, extension,
  dependency, ownership, and security work.
- Jinja2 remains the fastest no-component baseline once warm.

These are relative results from one machine. Read the
[published benchmark](https://citry.dev/about/benchmarks/) for the chart and
interpretation, or the
[benchmark repository guide](https://github.com/citry-dev/citry/blob/main/benchmarks/README.md)
to reproduce it.

## Get help and contribute

- [Documentation](https://citry.dev/docs/)
- [Examples](https://citry.dev/examples/)
- [API reference](https://citry.dev/reference/)
- [Release notes](https://citry.dev/releases/)
- [Discord](https://discord.gg/NaQ8QPyHtD)
- [GitHub Discussions](https://github.com/citry-dev/citry/discussions)
- [Issue tracker](https://github.com/citry-dev/citry/issues)
- [Contributing guide](https://github.com/citry-dev/citry/blob/main/CONTRIBUTING.md)
- [Sponsor Citry](https://github.com/sponsors/JuroOravec)

Citry continues the component work begun in
[django-components](https://github.com/django-components/django-components)
and
[django-components/djc-core](https://github.com/django-components/djc-core).

## License

[MIT](https://github.com/citry-dev/citry/blob/main/LICENSE)
