Issue 1:
First Check

I added a very descriptive title to this issue.

I used the GitHub search to find a similar issue and didn't find it.

I searched the FastAPI documentation, with the integrated search.

I already searched in Google "How to X in FastAPI" and didn't find any information.

I already read and followed all the tutorial in the docs and didn't find an answer.

I already checked if it is not related to FastAPI but to Pydantic.

I already checked if it is not related to FastAPI but to Swagger UI.

I already checked if it is not related to FastAPI but to ReDoc.

Commit to Help

I commit to help with one of those options 👆

Example Code

from fastapi import FastAPI, Depends
from pydantic import BaseModel

app: FastAPI = PydanticbasedApi()

def get_current_user():
return "admin"

@app.post("/user")
class CreateUser(BaseModel):
name: str
mail: str

async def __call__(self, user=Depends(get_current_user)):
return "success"

Description

It is convenient to be able to declare the body like Example Code.

Would you like to support pydantic based api?

When declaring a body, it becomes more descriptive and more versatile.

Wanted Solution

The implementation example of PydanticbasedApi is as follows.

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("Must be Callable.")

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__["self"] = 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

Wanted Code

...

Alternatives

No response

Operating System

Other

Operating System Details

No response

FastAPI Version

0.76.0

Python Version

Python 3.8.12

Additional Context

No response

Issue 2:
Describe the bug

When adding the content-type header to the response headers, this results in a duplicate response header

To Reproduce

Steps to reproduce the behavior:

Create a python file with the following contents and run it:

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)

Use CURL to execute the following command:

curl -v http://127.0.0.1:8000/content-type-test

This results in the following response (notice the duplicate content-type header):

* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
> GET /content-type-test HTTP/1.1
> Host: 127.0.0.1:8000
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
< date: Mon, 28 Oct 2019 12:33:24 GMT
< server: uvicorn
< content-length: 2
< content-type: application/json
< content-type: application/geo+json
<
* Connection #0 to host 127.0.0.1 left intact
{}

Expected behavior

I would have expect to only see the content-type: application/geo+json header

Environment:

OS: Windows

FastAPI Version: 0.42.0

Python version: 3.7.1