<p dir="auto">Also raised on <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="408498979" data-permission-text="Title is private" data-url="https://github.com/tiangolo/fastapi/issues/26" data-hovercard-type="pull_request" data-hovercard-url="/tiangolo/fastapi/pull/26/hovercard?comment_id=562755647&amp;comment_type=issue_comment" href="https://github.com/tiangolo/fastapi/pull/26#issuecomment-562755647">#26 (comment)</a>. See also <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="494702028" data-permission-text="Title is private" data-url="https://github.com/tiangolo/fastapi/issues/544" data-hovercard-type="issue" data-hovercard-url="/tiangolo/fastapi/issues/544/hovercard" href="https://github.com/tiangolo/fastapi/issues/544">#544</a>.</p>
<h3 dir="auto">Describe the bug</h3>
<p dir="auto">Write here a clear and concise description of what the bug is.</p>
<h3 dir="auto">To Reproduce</h3>
<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 fastapi import FastAPI

app = FastAPI()

@app.get(&quot;/app&quot;)
def read_root():
    return {&quot;Hello&quot;: &quot;World&quot;}"><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-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">"/app"</span>)</span>
<span class="pl-k">def</span> <span class="pl-en">read_root</span>():
    <span class="pl-k">return</span> {<span class="pl-s">"Hello"</span>: <span class="pl-s">"World"</span>}</pre></div>
<ol start="2" dir="auto">
<li>Launch it using <code class="notranslate">uvicorn --root-path="bar" test_app:app</code></li>
<li>Open the browser and go to <code class="notranslate">http://127.0.0.1:8000/docs</code>.</li>
<li>From the documentation, call the <code class="notranslate">GET /app</code> route.</li>
<li>The doc page calls <code class="notranslate">/app</code> and succeeds.</li>
</ol>
<h3 dir="auto">Expected behavior</h3>
<p dir="auto">The above test should fail after having called <code class="notranslate">/bar/app</code>, since <code class="notranslate">root_path</code> is supposed to prefix all generated URLs in case the application is served behind a reverse-proxy, among ther things. FastAPI only acknowledges <code class="notranslate">openapi_prefix</code> for the API doc.</p>
<h3 dir="auto">Environment</h3>
<ul dir="auto">
<li>OS: Windows</li>
<li>FastAPI Version: 0.45.0</li>
<li>Python version: 3.8.0</li>
</ul>
<h3 dir="auto">Additional context</h3>
<p dir="auto">A similar issue applies to sub-applications:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from fastapi import FastAPI

app = FastAPI()


@app.get(&quot;/app&quot;)
def read_main():
    return {&quot;message&quot;: &quot;Hello World from main app&quot;}


#subapi = FastAPI(openapi_prefix=&quot;/subapi&quot;)
subapi = FastAPI()

@subapi.get(&quot;/sub&quot;)
def read_sub(request: Request):
    return {
        &quot;root_path&quot;: request.scope['root_path'],
        &quot;raw_path&quot;: request.scope['raw_path'],
        &quot;path&quot;: request.scope['path'],
        &quot;app_url_for&quot;: app.url_path_for(&quot;read_sub&quot;),
        &quot;subapp_url_for&quot;: subapi.url_path_for(&quot;read_sub&quot;),
    }

app.mount(&quot;/subapi&quot;, subapi)"><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-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">"/app"</span>)</span>
<span class="pl-k">def</span> <span class="pl-en">read_main</span>():
    <span class="pl-k">return</span> {<span class="pl-s">"message"</span>: <span class="pl-s">"Hello World from main app"</span>}


<span class="pl-c">#subapi = FastAPI(openapi_prefix="/subapi")</span>
<span class="pl-s1">subapi</span> <span class="pl-c1">=</span> <span class="pl-v">FastAPI</span>()

<span class="pl-en">@<span class="pl-s1">subapi</span>.<span class="pl-en">get</span>(<span class="pl-s">"/sub"</span>)</span>
<span class="pl-k">def</span> <span class="pl-en">read_sub</span>(<span class="pl-s1">request</span>: <span class="pl-v">Request</span>):
    <span class="pl-k">return</span> {
        <span class="pl-s">"root_path"</span>: <span class="pl-s1">request</span>.<span class="pl-s1">scope</span>[<span class="pl-s">'root_path'</span>],
        <span class="pl-s">"raw_path"</span>: <span class="pl-s1">request</span>.<span class="pl-s1">scope</span>[<span class="pl-s">'raw_path'</span>],
        <span class="pl-s">"path"</span>: <span class="pl-s1">request</span>.<span class="pl-s1">scope</span>[<span class="pl-s">'path'</span>],
        <span class="pl-s">"app_url_for"</span>: <span class="pl-s1">app</span>.<span class="pl-en">url_path_for</span>(<span class="pl-s">"read_sub"</span>),
        <span class="pl-s">"subapp_url_for"</span>: <span class="pl-s1">subapi</span>.<span class="pl-en">url_path_for</span>(<span class="pl-s">"read_sub"</span>),
    }

