-
First Check
Commit to Help
Example Codefrom fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
templates = Jinja2Templates(directory=".")
class Prop:
@property
def no_crash(self) -> str:
return 'Hello World'
@property
def should_crash(self) -> str:
return self.item
class NoProp:
def no_crash(self) -> str:
return 'Hello World'
def should_crash(self) -> str:
return self.item
app = FastAPI()
@app.get("/noprop")
async def read_noprop(request: Request):
return templates.TemplateResponse(request=request, name='noprop.html', context={'item': NoProp()})
@app.get("/prop")
async def read_prop(request: Request):
return templates.TemplateResponse(request=request, name='prop.html', context={'item': Prop()})
import uvicorn
if __name__ == "__main__":
uvicorn.run("__main__:app", host="0.0.0.0", port=8080, reload=True)Descriptiongist with the python file and two html files here: https://gist.github.com/kratsg/3a1bb76833d1f28b0c6b8b57325cd5b8 Create two html files in the same working directory. One called One called Run the above file and navigate to both endpoints:
You get the following stack trace Stack traceINFO: 127.0.0.1:61954 - "GET /prop HTTP/1.1" 200 OK
INFO: 127.0.0.1:61954 - "GET /noprop HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 411, in run_asgi
result = await app( # type: ignore[func-returns-value]
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 69, in __call__
return await self.app(scope, receive, send)
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/fastapi/applications.py", line 1054, in __call__
await super().__call__(scope, receive, send)
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/starlette/applications.py", line 123, in __call__
await self.middleware_stack(scope, receive, send)
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/starlette/middleware/errors.py", line 186, in __call__
raise exc
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/starlette/middleware/errors.py", line 164, in __call__
await self.app(scope, receive, _send)
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 62, in __call__
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
raise exc
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
await app(scope, receive, sender)
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/starlette/routing.py", line 758, in __call__
await self.middleware_stack(scope, receive, send)
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/starlette/routing.py", line 778, in app
await route.handle(scope, receive, send)
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/starlette/routing.py", line 299, in handle
await self.app(scope, receive, send)
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/starlette/routing.py", line 79, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
raise exc
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
await app(scope, receive, sender)
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/starlette/routing.py", line 74, in app
response = await func(request)
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/fastapi/routing.py", line 278, in app
raw_response = await run_endpoint_function(
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/fastapi/routing.py", line 191, in run_endpoint_function
return await dependant.call(**values)
File "/Users/kratsg/audrey-two/debug_template_error.py", line 27, in read_noprop
return templates.TemplateResponse(request=request, name='noprop.html', context={'item': NoProp()})
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/starlette/templating.py", line 230, in TemplateResponse
return _TemplateResponse(
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/starlette/templating.py", line 40, in __init__
content = template.render(context)
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/jinja2/environment.py", line 1301, in render
self.environment.handle_exception()
File "/Users/kratsg/audrey-two/venv/lib/python3.10/site-packages/jinja2/environment.py", line 936, in handle_exception
raise rewrite_traceback_stack(source=source)
File "noprop.html", line 3, in top-level template code
{{ item.should_crash() }}
File "/Users/kratsg/audrey-two/debug_template_error.py", line 20, in should_crash
return self.item
AttributeError: 'NoProp' object has no attribute 'item'
Operating SystemmacOS Operating System DetailsFastAPI Version0.110.0 Pydantic Version2.6.4 Python VersionPython 3.10.13 Additional ContextI can't tell if this is a problem at the Jinja2 level, the Starlette level, or the FastAPI level. I will first start at the highest level before working downwards (I think this is maybe the safest assumption?) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
|
Indeed, this is not a FastAPI or Starlette issue. Debugging even further, it seems there's something funny happening with import jinja2
class Prop:
@property
def no_crash(self) -> str:
return 'Hello World'
@property
def should_crash(self) -> str:
return self.item
class NoProp:
def no_crash(self) -> str:
return 'Hello World'
def should_crash(self) -> str:
return self.item
environment = jinja2.Environment()
template_noprop = environment.from_string("""{{ item.no_crash() }}
{{ item.should_crash() }}""")
template_prop = environment.from_string("""{{ item.no_crash }}
{{ item.should_crash }}""")
print('Running NoProp')
try:
print(template_noprop.render(item=NoProp()))
except Exception:
print('NoProp crashed')
print('-'*20)
print('Running Prop')
try:
print(template_prop.render(item=Prop()))
except Exception:
print('Prop crashed')Running this gives $ python debug_template_error_jinja2.py
Running NoProp
NoProp crashed
--------------------
Running Prop
Hello World
So I will close this and file a corresponding issue in jinja2. |
Beta Was this translation helpful? Give feedback.
Indeed, this is not a FastAPI or Starlette issue. Debugging even further, it seems there's something funny happening with
jinja2. This example demonstrates the somewhat strange behavior