<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 👆</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, Depends
from pydantic import BaseModel

app: FastAPI = PydanticbasedApi()


def get_current_user():
    return &quot;admin&quot;


@app.post(&quot;/user&quot;)
class CreateUser(BaseModel):
    name: str
    mail: str

    async def __call__(self, user=Depends(get_current_user)):
        return &quot;success&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-v">Depends</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-v">FastAPI</span> <span class="pl-c1">=</span> <span class="pl-v">PydanticbasedApi</span>()


<span class="pl-k">def</span> <span class="pl-en">get_current_user</span>():
    <span class="pl-k">return</span> <span class="pl-s">"admin"</span>


<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">post</span>(<span class="pl-s">"/user"</span>)</span>
<span class="pl-k">class</span> <span class="pl-v">CreateUser</span>(<span class="pl-v">BaseModel</span>):
    <span class="pl-s1">name</span>: <span class="pl-s1">str</span>
    <span class="pl-s1">mail</span>: <span class="pl-s1">str</span>

    <span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">__call__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">user</span><span class="pl-c1">=</span><span class="pl-v">Depends</span>(<span class="pl-s1">get_current_user</span>)):
        <span class="pl-k">return</span> <span class="pl-s">"success"</span></pre></div>
<h3 dir="auto">Description</h3>
<p dir="auto">It is convenient to be able to declare the body like Example Code.<br>
Would you like to support pydantic based api?</p>
<p dir="auto">When declaring a body, it becomes more descriptive and more versatile.</p>
<h3 dir="auto">Wanted Solution</h3>
<p dir="auto">The implementation example of PydanticbasedApi is as follows.</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class PydanticbasedApi(FastAPI):
    @staticmethod
    def wrap_func(func_or_cls):
        import asyncio
        import inspect
        from functools import wraps
        from typing import Callable

        if not inspect.isfunction(func_or_cls) and issubclass(func_or_cls, BaseModel):
            if not issubclass(func_or_cls, Callable):  # type: ignore
                raise TypeError(&quot;Must be Callable.&quot;)

            if asyncio.iscoroutinefunction(func_or_cls.__call__):

                @wraps(func_or_cls.__call__)
                async def wrapper(self, *args, **kwargs):
                    return await self(*args, **kwargs)

            else:

                @wraps(func_or_cls.__call__)
                def wrapper(self, *args, **kwargs):
                    return self(*args, **kwargs)

            wrapper.__name__ = func_or_cls.__name__
            wrapper.__annotations__[&quot;self&quot;] = func_or_cls
            return wrapper

        else:
            return func_or_cls

    def post(self, *args, **kwargs):
        add_func = super().post

        def wrapped(func_or_cls):
            nonlocal add_func
            func = self.wrap_func(func_or_cls)
            add_func = add_func(*args, **kwargs)
            return add_func(func)

        return wrapped"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">PydanticbasedApi</span>(<span class="pl-v">FastAPI</span>):
    <span class="pl-en">@<span class="pl-s1">staticmethod</span></span>
    <span class="pl-k">def</span> <span class="pl-en">wrap_func</span>(<span class="pl-s1">func_or_cls</span>):
        <span class="pl-k">import</span> <span class="pl-s1">asyncio</span>
        <span class="pl-k">import</span> <span class="pl-s1">inspect</span>
        <span class="pl-k">from</span> <span class="pl-s1">functools</span> <span class="pl-k">import</span> <span class="pl-s1">wraps</span>
        <span class="pl-k">from</span> <span class="pl-s1">typing</span> <span class="pl-k">import</span> <span class="pl-v">Callable</span>

        <span class="pl-k">if</span> <span class="pl-c1">not</span> <span class="pl-s1">inspect</span>.<span class="pl-en">isfunction</span>(<span class="pl-s1">func_or_cls</span>) <span class="pl-c1">and</span> <span class="pl-en">issubclass</span>(<span class="pl-s1">func_or_cls</span>, <span class="pl-v">BaseModel</span>):
            <span class="pl-k">if</span> <span class="pl-c1">not</span> <span class="pl-en">issubclass</span>(<span class="pl-s1">func_or_cls</span>, <span class="pl-v">Callable</span>):  <span class="pl-c"># type: ignore</span>
                <span class="pl-k">raise</span> <span class="pl-v">TypeError</span>(<span class="pl-s">"Must be Callable."</span>)

            <span class="pl-k">if</span> <span class="pl-s1">asyncio</span>.<span class="pl-en">iscoroutinefunction</span>(<span class="pl-s1">func_or_cls</span>.<span class="pl-s1">__call__</span>):

                <span class="pl-en">@<span class="pl-en">wraps</span>(<span class="pl-s1">func_or_cls</span>.<span class="pl-s1">__call__</span>)</span>
                <span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">wrapper</span>(<span class="pl-s1">self</span>, <span class="pl-c1">*</span><span class="pl-s1">args</span>, <span class="pl-c1">**</span><span class="pl-s1">kwargs</span>):
                    <span class="pl-k">return</span> <span class="pl-k">await</span> <span class="pl-en">self</span>(<span class="pl-c1">*</span><span class="pl-s1">args</span>, <span class="pl-c1">**</span><span class="pl-s1">kwargs</span>)

            <span class="pl-k">else</span>:

                <span class="pl-en">@<span class="pl-en">wraps</span>(<span class="pl-s1">func_or_cls</span>.<span class="pl-s1">__call__</span>)</span>
                <span class="pl-k">def</span> <span class="pl-en">wrapper</span>(<span class="pl-s1">self</span>, <span class="pl-c1">*</span><span class="pl-s1">args</span>, <span class="pl-c1">**</span><span class="pl-s1">kwargs</span>):
                    <span class="pl-k">return</span> <span class="pl-en">self</span>(<span class="pl-c1">*</span><span class="pl-s1">args</span>, <span class="pl-c1">**</span><span class="pl-s1">kwargs</span>)

            <span class="pl-s1">wrapper</span>.<span class="pl-s1">__name__</span> <span class="pl-c1">=</span> <span class="pl-s1">func_or_cls</span>.<span class="pl-s1">__name__</span>
            <span class="pl-s1">wrapper</span>.<span class="pl-s1">__annotations__</span>[<span class="pl-s">"self"</span>] <span class="pl-c1">=</span> <span class="pl-s1">func_or_cls</span>
            <span class="pl-k">return</span> <span class="pl-s1">wrapper</span>

        <span class="pl-k">else</span>:
            <span class="pl-k">return</span> <span class="pl-s1">func_or_cls</span>

    <span class="pl-k">def</span> <span class="pl-en">post</span>(<span class="pl-s1">self</span>, <span class="pl-c1">*</span><span class="pl-s1">args</span>, <span class="pl-c1">**</span><span class="pl-s1">kwargs</span>):
        <span class="pl-s1">add_func</span> <span class="pl-c1">=</span> <span class="pl-en">super</span>().<span class="pl-s1">post</span>

        <span class="pl-k">def</span> <span class="pl-en">wrapped</span>(<span class="pl-s1">func_or_cls</span>):
            <span class="pl-k">nonlocal</span> <span class="pl-s1">add_func</span>
            <span class="pl-s1">func</span> <span class="pl-c1">=</span> <span class="pl-s1">self</span>.<span class="pl-en">wrap_func</span>(<span class="pl-s1">func_or_cls</span>)
            <span class="pl-s1">add_func</span> <span class="pl-c1">=</span> <span class="pl-en">add_func</span>(<span class="pl-c1">*</span><span class="pl-s1">args</span>, <span class="pl-c1">**</span><span class="pl-s1">kwargs</span>)
            <span class="pl-k">return</span> <span class="pl-en">add_func</span>(<span class="pl-s1">func</span>)

        <span class="pl-k">return</span> <span class="pl-s1">wrapped</span></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="..."><pre class="notranslate">...</pre></div>
