<h3 dir="auto">First Check</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I added a very descriptive title to this issue.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I used the GitHub search to find a similar issue and didn't find it.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I searched the FastAPI documentation, with the integrated search.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already searched in Google "How to X in FastAPI" and didn't find any information.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already read and followed all the tutorial in the docs and didn't find an answer.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/samuelcolvin/pydantic">Pydantic</a>.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/swagger-api/swagger-ui">Swagger UI</a>.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/Redocly/redoc">ReDoc</a>.</li>
</ul>
<h3 dir="auto">Commit to Help</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I commit to help with one of those options <g-emoji class="g-emoji" alias="point_up_2" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f446.png">👆</g-emoji></li>
</ul>
<h3 dir="auto">Example Code</h3>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class MyBaseModel(BaseModel):
    def __hash__(self):  # make hashable BaseModel subclass
        return hash((type(self),) + tuple(self.__dict__.values()))

class NestedItems(MyBaseModel):
    name: str

class Items(MyBaseModel):
    items: set[NestedItems]

@app.post(&quot;/offers/&quot;)
async def create_items(items: Items):
    return items
"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">fastapi</span> <span class="pl-k">import</span> <span class="pl-v">FastAPI</span>
<span class="pl-k">from</span> <span class="pl-s1">pydantic</span> <span class="pl-k">import</span> <span class="pl-v">BaseModel</span>

<span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-v">FastAPI</span>()

<span class="pl-k">class</span> <span class="pl-v">MyBaseModel</span>(<span class="pl-v">BaseModel</span>):
    <span class="pl-k">def</span> <span class="pl-en">__hash__</span>(<span class="pl-s1">self</span>):  <span class="pl-c"># make hashable BaseModel subclass</span>
        <span class="pl-k">return</span> <span class="pl-en">hash</span>((<span class="pl-en">type</span>(<span class="pl-s1">self</span>),) <span class="pl-c1">+</span> <span class="pl-en">tuple</span>(<span class="pl-s1">self</span>.<span class="pl-s1">__dict__</span>.<span class="pl-en">values</span>()))

<span class="pl-k">class</span> <span class="pl-v">NestedItems</span>(<span class="pl-v">MyBaseModel</span>):
    <span class="pl-s1">name</span>: <span class="pl-s1">str</span>

<span class="pl-k">class</span> <span class="pl-v">Items</span>(<span class="pl-v">MyBaseModel</span>):
    <span class="pl-s1">items</span>: <span class="pl-s1">set</span>[<span class="pl-v">NestedItems</span>]

<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">post</span>(<span class="pl-s">"/offers/"</span>)</span>
<span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">create_items</span>(<span class="pl-s1">items</span>: <span class="pl-v">Items</span>):
    <span class="pl-k">return</span> <span class="pl-s1">items</span></pre></div>
<p dir="auto">This can be tested with the following command:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="uvicorn mre:app --reload &amp;
curl -X 'POST' \
  'http://127.0.0.1:8000/offers/' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  &quot;items&quot;: [
    {
          &quot;name&quot;: &quot;string&quot;
    }
  ]
}'"><pre class="notranslate">uvicorn mre:app --reload <span class="pl-k">&amp;</span>
curl -X <span class="pl-s"><span class="pl-pds">'</span>POST<span class="pl-pds">'</span></span> \
  <span class="pl-s"><span class="pl-pds">'</span>http://127.0.0.1:8000/offers/<span class="pl-pds">'</span></span> \
  -H <span class="pl-s"><span class="pl-pds">'</span>accept: application/json<span class="pl-pds">'</span></span> \
  -H <span class="pl-s"><span class="pl-pds">'</span>Content-Type: application/json<span class="pl-pds">'</span></span> \
  -d <span class="pl-s"><span class="pl-pds">'</span>{</span>
