Dependency injection failure for unhashable types
See original GitHub issueExample
Suppose you run the following script
export MY_PREFIX_PASSWORD=hello
and then
from fastapi import FastAPI
app = FastAPI()
class MySettings(BaseSettings):
password: SecretStr
base_url: AnyHttpUrl = "https://www.google.com"
localdownload_dir: str = "~/mydir-import"
class Config:
env_prefix = "my_prefix"
def get_settings() -> MySettings:
return MySettings()
@app.get("/")
def read_root(settings:MySettings = Depends(get_settings)):
return {"Hello": "World"}
Description
When you invoke via curl the rest endpoint, you get the following failure:
File "/venv/lib/python3.7/site-packages/uvicorn/protocols/http/httptools_impl.py", line 390, in run_asgi result = await app(self.scope, self.receive, self.send) File "/venv/lib/python3.7/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__ return await self.app(scope, receive, send) File "/venv/lib/python3.7/site-packages/fastapi/applications.py", line 179, in __call__ await super().__call__(scope, receive, send) File "/venv/lib/python3.7/site-packages/starlette/applications.py", line 111, in __call__ await self.middleware_stack(scope, receive, send) File "/venv/lib/python3.7/site-packages/starlette/middleware/errors.py", line 181, in __call__ raise exc from None File "/venv/lib/python3.7/site-packages/starlette/middleware/errors.py", line 159, in __call__ await self.app(scope, receive, _send) File "/venv/lib/python3.7/site-packages/starlette/exceptions.py", line 82, in __call__ raise exc from None File "/venv/lib/python3.7/site-packages/starlette/exceptions.py", line 71, in __call__ await self.app(scope, receive, sender) File "/venv/lib/python3.7/site-packages/starlette/routing.py", line 566, in __call__ await route.handle(scope, receive, send) File "/venv/lib/python3.7/site-packages/starlette/routing.py", line 227, in handle await self.app(scope, receive, send) File "/venv/lib/python3.7/site-packages/starlette/routing.py", line 41, in app response = await func(request) File "/venv/lib/python3.7/site-packages/fastapi/routing.py", line 176, in app dependency_overrides_provider=dependency_overrides_provider, File "/venv/lib/python3.7/site-packages/fastapi/dependencies/utils.py", line 552, in solve_dependencies solved = await run_in_threadpool(call, **sub_values) File "/venv/lib/python3.7/site-packages/starlette/concurrency.py", line 34, in run_in_threadpool return await loop.run_in_executor(None, func, *args) File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run result = self.fn(*self.args, **self.kwargs) TypeError: unhashable type: 'MySettings'
Environment
- OS: [e.g. Linux / Windows / macOS]: MACOS
- FastAPI Version = “0.61.0”
- Python version: 3.7.3
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:12 (1 by maintainers)
Top GitHub Comments
This documentation section shows that we can use a dependency with
Depends
which uses@lru_cache
. I followed this docs and had the same problem described by this issue.Should the docs be updated to remove the usage of
@lru_cache
or can it be useful in some cases?Just ran into the same issue. Looks like
pydantic
does not implement a__hash__()
method for its models as of now: https://github.com/samuelcolvin/pydantic/pull/1881. ~So, I guess we should update the documentation, or do I miss something?~ (edit: see next comment)I guess, in general, it makes sense to document the use of
lru_cache
, as otherwise, the dependency generator is called for every request instead of just once. Additionally, it might be useful to explicitly state thatlru_cache
only works for hashable objects.Anyway, we can work around that issue for now by either let
fastapi
call the method multiple times, implement a__hash__()
method for theSettings
class or implement a custom caching mechanism, eg.