FastAPI data APIs with HTMX support.
Project description
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
ordominate
. - 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for fasthx-0.2401.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6cd9a856a1e82309101f5cc76be6789268e0516a64bac645da8c5ad579dda2aa |
|
MD5 | 2720a5e06a78feddfcd129631306f23f |
|
BLAKE2b-256 | f4738b1affe037e02ad511c7157128bc49baedb9b7f18091e626db9459a016a5 |