Fastapi: Allow None to be used as a valid json value.

Created on 30 Jun 2020  ·  8Comments  ·  Source: tiangolo/fastapi

First check

  • [X] I added a very descriptive title to this issue.
  • [X] I used the GitHub search to find a similar issue and didn't find it.
  • [X] I searched the FastAPI documentation, with the integrated search.
  • [X] I already searched in Google "How to X in FastAPI" and didn't find any information.
  • [X] I already read and followed all the tutorial in the docs and didn't find an answer.
  • [X] I already checked if it is not related to FastAPI but to Pydantic.
  • [X] I already checked if it is not related to FastAPI but to Swagger UI.
  • [X] 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.

Description

ATM, if you receive a post with the following json: {data: null}

And you have the following definition:

@app.post("/")
def post_data(data: Optional[str] = Body(...)):
  pass

FastAPI will say data was not passed. That's because it internally uses None as a placeholder for non-existing fields, instead of a sentinel value.

I wish to explicitly require null as one of the possible values, and not put a default value of None.

I've attempted to open a PR, but it failed. It looks like the issue is with dependencies.utils.request_body_to_args using None as a default value for value.

Environment

  • OS: [e.g. Linux / Windows / macOS]: macOS
  • FastAPI Version [e.g. 0.3.0]: 0.58.1
  • Python version: 3.8.3
answered question

All 8 comments

Well, in your example data is not a json. You're trying to use it as a Query.

You're probably aiming for:

from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Data(BaseModel):
    data: Optional[str]

@app.post("/")
def post_data(data: Data):
    return data

Which works just fine.

@Kludex Updated example, meant to use it with Body(...). Perhaps it works only in a model and not as a body param?

I've never tried receiving a string from a Body, not sure what expect from this notation. I'm not sure if doing that makes sense by definition. The way I interpret your code is: you're passing a JSON and then trying to catch it with an Optional[str].

On my example you validate your JSON with Data, using the data field (sorry about the similarity of the class and property names).

I'm passing a json, extracting the data field from the json, validating the data field as Optional[str].

It's all supported and works well, until the data field in the json is set to null. Then the whole world explodes and I'm left crying :cry:

If i’m not wrong “...” means that a value must exists maybe changing body(...) to body(any) should works

If i’m not wrong “...” means that a value must exists maybe changing body(...) to body(any) should works

It exists. None or null is a value. If someone explicitly gave me None, I'd like to accept it as a possible value.
Atm I can only resolve to workarounds such as parsing the json myself...

Try with Any or Union[Any, None]
I’m not on computer now

Thanks for the help here everyone! :clap: :bow:

@bharel If you solved the original problem, then you can close this issue :heavy_check_mark:

Otherwise, please make a minimum app that can show how to replicate the problem. Something that can be run directly with Uvicorn. That way me or others can try it and see the problem.

Was this page helpful?
0 / 5 - 0 ratings