<h3 dir="auto">First check</h3>
<ul dir="auto">
<li></li>
</ul>
<ul dir="auto">
<li>[ DONE] I added a very descriptive title to this issue.</li>
</ul>
<ul dir="auto">
<li>[ DONE] I used the GitHub search to find a similar issue and didn't find it.</li>
<li>[ DONE] I searched the FastAPI documentation, with the integrated search.</li>
<li>[ DONE] I already searched in Google "How to X in FastAPI" and didn't find any information.</li>
<li>[ DONE] I already read and followed all the tutorial in the docs and didn't find an answer.</li>
<li>[ DONE] I already checked if it is not related to FastAPI but to <a href="https://github.com/samuelcolvin/pydantic">Pydantic</a>.</li>
<li>[ DONE] 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>[ DONE] I already checked if it is not related to FastAPI but to <a href="https://github.com/Redocly/redoc">ReDoc</a>.</li>
<li>[ YES] After submitting this, I commit to one of:
<ul dir="auto">
<li>Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.</li>
<li>I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.</li>
<li>Implement a Pull Request for a confirmed bug.</li>
</ul>
</li>
</ul>
<p dir="auto">There is an issue when moving from default JSON responses to ORJSONResponse. When returning a Dict that uses integers as keys, default json responses will cast them to string, in order to produce valid json output. ORJSON will refuse to serialize this response.</p>
<h3 dir="auto">Example</h3>
<p dir="auto">Here's a self-contained, <a href="https://stackoverflow.com/help/minimal-reproducible-example" rel="nofollow">minimal, reproducible, example</a> with my use case:</p>
<p dir="auto">This works:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from fastapi import FastAPI
from fastapi.responses import ORJSONResponse

app = FastAPI()

@app.get(&quot;/&quot;)
async def dict():
    return {1:2}

if __name__ == &quot;__main__&quot;:
    import uvicorn
    uvicorn.run(&quot;service:app&quot;, port=8001, workers=1)"><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">fastapi</span>.<span class="pl-s1">responses</span> <span class="pl-k">import</span> <span class="pl-v">ORJSONResponse</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">async</span> <span class="pl-k">def</span> <span class="pl-en">dict</span>():
    <span class="pl-k">return</span> {<span class="pl-c1">1</span>:<span class="pl-c1">2</span>}

<span class="pl-k">if</span> <span class="pl-s1">__name__</span> <span class="pl-c1">==</span> <span class="pl-s">"__main__"</span>:
    <span class="pl-k">import</span> <span class="pl-s1">uvicorn</span>
    <span class="pl-s1">uvicorn</span>.<span class="pl-en">run</span>(<span class="pl-s">"service:app"</span>, <span class="pl-s1">port</span><span class="pl-c1">=</span><span class="pl-c1">8001</span>, <span class="pl-s1">workers</span><span class="pl-c1">=</span><span class="pl-c1">1</span>)</pre></div>
<p dir="auto">But this fails:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from fastapi import FastAPI
from fastapi.responses import ORJSONResponse

app = FastAPI(default_response_class=ORJSONResponse,)

@app.get(&quot;/&quot;)
async def dict():
    return {1:2}

if __name__ == &quot;__main__&quot;:
    import uvicorn
    uvicorn.run(&quot;service:app&quot;, port=8001, workers=1)"><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">fastapi</span>.<span class="pl-s1">responses</span> <span class="pl-k">import</span> <span class="pl-v">ORJSONResponse</span>

<span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-v">FastAPI</span>(<span class="pl-s1">default_response_class</span><span class="pl-c1">=</span><span class="pl-v">ORJSONResponse</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">async</span> <span class="pl-k">def</span> <span class="pl-en">dict</span>():
    <span class="pl-k">return</span> {<span class="pl-c1">1</span>:<span class="pl-c1">2</span>}