<span class="pl-s">  "items": [</span>
<span class="pl-s">    {</span>
<span class="pl-s">          "name": "string"</span>
<span class="pl-s">    }</span>
<span class="pl-s">  ]</span>
<span class="pl-s">}<span class="pl-pds">'</span></span></pre></div>
<h3 dir="auto">Description</h3>
<ul dir="auto">
<li>The following command triggers the error <code class="notranslate">TypeError: unhashable type: 'dict'</code>.</li>
<li>It works if I replace <code class="notranslate">NestedItems</code> by a simple <code class="notranslate">str</code>.</li>
<li>It works if I replace <code class="notranslate">set</code> by a simple <code class="notranslate">list</code>.</li>
</ul>
<h3 dir="auto">Operating System</h3>
<p dir="auto">Linux</p>
<h3 dir="auto">Operating System Details</h3>
<p dir="auto">Ubuntu 22.04</p>
<h3 dir="auto">FastAPI Version</h3>
<p dir="auto">0.86.0</p>
<h3 dir="auto">Python Version</h3>
<p dir="auto">3.11.0</p>
<h3 dir="auto">Additional Context</h3>
<p dir="auto"><em>No response</em></p>
<h3 dir="auto">First Check</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I added a very descriptive title to this issue.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I used the GitHub search to find a similar issue and didn't find it.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I searched the FastAPI documentation, with the integrated search.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already searched in Google "How to X in FastAPI" and didn't find any information.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already read and followed all the tutorial in the docs and didn't find an answer.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/samuelcolvin/pydantic">Pydantic</a>.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/swagger-api/swagger-ui">Swagger UI</a>.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I already checked if it is not related to FastAPI but to <a href="https://github.com/Redocly/redoc">ReDoc</a>.</li>
</ul>
<h3 dir="auto">Commit to Help</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I commit to help with one of those options <g-emoji class="g-emoji" alias="point_up_2" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f446.png">👆</g-emoji></li>
</ul>
<h3 dir="auto">Example Code</h3>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from fastapi import Depends, FastAPI

app = FastAPI()


def dependency() -&gt; int:
    return 99


@app.get(&quot;/&quot;)
def read_root(my_int: int = Depends(dependency)):
    return {&quot;an_int&quot;: my_int}"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">fastapi</span> <span class="pl-k">import</span> <span class="pl-v">Depends</span>, <span class="pl-v">FastAPI</span>

<span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-v">FastAPI</span>()


<span class="pl-k">def</span> <span class="pl-en">dependency</span>() <span class="pl-c1">-&gt;</span> <span class="pl-s1">int</span>:
    <span class="pl-k">return</span> <span class="pl-c1">99</span>


<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">get</span>(<span class="pl-s">"/"</span>)</span>
<span class="pl-k">def</span> <span class="pl-en">read_root</span>(<span class="pl-s1">my_int</span>: <span class="pl-s1">int</span> <span class="pl-c1">=</span> <span class="pl-v">Depends</span>(<span class="pl-s1">dependency</span>)):
    <span class="pl-k">return</span> {<span class="pl-s">"an_int"</span>: <span class="pl-s1">my_int</span>}</pre></div>
<h3 dir="auto">Description</h3>
<p dir="auto">Is there any reason that Depends does not use generics to automatically type hint the injected dependency?</p>
<p dir="auto">Currently, the  Depends function's return is typed as Any:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="def Depends(  # noqa: N802
    dependency: Optional[Callable[..., Any]] = None, *, use_cache: bool = True
) -&gt; Any:
    return params.Depends(dependency=dependency, use_cache=use_cache)"><pre class="notranslate"><span class="pl-k">def</span> <span class="pl-v">Depends</span>(  <span class="pl-c"># noqa: N802</span>
    <span class="pl-s1">dependency</span>: <span class="pl-v">Optional</span>[<span class="pl-v">Callable</span>[..., <span class="pl-v">Any</span>]] <span class="pl-c1">=</span> <span class="pl-c1">None</span>, <span class="pl-c1">*</span>, <span class="pl-s1">use_cache</span>: <span class="pl-s1">bool</span> <span class="pl-c1">=</span> <span class="pl-c1">True</span>
) <span class="pl-c1">-&gt;</span> <span class="pl-v">Any</span>:
    <span class="pl-k">return</span> <span class="pl-s1">params</span>.<span class="pl-v">Depends</span>(<span class="pl-s1">dependency</span><span class="pl-c1">=</span><span class="pl-s1">dependency</span>, <span class="pl-s1">use_cache</span><span class="pl-c1">=</span><span class="pl-s1">use_cache</span>)</pre></div>
