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.

After submitting this, I commit to one of:

Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.

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.

Implement a Pull Request for a confirmed bug.

Example

Here's a self-contained, minimal, reproducible, example with my use case:

from typing import Optional

from fastapi import Depends, FastAPI
from pydantic import BaseModel

# Models as shown in https://fastapi.tiangolo.com/tutorial/extra-models/
class Command(BaseModel):
name: str
game: int = 0
template: str
cooldown: int

class UpdateCommand(BaseModel):
name: str
game: int = 0
template: Optional[str]
cooldown: Optional[int]

app = FastAPI()

async def get_cmd_from_db_dep(name: str, game: Optional[int] = 0) -> Command:
pass

async def get_cmd_from_db_by_update_cmd(update_cmd: UpdateCommand) -> Command:
return await get_cmd_from_db_dep(update_cmd.name, update_cmd.game)

# Expects query args name and game, perfect for a get call
@app.get("/command", response_model=Command)
async def get_command(cmd: Command = Depends(get_cmd_from_db_dep)):
pass

# Expects query args name and game as well as a UpdateCommand in the body which will
# contain the name and game as well. Less desirable.
@app.post("/command", response_model=Command)
async def update_command(
update_cmd: UpdateCommand, cmd: Command = Depends(get_cmd_from_db_dep)
):
pass

# Expects a UpdateCommand in the body but requires an extra wrapper around
# `get_cmd_from_db_dep`
@app.post("/command_2", response_model=Command)
async def update_command_also(
update_cmd: UpdateCommand, cmd2: Command = Depends(get_cmd_from_db_by_update_cmd)
):
pass

Description

I am making a simple CRUD api, but I am hitting a weird pattern I feel like I am doing something wrong.

The above example will make a get api call that wants name and game ( My two pieces of my primary key essentially) which is perfect.

However, the update post wants both the name and game defined as query args AND the body to contain a name and game as well as the fields that are changing.

The only way I had found to get around this was defining "wrapper" dependencies such as get_cmd_from_db_by_update_cmd, which looks how I would like:

Is there a different way to define the dependency or the arguments to make it so that if I get a model that contains the arguments it will pass them to the dependency instead of expecting them as separate query args?

Environment

OS: [e.g. Linux / Windows / macOS]: Windows 10

FastAPI Version [e.g. 0.3.0]: 0.61.1

Python version: 3.7.9

Additional context

Obligatory, my model is actually a little more complicated than that, but the ideas conveyed are what I am after. Also, I LOVE the project, I just want to make sure I am doing things right with it!

Issue 2:
Hi there!

I'm trying to send a post with a JSON that might contain a \n character in one of its fields. I tried what is explained here https://pydantic-docs.helpmanual.io/usage/exporting_models/ with no success. I can run the example there with no problems but when used in the app it crashes when it tries to parse the input json.

The sample code:

import json
from fastapi import FastAPI
from pydantic import BaseModel

def new_json_loads(*args, **kwargs):
kwargs.update(dict(strict=False))
return json.loads(*args, **kwargs)

class Request(BaseModel):
name = "John Doe"
class Config:
json_loads = new_json_loads

r = Request.parse_raw('{\n "name": "john \n doe"\n}')
# It runs!
print(r)

app = FastAPI()

# It does not run here when a request arrives
@app.post("/test")
def read_root(request: Request):
return request

Description

Open the browser and call the endpoint http://0.0.0.0:8000/docs#/default/read_root_test_post.

Try it out with: { "name": "john doe" }. Don't forget to enter a new line after the word John

The 422 error returns

{
"detail": [
{
"loc": [
"body",
18
],
"msg": "Invalid control character at: line 2 column 17 (char 18)",
"type": "value_error.jsondecode",
"ctx": {
"msg": "Invalid control character at",
"doc": "{\n \"name\": \"john \ndoe\"\n}",
"pos": 18,
"lineno": 2,
"colno": 17
}
}
]
}

Environment

OS: [e.g. Linux / Windows / macOS]: Linux 20.04

FastAPI Version [e.g. 0.3.0]: 0.61.1

Python version: 3.7.8

Thanks for your help!