<span class="pl-k">if</span> <span class="pl-s1">__name__</span> <span class="pl-c1">==</span> <span class="pl-s">"__main__"</span>:
    <span class="pl-k">import</span> <span class="pl-s1">uvicorn</span>
    <span class="pl-s1">uvicorn</span>.<span class="pl-en">run</span>(<span class="pl-s">"service:app"</span>, <span class="pl-s1">port</span><span class="pl-c1">=</span><span class="pl-c1">8001</span>, <span class="pl-s1">workers</span><span class="pl-c1">=</span><span class="pl-c1">1</span>)</pre></div>
<p dir="auto">You can test both behaviours using swagger UI.</p>
<p dir="auto">Also, I don't know if there's something we can do here, since it seems to be the way ORJSON was defined, but I think we can at least add a comment about it in the docs.</p>
<h3 dir="auto">Environment</h3>
<ul dir="auto">
<li>OS: [e.g. Linux / Windows / macOS]: Tested on Ubuntu MATE 18.04, MacOS, and alpine linux</li>
<li>FastAPI Version [e.g. 0.3.0]: 0.63.0 in all cases</li>
<li>Python version: 3.7, 3.8 and 3.9</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="#main.py

from fastapi import FastAPI
from fastapi.openapi.utils import get_openapi

from test_api.router import *

logger = logging.getLogger(__name__)

app = FastAPI(
    title=&quot;test_API&quot;,
    root_path=&quot;/test&quot;,
)

app.include_router(router)

description = &quot;&quot;&quot;
Test API overview
&quot;&quot;&quot;

def custom_openapi():
    if app.openapi_schema:
        return app.openapi_schema
    openapi_schema = get_openapi(
        title=&quot;Test API&quot;,
        version=&quot;0.0.1&quot;,
        description=description,
        routes=app.routes,
    )
    openapi_schema[&quot;info&quot;][&quot;x-logo&quot;] = {
        &quot;url&quot;: &quot;https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png&quot;
    }
    app.openapi_schema = openapi_schema
    return app.openapi_schema

# assign the customized OpenAPI schema
app.openapi = custom_openapi

#router.py

import logging

from fastapi import APIRouter

logger = logging.getLogger(__name__)

router = APIRouter(
    prefix=&quot;/test&quot;,
)

@router.get(
    &quot;/health_check&quot;,
)
def root():
    return {&quot;status&quot;: &quot;Success&quot;}"><pre class="notranslate"><span class="pl-c">#main.py</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">fastapi</span>.<span class="pl-s1">openapi</span>.<span class="pl-s1">utils</span> <span class="pl-k">import</span> <span class="pl-s1">get_openapi</span>

<span class="pl-k">from</span> <span class="pl-s1">test_api</span>.<span class="pl-s1">router</span> <span class="pl-k">import</span> <span class="pl-c1">*</span>

<span class="pl-s1">logger</span> <span class="pl-c1">=</span> <span class="pl-s1">logging</span>.<span class="pl-en">getLogger</span>(<span class="pl-s1">__name__</span>)

<span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-v">FastAPI</span>(
    <span class="pl-s1">title</span><span class="pl-c1">=</span><span class="pl-s">"test_API"</span>,
    <span class="pl-s1">root_path</span><span class="pl-c1">=</span><span class="pl-s">"/test"</span>,
)

<span class="pl-s1">app</span>.<span class="pl-en">include_router</span>(<span class="pl-s1">router</span>)

<span class="pl-s1">description</span> <span class="pl-c1">=</span> <span class="pl-s">"""</span>
<span class="pl-s">Test API overview</span>
<span class="pl-s">"""</span>