<p dir="auto">This leads to a lot of duplicate code writing the type hints when defining an endpoint, for example:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@router.post(&quot;/&quot;, response_model=FileRead)
async def upload_file(
    *,
    file: UploadFile,
    session: Session = Depends(get_session),
    user: OIDCUser = Depends(get_user),
    file_manager: AsnycBaseFileManager = Depends(get_file_manager),
) -&gt; File:
    ...

@router.get(&quot;/content/{file_id}&quot;)
async def get_file_content(
    *,
    file_id: int,
    session: Session = Depends(get_session),
    file_manager: AsyncBaseFileManager = Depends(get_file_manager),
) -&gt; StreamingResponse:
   ..."><pre class="notranslate"><span class="pl-en">@<span class="pl-s1">router</span>.<span class="pl-en">post</span>(<span class="pl-s">"/"</span>, <span class="pl-s1">response_model</span><span class="pl-c1">=</span><span class="pl-v">FileRead</span>)</span>
<span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">upload_file</span>(
    <span class="pl-c1">*</span>,
    <span class="pl-s1">file</span>: <span class="pl-v">UploadFile</span>,
    <span class="pl-s1">session</span>: <span class="pl-v">Session</span> <span class="pl-c1">=</span> <span class="pl-v">Depends</span>(<span class="pl-s1">get_session</span>),
    <span class="pl-s1">user</span>: <span class="pl-v">OIDCUser</span> <span class="pl-c1">=</span> <span class="pl-v">Depends</span>(<span class="pl-s1">get_user</span>),
    <span class="pl-s1">file_manager</span>: <span class="pl-v">AsnycBaseFileManager</span> <span class="pl-c1">=</span> <span class="pl-v">Depends</span>(<span class="pl-s1">get_file_manager</span>),
) <span class="pl-c1">-&gt;</span> <span class="pl-v">File</span>:
    ...

<span class="pl-en">@<span class="pl-s1">router</span>.<span class="pl-en">get</span>(<span class="pl-s">"/content/{file_id}"</span>)</span>
<span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">get_file_content</span>(
    <span class="pl-c1">*</span>,
    <span class="pl-s1">file_id</span>: <span class="pl-s1">int</span>,
    <span class="pl-s1">session</span>: <span class="pl-v">Session</span> <span class="pl-c1">=</span> <span class="pl-v">Depends</span>(<span class="pl-s1">get_session</span>),
    <span class="pl-s1">file_manager</span>: <span class="pl-v">AsyncBaseFileManager</span> <span class="pl-c1">=</span> <span class="pl-v">Depends</span>(<span class="pl-s1">get_file_manager</span>),
) <span class="pl-c1">-&gt;</span> <span class="pl-v">StreamingResponse</span>:
   ...</pre></div>
<p dir="auto">There is also room for human error if you write the wrong type hint, with no static type checking tools being able to prevent this.</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/44192816/164703476-0ffc0298-01b1-4be7-8f46-28d289178b2c.png"><img src="https://user-images.githubusercontent.com/44192816/164703476-0ffc0298-01b1-4be7-8f46-28d289178b2c.png" alt="image" style="max-width: 100%;"></a></p>
<p dir="auto">It is possible to use Generics to properly type hint the Depends function:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="T = TypeVar(&quot;T&quot;)

def Depends(  # noqa: N802
    dependency: Optional[Callable[..., T]] = None, *, use_cache: bool = True
) -&gt; T:
    return params.Depends(dependency=dependency, use_cache=use_cache)"><pre class="notranslate"><span class="pl-v">T</span> <span class="pl-c1">=</span> <span class="pl-v">TypeVar</span>(<span class="pl-s">"T"</span>)

