最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - Passing Integers to FastAPI post endpoint - Stack Overflow

programmeradmin1浏览0评论

I have two endpoints below, one that accepts two integers and another that accepts tow lists of integers.

I also have two post requests that I am making using Python requests. The request for the list of ints endpoint works fine, but the one that just accepts the two ints does not.

I know that if I pass the two ints in the URL (i.e, the query string), the endpoint will work. However, could you tell me why it doesn't work when passed as JSON?

endpoints.py

from fastapi import FastAPI

app = FastAPI()

@app.post('/ints')
def post_int(x: int, y: int):
    return x, y

@app.post('/lists')
def post_list(x: list[int], y: list[int]):
    return x, y

requests.py

import requests

r = requests.post('http://127.0.0.1:8000/ints', json={'x': 1, 'y': 2})
print(r.json()) # returns an error saying that x and y are missing

r = requests.post('http://127.0.0.1:8000/ints?x=1&y=2')
print(r.json()) # returns the two ints

r = requests.post('http://127.0.0.1:8000/lists', json={'x': [1, 2, 5], 'y': [1, 2, 3]})
print(r.json()) # returns the two lists

To start server, run "fastapi dev /path/to/endpoints.py" in terminal. Run requests.py in another terminal for output.

I have two endpoints below, one that accepts two integers and another that accepts tow lists of integers.

I also have two post requests that I am making using Python requests. The request for the list of ints endpoint works fine, but the one that just accepts the two ints does not.

I know that if I pass the two ints in the URL (i.e, the query string), the endpoint will work. However, could you tell me why it doesn't work when passed as JSON?

endpoints.py

from fastapi import FastAPI

app = FastAPI()

@app.post('/ints')
def post_int(x: int, y: int):
    return x, y

@app.post('/lists')
def post_list(x: list[int], y: list[int]):
    return x, y

requests.py

import requests

r = requests.post('http://127.0.0.1:8000/ints', json={'x': 1, 'y': 2})
print(r.json()) # returns an error saying that x and y are missing

r = requests.post('http://127.0.0.1:8000/ints?x=1&y=2')
print(r.json()) # returns the two ints

r = requests.post('http://127.0.0.1:8000/lists', json={'x': [1, 2, 5], 'y': [1, 2, 3]})
print(r.json()) # returns the two lists

To start server, run "fastapi dev /path/to/endpoints.py" in terminal. Run requests.py in another terminal for output.

Share Improve this question edited Mar 14 at 5:35 Chris 35.5k10 gold badges104 silver badges251 bronze badges asked Mar 13 at 15:46 JayJay 591 silver badge7 bronze badges 3
  • @jabaa have included the imports and additional code required to reproduce. – Jay Commented Mar 13 at 16:39
  • 1 In the first case, the data are expected as query params (if also defined in the endpoint's path, as in this, they would be expected as path parameters). If you need them to be expected as JSON data in the request's body instead, have a look at this answer for the various approaches. In the second case, FastAPI would interpret the list parameters as body data by default. To use them as query params instead, you need to explicitly use Query – Chris Commented Mar 13 at 17:52
  • Thanks @Chris, this is really helpful! – Jay Commented Mar 13 at 22:22
Add a comment  | 

1 Answer 1

Reset to default 0

could you tell me why it doesn't work when passed as JSON?

When you register a route with

@app.post('/ints')
def post_int(x: int, y: int):
    return x, y

in FastApi, the route is analyzed and added in

decorator (routing.py)
add_api_route (routing.py)
__init__ (routing.py)
get_dependant (dependencies/utils.py)
analyze_param (dependencies/utils.py)

Near the end of analyze_param, you can find

elif field_info is None and depends is None:
    default_value = value if value is not inspect.Signature.empty else RequiredParam
    if is_path_param:
        # We might check here that `default_value is RequiredParam`, but the fact is that the same
        # parameter might sometimes be a path parameter and sometimes not. See
        # `tests/test_infer_param_optionality.py` for an example.
        field_info = params.Path(annotation=use_annotation)
    elif is_uploadfile_or_nonable_uploadfile_annotation(
        type_annotation
    ) or is_uploadfile_sequence_annotation(type_annotation):
        field_info = params.File(annotation=use_annotation, default=default_value)
    elif not field_annotation_is_scalar(annotation=type_annotation):
        field_info = params.Body(annotation=use_annotation, default=default_value)
    else:
        field_info = params.Query(annotation=use_annotation, default=default_value)

https://github/fastapi/fastapi/blob/master/fastapi/dependencies/utils.py#L460

There you can see that scalar parameters have field info type query. Lists aren't scalar values and have field info type body.

发布评论

评论列表(0)

  1. 暂无评论