<h3 dir="auto">Alternatives</h3>
<p dir="auto"><em>No response</em></p>
<h3 dir="auto">Operating System</h3>
<p dir="auto">Other</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.76.0</p>
<h3 dir="auto">Python Version</h3>
<p dir="auto">Python 3.8.12</p>
<h3 dir="auto">Additional Context</h3>
<p dir="auto"><em>No response</em></p>
<p dir="auto"><strong>Describe the bug</strong><br>
When adding the content-type header to the response headers, this results in a duplicate response header</p>
<p dir="auto"><strong>To Reproduce</strong><br>
Steps to reproduce the behavior:</p>
<ol dir="auto">
<li>Create a python file with the following contents and run it:</li>
</ol>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import uvicorn
from fastapi import FastAPI
from starlette.responses import Response

# Create new application instance
app = FastAPI()

@app.get('/content-type-test')
async def content_type_test(response: Response):
    response.headers['content-type'] = 'application/geo+json'
    return {}


if __name__ == '__main__':
    # Run the application locally
    uvicorn.run(app, host='127.0.0.1', port=8000)"><pre class="notranslate"><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">starlette</span>.<span class="pl-s1">responses</span> <span class="pl-k">import</span> <span class="pl-v">Response</span>

<span class="pl-c"># Create new application instance</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">'/content-type-test'</span>)</span>
<span class="pl-k">async</span> <span class="pl-k">def</span> <span class="pl-en">content_type_test</span>(<span class="pl-s1">response</span>: <span class="pl-v">Response</span>):
    <span class="pl-s1">response</span>.<span class="pl-s1">headers</span>[<span class="pl-s">'content-type'</span>] <span class="pl-c1">=</span> <span class="pl-s">'application/geo+json'</span>
    <span class="pl-k">return</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-c"># Run the application locally</span>
    <span class="pl-s1">uvicorn</span>.<span class="pl-en">run</span>(<span class="pl-s1">app</span>, <span class="pl-s1">host</span><span class="pl-c1">=</span><span class="pl-s">'127.0.0.1'</span>, <span class="pl-s1">port</span><span class="pl-c1">=</span><span class="pl-c1">8000</span>)</pre></div>
