Skip to main content

FastAPI data APIs with HTMX support.

Project description

Tests Linters Documentation PyPI package

Source code: https://github.com/volfpeter/fasthx

Documentation and examples: https://volfpeter.github.io/fasthx

FastHX

FastAPI and HTMX, the right way.

Key features:

  • Decorator syntax that works with FastAPI as one would expect, no need for unused or magic dependencies in routes.
  • Works with any templating engine or server-side rendering rendering library, e.g. markyp-html or dominate.
  • Built-in Jinja2 templating support (even with multiple template folders).
  • Gives the rendering engine access to all dependencies of the decorated route.
  • FastAPI routes will keep working normally by default if they receive non-HTMX requests, so the same route can serve data and render HTML at the same time.
  • Correct typing makes it possible to apply other (typed) decorators to your routes.
  • Works with both sync and async routes.

Installation

The package is available on PyPI and can be installed with:

$ pip install fasthx

Examples

Jinja2 templating

To start serving HTMX requests, all you need to do is create an instance of fasthx.Jinja and use it as a decorator on your routes like this:

from fastapi import FastAPI
from fastapi.templating import Jinja2Templates
from fasthx import Jinja

# Create the app.
app = FastAPI()

# Create a FastAPI Jinja2Templates instance and use it to create a
# FastHX Jinja instance that will serve as your decorator.
jinja = Jinja(Jinja2Templates("templates"))

@app.get("/htmx-or-data")
@jinja("user-list.html")  # Render the response with the user-list.html template.
def htmx_or_data() -> dict[str, list[dict[str, str]]]:
    return {"users": [{"name": "Joe"}]}

@app.get("/htmx-only")
@jinja.template("user-list.html", no_data=True)  # Render the response with the user-list.html template.
def htmx_only() -> dict[str, list[dict[str, str]]]:
    # no_data is set to True, so this route can not serve JSON, it only responds to HTMX requests.
    return {"users": [{"name": "Joe"}]}

Custom templating

Custom templating offers more flexibility than the built-in Jinja renderer by giving access to all dependencies of the decorated route to the renderer function:

from typing import Annotated

from fastapi import Depends, FastAPI
from fasthx import hx

# Create a dependecy to see that its return value is available in the render function.
def get_random_number() -> int:
    return 4  # Chosen by fair dice roll.

DependsRandomNumber = Annotated[int, Depends(get_random_number)]

# Create the render method: it must always have these three arguments.
# If you're using static type checkers, the type hint of `result` must match the return type
# annotation of the route on which this render method is used.
def render_user_list(result: list[dict[str, str]], *, context: dict[str, Any], request: Request) -> str:
    # The value of the `DependsRandomNumber` dependency is accessible with the same name as in the route.
    random_number = context["random_number"]
    lucky_number = f"<h1>{random_number}</h1>"
    users = "".join(("<ul>", *(f"<li>{u.name}</li>" for u in result), "</ul>"))
    return f"{lucky_number}\n{users}"

@app.get("/htmx-or-data")
@hx(render_user_list)
def htmx_or_data(random_number: DependsRandomNumber) -> list[dict[str, str]]:
    return [{"name": "Joe"}]

@app.get("/htmx-only")
@hx(render_user_list, no_data=True)
async def htmx_only(random_number: DependsRandomNumber) -> list[dict[str, str]]:
    return [{"name": "Joe"}]

Dependencies

The only dependency of this package is fastapi.

Development

Use ruff for linting and formatting, mypy for static code analysis, and pytest for testing.

The documentation is built with mkdocs-material and mkdocstrings.

Contributing

All contributions are welcome.

License - MIT

The package is open-sourced under the conditions of the MIT license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fasthx-0.2401.0.tar.gz (5.5 kB view hashes)

Uploaded Source

Built Distribution

fasthx-0.2401.0-py3-none-any.whl (5.9 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page