jpsca / jinjax

Server-Side Components with Jinja
https://jinjax.scaletti.dev/
MIT License
290 stars 16 forks source link

Using `catalog.get_middleware` with FastAPI #72

Open MLackner opened 2 months ago

MLackner commented 2 months ago

Hi,

I have a problem getting the necessary middleware to run with FastAPI. The documention is specific to a Flask app:

from flask import Flask
from jinjax import Catalog

app = Flask(__name__)

# Here we add the Flask Jinja globals, filters, etc., like `url_for()`
catalog = jinjax.Catalog(jinja_env=app.jinja_env)

catalog.add_folder("myapp/components")

app.wsgi_app = catalog.get_middleware(
    app.wsgi_app,
    autorefresh=app.debug,
)

I was not able to transfer that example to FastAPI. Did anyone get this to work? 😊

Kokoserver commented 1 month ago

i also tried this but the result is a string rather than html

Kokoserver commented 1 month ago

@MLackner have you been able to make it work with fastapi

# I'm using lilya framework, but this work, 
# this should be the equivalent with fastapi
from lilya.templating import Jinja2Template
from jinjax import Catalog

templates = Jinja2Template(directory="templates")

catalog = Catalog(jinja_env=templates.env)
catalog.add_folder("templates/components")

@router.get("/")
async def welcome() -> Response:
    result = catalog.render("Hello", name="Welcome")
    return Response(result, status_code=200, media_type="text/html")
mardiros commented 1 month ago

Hello @MLackner

I use fastapi with JinjaX without using the get_middeware. I create a FastAPI dependency instead.

Unfortunatly, my code is mode complex than the lilya exemple above, but you can read a bit of how it works here:

I have a jinjax renderer helper here that also handle CSRF tokens since I post form.

https://github.com/mardiros/fastlife/blob/main/src/fastlife/templating/renderer/jinjax.py

And I have a binding that get the renderer and return the renderer in order to render it.

https://github.com/mardiros/fastlife/blob/main/src/fastlife/templating/binding.py

You can note here that the magic content/type is set with some code like

data = catalog.render("HelloWorld",  ...)
resp = Response(data, headers={"Content-Type": content_type})

Then, an exemple of how I use the template dependency. https://github.com/mardiros/fastlife/blob/main/tests/fastlife_app/views/home.py#L15