<ol start="2" dir="auto">
<li>Use CURL to execute the following command:</li>
</ol>
<div class="highlight highlight-text-shell-session notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="curl -v http://127.0.0.1:8000/content-type-test"><pre class="notranslate"><span class="pl-c1">curl -v http://127.0.0.1:8000/content-type-test</span></pre></div>
<ol start="3" dir="auto">
<li>This results in the following response (notice the duplicate content-type header):</li>
</ol>
<div class="highlight highlight-text-shell-session notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
&gt; GET /content-type-test HTTP/1.1
&gt; Host: 127.0.0.1:8000
&gt; User-Agent: curl/7.58.0
&gt; Accept: */*
&gt;
&lt; HTTP/1.1 200 OK
&lt; date: Mon, 28 Oct 2019 12:33:24 GMT
&lt; server: uvicorn
&lt; content-length: 2
&lt; content-type: application/json
&lt; content-type: application/geo+json
&lt;
* Connection #0 to host 127.0.0.1 left intact
{}"><pre class="notranslate"><span class="pl-c1">*   Trying 127.0.0.1...</span>
<span class="pl-c1">* TCP_NODELAY set</span>
<span class="pl-c1">* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)</span>
&gt; <span class="pl-s1">GET /content-type-test HTTP/1.1</span>
&gt; <span class="pl-s1">Host: 127.0.0.1:8000</span>
&gt; <span class="pl-s1">User-Agent: curl/7.58.0</span>
&gt; <span class="pl-s1">Accept: <span class="pl-k">*</span>/<span class="pl-k">*</span></span>
&gt;
<span class="pl-c1">&lt; HTTP/1.1 200 OK</span>
<span class="pl-c1">&lt; date: Mon, 28 Oct 2019 12:33:24 GMT</span>
<span class="pl-c1">&lt; server: uvicorn</span>
<span class="pl-c1">&lt; content-length: 2</span>
<span class="pl-c1">&lt; content-type: application/json</span>
<span class="pl-c1">&lt; content-type: application/geo+json</span>
<span class="pl-c1">&lt;</span>
<span class="pl-c1">* Connection #0 to host 127.0.0.1 left intact</span>
<span class="pl-c1">{}</span></pre></div>
<p dir="auto"><strong>Expected behavior</strong><br>
I would have expect to only see the <code class="notranslate">content-type: application/geo+json</code> header</p>
<p dir="auto"><strong>Environment:</strong></p>
<ul dir="auto">
<li>OS: Windows</li>
<li>FastAPI Version: 0.42.0</li>
<li>Python version: 3.7.1</li>
</ul>