<span class="pl-k">def</span> <span class="pl-v">Depends</span>(  <span class="pl-c"># noqa: N802</span>
    <span class="pl-s1">dependency</span>: <span class="pl-v">Optional</span>[<span class="pl-v">Callable</span>[..., <span class="pl-v">T</span>]] <span class="pl-c1">=</span> <span class="pl-c1">None</span>, <span class="pl-c1">*</span>, <span class="pl-s1">use_cache</span>: <span class="pl-s1">bool</span> <span class="pl-c1">=</span> <span class="pl-c1">True</span>
) <span class="pl-c1">-&gt;</span> <span class="pl-v">T</span>:
    <span class="pl-k">return</span> <span class="pl-s1">params</span>.<span class="pl-v">Depends</span>(<span class="pl-s1">dependency</span><span class="pl-c1">=</span><span class="pl-s1">dependency</span>, <span class="pl-s1">use_cache</span><span class="pl-c1">=</span><span class="pl-s1">use_cache</span>)</pre></div>
<p dir="auto">This leads to automatically having the correct type hints:</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/44192816/164704235-43fe1ef5-4d2e-4745-beac-653a8cb40b0f.png"><img src="https://user-images.githubusercontent.com/44192816/164704235-43fe1ef5-4d2e-4745-beac-653a8cb40b0f.png" alt="image" style="max-width: 100%;"></a></p>
<p dir="auto">Is there a reason Depends explicitly returns Any, instead of an unbounded TypeVar? If not I am happy to PR this and PR documentation if necessary.</p>
<h3 dir="auto">Wanted Solution</h3>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="T = TypeVar(&quot;T&quot;)

def Depends(  # noqa: N802
    dependency: Optional[Callable[..., T]] = None, *, use_cache: bool = True
) -&gt; T:
    return params.Depends(dependency=dependency, use_cache=use_cache)"><pre class="notranslate"><code class="notranslate">T = TypeVar("T")

def Depends(  # noqa: N802
    dependency: Optional[Callable[..., T]] = None, *, use_cache: bool = True
) -&gt; T:
    return params.Depends(dependency=dependency, use_cache=use_cache)
</code></pre></div>
<h3 dir="auto">Wanted Code</h3>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from fastapi import Depends, FastAPI

app = FastAPI()


def dependency() -&gt; int:
    return 99


@app.get(&quot;/&quot;)
def read_root(my_int = Depends(dependency)):
    return {&quot;an_int&quot;: my_int}"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">fastapi</span> <span class="pl-k">import</span> <span class="pl-v">Depends</span>, <span class="pl-v">FastAPI</span>

<span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-v">FastAPI</span>()


<span class="pl-k">def</span> <span class="pl-en">dependency</span>() <span class="pl-c1">-&gt;</span> <span class="pl-s1">int</span>:
    <span class="pl-k">return</span> <span class="pl-c1">99</span>


<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">get</span>(<span class="pl-s">"/"</span>)</span>
<span class="pl-k">def</span> <span class="pl-en">read_root</span>(<span class="pl-s1">my_int</span> <span class="pl-c1">=</span> <span class="pl-v">Depends</span>(<span class="pl-s1">dependency</span>)):
    <span class="pl-k">return</span> {<span class="pl-s">"an_int"</span>: <span class="pl-s1">my_int</span>}</pre></div>
<h3 dir="auto">Alternatives</h3>
<p dir="auto"><em>No response</em></p>
<h3 dir="auto">Operating System</h3>
<p dir="auto">Windows</p>
<h3 dir="auto">Operating System Details</h3>
<p dir="auto"><em>No response</em></p>
<h3 dir="auto">FastAPI Version</h3>
<p dir="auto">0.75.2</p>
<h3 dir="auto">Python Version</h3>
<p dir="auto">3.9.12</p>
<h3 dir="auto">Additional Context</h3>
<p dir="auto"><em>No response</em></p>