<span class="pl-k">def</span> <span class="pl-en">custom_openapi</span>():
    <span class="pl-k">if</span> <span class="pl-s1">app</span>.<span class="pl-s1">openapi_schema</span>:
        <span class="pl-k">return</span> <span class="pl-s1">app</span>.<span class="pl-s1">openapi_schema</span>
    <span class="pl-s1">openapi_schema</span> <span class="pl-c1">=</span> <span class="pl-en">get_openapi</span>(
        <span class="pl-s1">title</span><span class="pl-c1">=</span><span class="pl-s">"Test API"</span>,
        <span class="pl-s1">version</span><span class="pl-c1">=</span><span class="pl-s">"0.0.1"</span>,
        <span class="pl-s1">description</span><span class="pl-c1">=</span><span class="pl-s1">description</span>,
        <span class="pl-s1">routes</span><span class="pl-c1">=</span><span class="pl-s1">app</span>.<span class="pl-s1">routes</span>,
    )
    <span class="pl-s1">openapi_schema</span>[<span class="pl-s">"info"</span>][<span class="pl-s">"x-logo"</span>] <span class="pl-c1">=</span> {
        <span class="pl-s">"url"</span>: <span class="pl-s">"https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png"</span>
    }
    <span class="pl-s1">app</span>.<span class="pl-s1">openapi_schema</span> <span class="pl-c1">=</span> <span class="pl-s1">openapi_schema</span>
    <span class="pl-k">return</span> <span class="pl-s1">app</span>.<span class="pl-s1">openapi_schema</span>

<span class="pl-c"># assign the customized OpenAPI schema</span>
<span class="pl-s1">app</span>.<span class="pl-s1">openapi</span> <span class="pl-c1">=</span> <span class="pl-s1">custom_openapi</span>

<span class="pl-c">#router.py</span>

<span class="pl-k">import</span> <span class="pl-s1">logging</span>

<span class="pl-k">from</span> <span class="pl-s1">fastapi</span> <span class="pl-k">import</span> <span class="pl-v">APIRouter</span>

<span class="pl-s1">logger</span> <span class="pl-c1">=</span> <span class="pl-s1">logging</span>.<span class="pl-en">getLogger</span>(<span class="pl-s1">__name__</span>)

<span class="pl-s1">router</span> <span class="pl-c1">=</span> <span class="pl-v">APIRouter</span>(
    <span class="pl-s1">prefix</span><span class="pl-c1">=</span><span class="pl-s">"/test"</span>,
)

<span class="pl-en">@<span class="pl-s1">router</span>.<span class="pl-en">get</span>(</span>
<span class="pl-en">    <span class="pl-s">"/health_check"</span>,</span>
<span class="pl-en">)</span>
<span class="pl-k">def</span> <span class="pl-en">root</span>():
    <span class="pl-k">return</span> {<span class="pl-s">"status"</span>: <span class="pl-s">"Success"</span>}</pre></div>
<h3 dir="auto">Description</h3>
<p dir="auto">We are using FastAPI alongside ApiGateway on AWS. We have multiple APIs being handled by one Custom domain name so we are required to use API mappings with specific Paths.</p>
<p dir="auto">With the configuration shown all the routes for the API works as well as the documentation or getting the openapi.json file. The only issue is when trying to execute the API from the docs page with the "Try it out" option. Is not adding the prefix so every request is ending up with a 404 error.</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/105293902/210645631-afc721e5-731a-43b6-99a6-4c71f91d2d7c.png"><img src="https://user-images.githubusercontent.com/105293902/210645631-afc721e5-731a-43b6-99a6-4c71f91d2d7c.png" alt="image" style="max-width: 100%;"></a></p>
<p dir="auto">We tried working with routes as well, but this ends up duplicating the prefix and we don't want that.</p>
<p dir="auto">After more testing we found that the issue could be related to the custom_openapi function, if we remove it, the try it out button works. But the rest of the docs does not.</p>
<p dir="auto">Is there any kind of parameter we could use inside this definition to achieve the addition of the prefix only to the execute part without having the need to add a router since this causes the prefix to be duplicated.</p>
<p dir="auto">The request would look like this:</p>
<p dir="auto">curl --location --request GET '<a href="http://127.0.0.1:9999/test/test/health_check" rel="nofollow">http://127.0.0.1:9999/test/test/health_check</a>'</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.88.0</p>
<h3 dir="auto">Python Version</h3>
<p dir="auto">Python 3.8</p>
<h3 dir="auto">Additional Context</h3>
<p dir="auto"><em>No response</em></p>