<span class="pl-s1">app</span>.<span class="pl-en">mount</span>(<span class="pl-s">"/subapi"</span>, <span class="pl-s1">subapi</span>)</pre></div>
<div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;root_path&quot;:&quot;bar/subapi&quot;,
  &quot;raw_path&quot;:&quot;/subapi/sub&quot;,
  &quot;path&quot;:&quot;/sub&quot;,
  &quot;app_url_for&quot;:&quot;/subapi/sub&quot;,
  &quot;subapp_url_for&quot;:&quot;/sub&quot;
}"><pre class="notranslate">{
  <span class="pl-ent">"root_path"</span>:<span class="pl-s"><span class="pl-pds">"</span>bar/subapi<span class="pl-pds">"</span></span>,
  <span class="pl-ent">"raw_path"</span>:<span class="pl-s"><span class="pl-pds">"</span>/subapi/sub<span class="pl-pds">"</span></span>,
  <span class="pl-ent">"path"</span>:<span class="pl-s"><span class="pl-pds">"</span>/sub<span class="pl-pds">"</span></span>,
  <span class="pl-ent">"app_url_for"</span>:<span class="pl-s"><span class="pl-pds">"</span>/subapi/sub<span class="pl-pds">"</span></span>,
  <span class="pl-ent">"subapp_url_for"</span>:<span class="pl-s"><span class="pl-pds">"</span>/sub<span class="pl-pds">"</span></span>
}</pre></div>
<p dir="auto">(<code class="notranslate">url_for</code> not being prefixed with <code class="notranslate">root_path</code> is fixed upstream by <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="516102365" data-permission-text="Title is private" data-url="https://github.com/encode/starlette/issues/699" data-hovercard-type="pull_request" data-hovercard-url="/encode/starlette/pull/699/hovercard" href="https://github.com/encode/starlette/pull/699">encode/starlette#699</a>)</p>
<p dir="auto">Unless <code class="notranslate">openapi_prefix="/subapi"</code> is passed when creating the subapplication, both <code class="notranslate">http://127.0.0.1:8000/docs</code> and <code class="notranslate">http://127.0.0.1:8000/subapi/docs</code> will point towards <code class="notranslate">http://127.0.0.1:8000/openapi.json</code>, which goes against the point of having isolated subapplications.</p>
<p dir="auto"><code class="notranslate">openapi_prefix</code> should probably just be deprecated and assumed to match <code class="notranslate">root_path</code> if absent.</p>
<p dir="auto">It would be nice to have a way to exclude fields from a model when using it to type a query/body parameter. My use case is a post request where a user needs to pass all the fields for a model except the id. The id is generated in the app when they make the post.</p>
<h3 dir="auto">Example</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 Widget(BaseModel):
    id = str
    foo = str
    bar = str

@app.post(&quot;/widgets&quot;)
def r(foo: str, bar: str):
    w = Widget(id=gen_id(), foo=foo, bar=bar)
    ..."><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">Widget</span>(<span class="pl-v">BaseModel</span>):
    <span class="pl-s1">id</span> <span class="pl-c1">=</span> <span class="pl-s1">str</span>
    <span class="pl-s1">foo</span> <span class="pl-c1">=</span> <span class="pl-s1">str</span>
    <span class="pl-s1">bar</span> <span class="pl-c1">=</span> <span class="pl-s1">str</span>

<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">post</span>(<span class="pl-s">"/widgets"</span>)</span>
<span class="pl-k">def</span> <span class="pl-en">r</span>(<span class="pl-s1">foo</span>: <span class="pl-s1">str</span>, <span class="pl-s1">bar</span>: <span class="pl-s1">str</span>):
    <span class="pl-s1">w</span> <span class="pl-c1">=</span> <span class="pl-v">Widget</span>(<span class="pl-s1">id</span><span class="pl-c1">=</span><span class="pl-en">gen_id</span>(), <span class="pl-s1">foo</span><span class="pl-c1">=</span><span class="pl-s1">foo</span>, <span class="pl-s1">bar</span><span class="pl-c1">=</span><span class="pl-s1">bar</span>)
    ...</pre></div>
<p dir="auto">This means my code is more verbose because I have to type out every field/type in the model in the signature. Something like the following that returns a duplicated class that hides the field from the user.</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@app.post(&quot;/widgets&quot;)
def r(widget: Widget.exclude('id')):
    widget.id = gen_id()
    ..."><pre class="notranslate"><span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">post</span>(<span class="pl-s">"/widgets"</span>)</span>
<span class="pl-k">def</span> <span class="pl-en">r</span>(<span class="pl-s1">widget</span>: <span class="pl-v">Widget</span>.<span class="pl-en">exclude</span>(<span class="pl-s">'id'</span>)):
    <span class="pl-s1">widget</span>.<span class="pl-s1">id</span> <span class="pl-c1">=</span> <span class="pl-en">gen_id</span>()
    ...</pre></div>