<h3 dir="auto">Describe the bug</h3>
<p dir="auto">KeyError when two classes contain inner classes with the same name. If i rename one of the inner classes, app runs good.</p>
<h3 dir="auto">To Reproduce</h3>
<p dir="auto">Steps to reproduce the behavior with a minimum self-contained file.</p>
<p dir="auto">Replace each part with your own scenario:</p>
<ol dir="auto">
<li>Create a file with:</li>
</ol>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from __future__ import annotations

from typing import Union

import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel


class X(BaseModel):
    class A(BaseModel):
        pass

    a: X.A


X.update_forward_refs()


class Y(BaseModel):
    class A(BaseModel):
        pass

    y: Y.A


Y.update_forward_refs()

app = FastAPI()


@app.get(&quot;/&quot;)
def route(request: Union[X, Y]):
    return str(request)"><pre class="notranslate"><span class="pl-k">from</span> __future__ <span class="pl-k">import</span> <span class="pl-s1">annotations</span>

<span class="pl-k">from</span> <span class="pl-s1">typing</span> <span class="pl-k">import</span> <span class="pl-v">Union</span>

<span class="pl-k">import</span> <span class="pl-s1">uvicorn</span>
<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-k">class</span> <span class="pl-v">X</span>(<span class="pl-v">BaseModel</span>):
    <span class="pl-k">class</span> <span class="pl-v">A</span>(<span class="pl-v">BaseModel</span>):
        <span class="pl-k">pass</span>

    <span class="pl-s1">a</span>: <span class="pl-v">X</span>.<span class="pl-v">A</span>


<span class="pl-v">X</span>.<span class="pl-en">update_forward_refs</span>()


<span class="pl-k">class</span> <span class="pl-v">Y</span>(<span class="pl-v">BaseModel</span>):
    <span class="pl-k">class</span> <span class="pl-v">A</span>(<span class="pl-v">BaseModel</span>):
        <span class="pl-k">pass</span>

    <span class="pl-s1">y</span>: <span class="pl-v">Y</span>.<span class="pl-v">A</span>


<span class="pl-v">Y</span>.<span class="pl-en">update_forward_refs</span>()

<span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-v">FastAPI</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">route</span>(<span class="pl-s1">request</span>: <span class="pl-v">Union</span>[<span class="pl-v">X</span>, <span class="pl-v">Y</span>]):
    <span class="pl-k">return</span> <span class="pl-en">str</span>(<span class="pl-s1">request</span>)</pre></div>
<ol start="3" dir="auto">
<li>Open the browser and call the endpoint <code class="notranslate">/docs</code>.</li>
<li>It show <code class="notranslate">Fetch error Internal Server Error /openapi.json</code> and the app raise an error</li>
</ol>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="  File &quot;/usr/local/lib/python3.7/site-packages/fastapi/utils.py&quot;, line 64, in get_model_definitions
    model_name = model_name_map[model]
KeyError: &lt;class '__main__.X.A'&gt;"><pre class="notranslate">  <span class="pl-v">File</span> <span class="pl-s">"/usr/local/lib/python3.7/site-packages/fastapi/utils.py"</span>, <span class="pl-s1">line</span> <span class="pl-c1">64</span>, <span class="pl-s1">in</span> <span class="pl-s1">get_model_definitions</span>
    <span class="pl-s1">model_name</span> <span class="pl-c1">=</span> <span class="pl-s1">model_name_map</span>[<span class="pl-s1">model</span>]
<span class="pl-v">KeyError</span>:<span class="pl-s1"></span> <span class="pl-c1">&lt;</span><span class="pl-s1">class</span> <span class="pl-s">'__main__.X.A'</span><span class="pl-c1">&gt;</span></pre></div>
<h3 dir="auto">Environment</h3>
<ul dir="auto">
<li>OS: MacOS</li>
<li>FastAPI Version : 0.55.1</li>
<li>Python: 3.8.2</li>
</ul>
<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, Request
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseSettings


class Settings(BaseSettings):
    token_url: str

def get_settings() -&gt; Settings:
    return Settings()


app = FastAPI()


def get_oauth2_scheme(settings=Depends(get_settings)):
    return OAuth2PasswordBearer(tokenUrl=settings.token_url)

async def use_token(request: Request, oauth2_scheme=Depends(get_oauth2_scheme)):
    return await oauth2_scheme(request)

