Git Product home page Git Product logo

asgi-htmx's Introduction

asgi-htmx

Build Status Coverage Package version

HTMX integration for ASGI applications. Works with Starlette, FastAPI, Quart -- or any other web framework supporting ASGI that exposes the ASGI scope. Inspired by django-htmx.

Table of contents

Installation

NOTE: This is alpha software. Please be sure to pin your dependencies.

pip install asgi-htmx==0.1.*

Quickstart

First, ensure HTMX is installed.

For example, download a copy of htmx.min.js, add it to your static files, then add the script tag to templates:

<script src="{{ url_for('static', path='/js/htmx.min.js') }}" defer></script>

Now, install HtmxMiddleware onto the ASGI app:

  • Using Starlette:

    from asgi_htmx import HtmxMiddleware
    from starlette.middleware import Middleware
    
    app = Starlette(
        middleware=[
            ...,
            Middleware(HtmxMiddleware),
            ...,
        ],
    )
  • Using FastAPI:

    from asgi_htmx import HtmxMiddleware
    from fastapi import FastAPI
    
    app = FastAPI()
    app.add_middleware(HtmxMiddleware)

You can now access scope["htmx"] (an instance of HtmxDetails) in endpoints:

# `HtmxRequest` makes code editors type-check `request.scope["htmx"]`
from asgi_htmx import HtmxRequest as Request

from .resources import templates

async def home(request: Request):
    template = "home.html"
    context = {"request": request}

    if (htmx := request.scope["htmx"]):
        template = "partials/items.html"
        context["boosted"] = htmx.boosted  # ...

    return templates.TemplateResponse(template, context)

See examples for full working example code.

API Reference

HtmxMiddleware

An ASGI middleware that sets scope["htmx"] to an instance of HtmxDetails (scope refers to the ASGI scope).

app = HtmxMiddleware(app)

HtmxDetails

A helper that provides shortcuts for accessing HTMX-specific request headers.

htmx = HtmxDetails(scope)
  • __bool__() -> bool - Return True if the request was made using HTMX (HX-Request is present), False otherwise.
  • boosted: bool - Mirrors the HX-Boosted header: True if the request is via an element with the hx-boost attribute.
  • current_url: str | None - Mirrors the HX-Current-URL header: The current URL of the browser, or None for non-HTMX requests.
  • history_restore_request: str - Mirrors the HX-History-Restore-Request header: True if the request is for history restoration after a miss in the local history cache.
  • prompt: str | None - Mirrors HX-Prompt: The user response to hx-prompt if it was used, or None.
  • target: str | None - Mirrors HX-Target: The id of the target element if it exists, or None.
  • trigger: str | None - Mirrors HX-Trigger: The id of the trigger element if it exists, or None.
  • trigger_name: str | None - Mirrors HX-Trigger-Name: The name of the trigger element if it exists, or None.
  • triggering_event: Any | None - Mirrors Triggering-Event, which is set by the event-header extension: The deserialized JSON representation of the event that triggered the request if it exists, or None.

HtmxRequest

For Starlette-based frameworks, use this instead of the standard starlette.requests.Request so that code editors understand that request.scope["htmx"] contains an HtmxDetails instance:

from asgi_htmx import HtmxRequest as Request

async def home(request: Request):
    reveal_type(request.scope["htmx"])  # Revealed type is 'HtmxDetails'

License

MIT

asgi-htmx's People

Contributors

euri10 avatar florimondmanca avatar kludex avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

euri10

asgi-htmx's Issues

I am working on a awesome-python-htmx, seeking your feedback

A few of us at PyCon this year got together and brainstormed a new Web Stack that we are calling PyHAT (Python, htmx, ASGI, TailwindCSS). The first thing we set out to do is create awesome-python-htmx; a collection of active tools/libraries/projects in that space.

I like the look of your project, specifically I like that it is trying to be more general (most other projects in this space are build specifically for one framework), but it seems development may have stalled?

In addition to that, if you could also participate in PyHAT-stack/awesome-python-htmx#1 that would be greatly appreciated!

Example code could use block rendering instead of partial templates

Prompted by #8 (comment)

Currently the example code showcases using a custom port of jinja-partials to render a partial template when responding to an HTMX request. The custom port is because we’re testing against Quart too and Jinja-partials didn’t have an integration for it; since the code is so small, I copied it over and added the Quart render_partial helper.

It seems the community is settling on a practice that’s a bit beyond this: rendering a block defined a template (rather than splitting a template across partial files).

This is consistent with non htmx approaches such as the one used by Turbo Frames, where a frame is defined in the returned HTML and by default Turbo will update only that frame when receiving the response.

To currently maintained library for this for Jinja2 seems to be: https://github.com/sponsfreixes/jinja2-fragments

We can consider updating the example code consequently.

CI setup

Need to enable CI for this repository on Azure Pipelines.

ci/ should already contain everything required to run CI.

Let's add the "Build status" badge to the README as well.

is render_partial working ?

salut !

I'm playing a little with this repo, after I spent too much time parsing htmx headers so I like the HTMXDetails class a lot now,

However, I started the example but it seems like instead of rendering html, render_partial is rendering a string of that html ...

see the screenshot for a better description

is there anything I'm doing incorrectly ?
20230529_0802_1063x319_1685340172

Package should be available on PyPI

Let's get asgi-htmx on PyPI.

For this, we should first address #1, then perform an initial release:

  • Bump __version__ to 0.1.0
  • Open a release PR
  • Merge it
  • Create a release on GitHub
  • Ensure publish job runs fine on CI

Anyone using this? Please share!

If anyone is actually using asgi-htmx to integrate htmx with ASGI applications (eg. a Starlette app), feel free to share here.

For context, I built asgi-htmx to mirror django-htmx for all ASGI applications. I'm not using this myself yet. But I'm curious how people use htmx for server-side Starlette applications with templates, and certainly this small integration helps. Also sure folks over at htmx would also be happy to see another example of what people build with htmx. :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.