1

I am trying to to post some data via a request body to my server and for some reason I am getting a msg: "value is not a valid dict", type: "type_error.dict" error.

The backend (built in FastAPI) is working fine, as I am able to get a proper response when using FastAPI's Swagger UI.

I am quite new to JavaScript and AJAX (I mainly work with Python), so I think the issue must be coming from the AJAX function I setup.

My code

main.py (Backend)

from typing import Union
from fastapi import FastAPI, Form
from starlette.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
    "http://localhost:8080",
    "http://127.0.0.1:5500",
    "*"
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

from pydantic import BaseModel

class Item(BaseModel):
    id: int
    name: str
    description: str

@app.post("/items_via_request_body")
def read_item_via_request_body(item: Item):
    #return {"item_id": item.id, "item_description": item.description}
    return {"Hello": "World"}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    

</head>
<body>
    
    <h1>Hello world</h1>
    <button id="request_body_param">Test Request body Parameters</button><br>

    <script>

        $(document).ready(function(){
            
            // Request body parameters
            $("#request_body_param").click(function(){
                console.log('request_body_param pushed')

                $.ajax({
                    url: "http://127.0.0.1:8000/items_via_request_body",
                    type: "POST",
                    data: {
                        id: 123,
                        name: "John",
                        description: "I am a description"
                    },
                    dataType: "json",
                    success: function(data){
                    $("#content").html(data);
                        console.log("SUCCESS: " + JSON.stringify(data));
                    },
                    error: function(data){
                        $("#content").html("Failed to load data. " + JSON.stringify(data));
                        console.log("ERROR: " + JSON.stringify(data));
                    },
                    complete: function(data){
                        console.log("COMPLETED: " + JSON.stringify(data));
                    },
                });
            });
        });

    </script>


</body>
</html>

Any help is really appreciated!

Chris
  • 18,724
  • 6
  • 46
  • 80
DAgu
  • 43
  • 5
  • Related answers can also be found [here](https://stackoverflow.com/a/73761724/17865804), [here](https://stackoverflow.com/a/70636163/17865804), as well as [here](https://stackoverflow.com/a/71023536/17865804), [here](https://stackoverflow.com/a/70640522/17865804) and [here](https://stackoverflow.com/a/71665594/17865804). – Chris Oct 08 '22 at 13:13
  • Thanks for the links! Using forms and the fetch seems to do the trick. Do you know though if it is required for the data to be within a form? Also, do you know why it doesn't work with JQuery, and it does with Fetch? – DAgu Oct 08 '22 at 13:48
  • No, it is not required for the data to be submitted through `
    `. You can instead use, for instance, `body: JSON.stringify({foo: "bar"})`. Please have a closer look at the references above. As for your ajax request, you are most likely missing the `contentType` (see [here](https://stackoverflow.com/q/18701282) and [here](https://stackoverflow.com/q/8517071)); however, I would suggest you stick to [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
    – Chris Oct 08 '22 at 14:14
  • Also, better not to use the `"*"` wildcard in `allow_origins`. Please have a look at [this answer](https://stackoverflow.com/a/73963905/17865804), as well as [this comment](https://stackoverflow.com/questions/65635346/how-can-i-enable-cors-in-fastapi/66460861#comment129957640_66460861) for more details. – Chris Oct 08 '22 at 14:36
  • Thanks for the reminder. Actually, I enabled all the origins to make sure my JS code was not failing because of cors (my real applications has that enabled already). – DAgu Oct 09 '22 at 10:02

1 Answers1

0
from fastapi import FastAPI, Request

# code-stack as in question...

@app.post("/items_via_request_body")
def read_item_via_request_body(request: Request):
    
    form_data = request.form()
    
    # ... Data management operations here ...
    
    return form_data
  • 1
    Thanks for the quick response! However, this answer doesn't make use of the Pydantic's data validation capabilities. I want to ensure that the data provided by the user adheres to the schemas I define. Still, now I know I have an alternative in case I cannot solve the issue I have. – DAgu Oct 08 '22 at 13:36