2
respostas

Erro na execução do projeto final fornecido pelo curso

Tentei acompanhar o projeto e foi tudo bem até o capítulo 3. Quando começou a parte de frontend , mesmo no primeiro teste quando tentava o http://localhost:8000/ já dava erro. (Internal Error ) Se tentasse o endereço com '/clientes' devolvia o json ok, mas a parte de frontend não funcionava. Não consegui entender e não pude mais acompanhar pelo meu projeto.

No final do curso, peguei o codigo no github e tentei usar o docker (fiz build e depois mandei executar):
docker run --rm -p 8080:8000 techlog:v1
Mas ao testar no browser recebi o mesmo erro no endereço //localhost:8080 : Internal error.
Não consigo colocar todo log, vou colocar o começo do log e o finalzinho dele

(Parte inicial do log:)
INFO: Started server process [1]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
Banco de dados inicializado
INFO: 172.18.0.1:50020 - "GET / HTTP/1.1" 303 See Other
INFO: 172.18.0.1:50020 - "GET /login HTTP/1.1" 307 Temporary Redirect
INFO: 172.18.0.1:50020 - "GET /login/ HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/usr/local/lib/python3.14/site-packages/uvicorn/protocols/http/httptools_impl.py", line 421, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
self.scope, self.receive, self.send
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/usr/local/lib/python3.14/site-packages/uvicorn/middleware/proxy_headers.py", line 56, in call
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.14/site-packages/fastapi/applications.py", line 1159, in call
await super().call(scope, receive, send)
File "/usr/local/lib/python3.14/site-packages/starlette/applications.py", line 90, in call
await self.middleware_stack(scope, receive, send)
File "/usr/local/lib/python3.14/site-packages/starlette/middleware/errors.py", line 186, in call
raise exc
File "/usr/local/lib/python3.14/site-packages/starlette/middleware/errors.py", line 164, in call
await self.app(scope, receive, _send)
File "/usr/local/lib/python3.14/site-packages/starlette/middleware/base.py", line 191, in call
with recv_stream, send_stream, collapse_excgroups():
~~~~~~~~~~~~~~~~~~^^
File "/usr/local/lib/python3.14/contextlib.py", line 162, in exit
self.gen.throw(value)
~~~~~~~~~~~~~~^^^^^^^
File "/usr/local/lib/python3.14/site-packages/starlette/_utils.py", line 87, in collapse_excgroups
raise exc
File "/usr/local/lib/python3.14/site-packages/starlette/middleware/base.py", line 193, in call
response = await self.dispatch_func(request, call_next)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/app/autenticacao_middleware.py", line 11, in dispatch
return await call_next(request)
^^^^^^^^^^^^^^^^^^^^^^^^
(...)

(parte final do log)
(...)
File "/usr/local/lib/python3.14/site-packages/starlette/templating.py", line 148, in TemplateResponse
template = self.get_template(name)
File "/usr/local/lib/python3.14/site-packages/starlette/templating.py", line 115, in get_template
return self.env.get_template(name)
~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/usr/local/lib/python3.14/site-packages/jinja2/environment.py", line 1016, in get_template
return self._load_template(name, globals)
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.14/site-packages/jinja2/environment.py", line 964, in _load_template
template = self.cache.get(cache_key)
File "/usr/local/lib/python3.14/site-packages/jinja2/utils.py", line 477, in get
return self[key]
~~~~^^^^^
File "/usr/local/lib/python3.14/site-packages/jinja2/utils.py", line 515, in getitem
rv = self._mapping[key]
~~~~~~~~~~~~~^^^^^
TypeError: cannot use 'tuple' as a dict key (unhashable type: 'dict')

Poderia me ajudar? grata!

2 respostas

Olá, Amanda. Como vai?

Analisei cuidadosamente o log que você compartilhou e o erro é bastante específico. Embora o log mostre várias camadas de execução, o "ponto de ignição" está nas últimas linhas, onde o Jinja2 (o motor de templates que o FastAPI usa para o frontend) tenta carregar um arquivo HTML.

O erro TypeError: cannot use 'tuple' as a dict key (unhashable type: 'dict') dentro do jinja2 ao tentar buscar um template é um comportamento conhecido que ocorre devido a uma incompatibilidade de versões entre o Jinja2 e as versões mais recentes do Python (especificamente do Python 3.12 em diante, e notei que você está usando o 3.14 no Docker).

Isso acontece porque algumas estruturas internas do Jinja2 mudaram a forma como lidam com o cache de templates, e versões antigas da biblioteca tentam usar dicionários de forma que o Python mais novo não permite mais.

Para resolver isso, você tem dois caminhos principais:

1. Atualizar as dependências no Docker

A forma mais definitiva de resolver é garantir que o Jinja2 esteja em uma versão atualizada (3.1.x ou superior). No seu arquivo requirements.txt do projeto, verifique se a versão está fixada. Você pode tentar alterar para:

jinja2>=3.1.2

Depois, reconstrua a imagem do Docker para que ele instale a versão correta:

docker build -t techlog:v2 .

2. Ajustar a versão do Python no Dockerfile

Se você preferir manter as bibliotecas exatamente como o instrutor deixou, o ideal é usar uma versão do Python mais próxima da que foi usada na gravação do curso (geralmente 3.10 ou 3.11). No seu arquivo Dockerfile, altere a primeira linha para:

FROM python:3.11-slim

Por que o JSON funciona e o Frontend não?

Isso explica por que o /clientes funciona (ele devolve apenas dados puros, sem passar pelo Jinja2), mas a raiz / ou o /login falham, pois eles tentam renderizar um arquivo .html usando o StaticFiles ou Jinja2Templates.

Um detalhe sobre o Middleware

Notei no log que o erro passa pelo seu autenticacao_middleware.py. Se após corrigir a versão o erro persistir com uma mensagem diferente, verifique se o middleware está tentando passar um objeto de contexto para o template de forma incorreta. Mas, pelo rastro do erro atual, o culpado é realmente o sistema de cache do Jinja2 com o Python novo.

Tente atualizar a biblioteca ou baixar a versão do Python no Docker e veja se o frontend volta a carregar!

Espero que possa ter lhe ajudado!

Tentei todas as opções e não deu certo. Se deixo a versão 3.14 e tento instalar o Jinja mais novo continua com mesmo erro.
Se baixo para versão 3.10 ou 3.11 dá outro erro.
Abaixo log de erro quando baixo no Dockerfile para versão 3.11-slim

           ^^^^^^^^^^^^^^^^

File "/usr/local/lib/python3.11/site-packages/fastapi/routing.py", line 674, in app
raw_response = await run_endpoint_function(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/fastapi/routing.py", line 328, in run_endpoint_function
return await dependant.call(**values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/app/rotas/login.py", line 20, in pagina_login
return templates.TemplateResponse("login.html", {"request": request})
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/starlette/templating.py", line 148, in TemplateResponse
template = self.get_template(name)
^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/starlette/templating.py", line 115, in get_template
return self.env.get_template(name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/jinja2/environment.py", line 1016, in get_template
return self._load_template(name, globals)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/jinja2/environment.py", line 964, in _load_template
template = self.cache.get(cache_key)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/jinja2/utils.py", line 477, in get
return self[key]
~~~~^^^^^
File "/usr/local/lib/python3.11/site-packages/jinja2/utils.py", line 515, in getitem
rv = self._mapping[key]
~~~~~~~~~~~~~^^^^^
TypeError: unhashable type: 'dict'

Tem alguma outra dica? grata!