@app.get(&quot;/items/&quot;)
async def read_items(token: str = Depends(use_token)):
    return {&quot;token&quot;: token}"><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-v">Request</span>
<span class="pl-k">from</span> <span class="pl-s1">fastapi</span>.<span class="pl-s1">security</span> <span class="pl-k">import</span> <span class="pl-v">OAuth2PasswordBearer</span>
<span class="pl-k">from</span> <span class="pl-s1">pydantic</span> <span class="pl-k">import</span> <span class="pl-v">BaseSettings</span>


<span class="pl-k">class</span> <span class="pl-v">Settings</span>(<span class="pl-v">BaseSettings</span>):
    <span class="pl-s1">token_url</span>: <span class="pl-s1">str</span>

<span class="pl-k">def</span> <span class="pl-en">get_settings</span>() <span class="pl-c1">-&gt;</span> <span class="pl-v">Settings</span>:
    <span class="pl-k">return</span> <span class="pl-v">Settings</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">get_oauth2_scheme</span>(<span class="pl-s1">settings</span><span class="pl-c1">=</span><span class="pl-v">Depends</span>(<span class="pl-s1">get_settings</span>)):
    <span class="pl-k">return</span> <span class="pl-v">OAuth2PasswordBearer</span>(<span class="pl-s1">tokenUrl</span><span class="pl-c1">=</span><span class="pl-s1">settings</span>.<span class="pl-s1">token_url</span>)

<span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">use_token</span>(<span class="pl-s1">request</span>: <span class="pl-v">Request</span>, <span class="pl-s1">oauth2_scheme</span><span class="pl-c1">=</span><span class="pl-v">Depends</span>(<span class="pl-s1">get_oauth2_scheme</span>)):
    <span class="pl-k">return</span> <span class="pl-k">await</span> <span class="pl-en">oauth2_scheme</span>(<span class="pl-s1">request</span>)

<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">get</span>(<span class="pl-s">"/items/"</span>)</span>
<span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">read_items</span>(<span class="pl-s1">token</span>: <span class="pl-s1">str</span> <span class="pl-c1">=</span> <span class="pl-v">Depends</span>(<span class="pl-s1">use_token</span>)):
    <span class="pl-k">return</span> {<span class="pl-s">"token"</span>: <span class="pl-s1">token</span>}</pre></div>
<h3 dir="auto">Description</h3>
<ol dir="auto">
<li>Run saved script, for example: <code class="notranslate">TOKEN_URL="token" uvicorn tmp:app</code></li>
<li>Navigate to <a href="http://127.0.0.1:8000/docs" rel="nofollow">http://127.0.0.1:8000/docs</a></li>
<li>Notice there is no "Authorize" button in docs</li>
<li>Endpoint is protected, a request fails with a 401 error</li>
</ol>
<h3 dir="auto">Wanted Solution</h3>
<p dir="auto">The Dependency Injection system doesn't seem to be fully resolving these dependencies so it can auto-detect the authentication mechanism. It seems to only resolve first surface level dependencies. This seems to apply to any Depends()<br>
objects for authorization, either in route definitions or route signatures.</p>
<h3 dir="auto">Wanted Code</h3>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="(The example/reproduction code working would be great, no extra syntax needed)"><pre class="notranslate">(<span class="pl-v">The</span> <span class="pl-s1">example</span><span class="pl-c1">/</span><span class="pl-s1">reproduction</span> <span class="pl-s1">code</span> <span class="pl-s1">working</span> <span class="pl-s1">would</span> <span class="pl-s1">be</span> <span class="pl-s1">great</span>, <span class="pl-s1">no</span> <span class="pl-s1">extra</span> <span class="pl-s1">syntax</span> <span class="pl-s1">needed</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">Linux</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.37.0</p>
<h3 dir="auto">Python Version</h3>
<p dir="auto">3.9</p>
<h3 dir="auto">Additional Context</h3>
<p dir="auto">Discussion in Discord here: <a href="https://discord.com/channels/772607987558252564/772631203689922562/942107142859673732" rel="nofollow">https://discord.com/channels/772607987558252564/772631203689922562/942107142859673732</a></p>
<p dir="auto"><a href="https://cdn.discordapp.com/attachments/772631203689922562/942107232315777094/unknown.png" rel="nofollow">https://cdn.discordapp.com/attachments/772631203689922562/942107232315777094/unknown.png</a></p>