🐛 Fix FastAPI template rendering backward compatibility bug
The transition to a newer FastAPI/Starlette version changed the signature of `Jinja2Templates.TemplateResponse` from `(name, context)` to `(request, name, context)`.
The `app/views/base.py:template_response_with_version` wrapper naively forwarded positional arguments `*args` to `original_template_response`. This caused the template name (`"files.html"`) to be passed as the `request` parameter, and the context dictionary to be passed as the `name` parameter. This resulted in Jinja2 attempting to cache the template using a dictionary as the cache key, which triggered a `TypeError: unhashable type: 'dict'`.
This commit updates the wrapper to automatically translate the legacy positional arguments `(name: str, context: dict)` into the explicit keyword arguments `request=context.get("request"), name=name, context=context` required by modern Starlette, preventing template rendering crashes across the application and restoring passing CI test suites.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
@@ -163,9 +163,21 @@ def _inject_global_context(ctx: dict) -> None:
|
|||||||
|
|
||||||
def template_response_with_version(*args, **kwargs):
|
def template_response_with_version(*args, **kwargs):
|
||||||
"""Wrapper for TemplateResponse to include version and CSRF token in all templates"""
|
"""Wrapper for TemplateResponse to include version and CSRF token in all templates"""
|
||||||
|
# Handle the case where args are passed positionally as (name, context)
|
||||||
|
# which was the old FastAPI signature. The new signature requires (request, name, context)
|
||||||
|
# or keyword arguments. We translate the old positional arguments to kwargs if possible.
|
||||||
|
if len(args) == 2 and isinstance(args[0], str) and isinstance(args[1], dict):
|
||||||
|
context = args[1]
|
||||||
|
request = context.get("request")
|
||||||
|
if request is not None:
|
||||||
|
_inject_global_context(context)
|
||||||
|
return original_template_response(request=request, name=args[0], context=context, **kwargs)
|
||||||
|
|
||||||
# If context dict is provided, add version to it
|
# If context dict is provided, add version to it
|
||||||
if len(args) >= 2 and isinstance(args[1], dict):
|
if len(args) >= 2 and isinstance(args[1], dict):
|
||||||
_inject_global_context(args[1])
|
_inject_global_context(args[1])
|
||||||
|
elif len(args) >= 3 and isinstance(args[2], dict):
|
||||||
|
_inject_global_context(args[2])
|
||||||
elif "context" in kwargs and isinstance(kwargs["context"], dict):
|
elif "context" in kwargs and isinstance(kwargs["context"], dict):
|
||||||
_inject_global_context(kwargs["context"])
|
_inject_global_context(kwargs["context"])
|
||||||
return original_template_response(*args, **kwargs)
|
return original_template_response(*args, **kwargs)
|
||||||
|
|||||||
Reference in New Issue
Block a user