Metadata-Version: 2.4
Name: falk
Version: 0.7.2
Summary: Responsive server components in Python
Author-email: Florian Scherf <mail@florianscherf.de>
License-Expression: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Framework :: Django
Classifier: Framework :: Pytest
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Programming Language :: Python
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Topic :: Software Development :: User Interfaces
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Requires-Dist: jinja2
Requires-Dist: simple-logging-setup
Requires-Dist: aiofiles
Requires-Dist: python-multipart
Provides-Extra: dev
Requires-Dist: uvicorn[standard]; extra == "dev"
Requires-Dist: rlpython; extra == "dev"
Provides-Extra: test
Requires-Dist: coverage==7.10.4; extra == "test"
Requires-Dist: pytest==8.4.1; extra == "test"
Requires-Dist: pytest-playwright==0.7.2; extra == "test"
Requires-Dist: requests; extra == "test"
Requires-Dist: rlpython; extra == "test"
Requires-Dist: uvicorn[standard]; extra == "test"
Requires-Dist: starlette; extra == "test"
Requires-Dist: Django~=5.2; extra == "test"
Provides-Extra: docs
Requires-Dist: mkdocs==1.6.1; extra == "docs"
Requires-Dist: mkdocstrings[python]==0.28.2; extra == "docs"
Requires-Dist: mkdocs-material==9.6.6; extra == "docs"
Requires-Dist: grip==4.6.2; extra == "docs"
Dynamic: license-file

# falk

[![PyPI - Version](https://img.shields.io/pypi/v/falk)](https://pypi.org/project/falk)
[![PyPI - License](https://img.shields.io/pypi/l/falk)](https://github.com/fscherf/falk/blob/master/LICENSE.txt)

falk is a Python based web framework for responsive server components. falk
components hold their state cryptographically signed on the client side. This
makes the server fully stateless and easy to scale.

falk components can contain business logic, HTML markup, external and inline
stylesheets and scripts, can communicate with the server over HTTP REST
or websockets.


## Demo

![Demo](./demo.gif)

```python
# pip install uvicorn[websocket] falk
# uvicorn --app-dir=./ demo:app

from falk.components import HTML5Base
from falk.asgi import get_asgi_app


def Counter(initial_render, props, state, add_callback):

    # initialize state object
    if initial_render:
        state.update({
            "count": props.get("initial_value", 0),
        })

    # this callback gets called when the button is clicked
    # (callbacks can be sync or async)
    def increment(args):
        state["count"] += args[0]

    add_callback(increment)

    return """
        <button onclick="{{ falk.run_callback('increment', [1]) }}">
            Count: <strong>{{ state.count }}</strong>
        </button>
    """


def Index(HTML5Base=HTML5Base, Counter=Counter):
    return """
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">

        <style>
            .container {
                margin: 0 auto;
                margin-top: 2em;
            }

            button {
                padding: 5px 10px;
                margin-bottom: 10px;
            }
        </style>

        <HTML5Base title="falk Hello World">
            <div class="container">
                <h1>falk Hello World</h1>

                {% for i in range(5) %}
                    <Counter initial_value="{{ i }}" />
                    <br/>
                {% endfor %}
            </div>
        </HTML5Base>
    """


def configure_app(set_setting, add_route):
    set_setting("debug", True)

    add_route("/", Index)


app = get_asgi_app(configure_app)
```
