libcpr / cpr

C++ Requests: Curl for People, a spiritual port of Python Requests.
https://docs.libcpr.org/
Other
6.29k stars 903 forks source link

Correct way to post JSON data/payload (to a FastAPI python server app) #1066

Closed TuxxuT closed 1 week ago

TuxxuT commented 2 weeks ago

Description

Please, I want to know what is the correct way to send JSON data to fastAPI app? I tried many many things, but nothing seems to work...

Example/How to Reproduce

For example:

Python part (server side)

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    vorname: str
    nachname: str | None = None
    alter: int
    gewicht: float | None = None

@app.post("/items/")
async def create_item(item: Item):
    return item

The JSON payload data has this structure

{ "vorname": "string", "nachname": "string", "alter": 0, "gewicht": 0 }

CPP part (client):

// POST REQUEST
    cpr::Response postRequest = cpr::Post(cpr::Url{"http://127.0.0.1:8000/items"},
                    cpr::Header{{"Content-Type", "application/json"}},
                   cpr::Payload{ 
                        {"vorname", "test"}, 
                        {"nachname", "test"}, 
                        {"alter", "12"}, {"gewicht", "35"} });
    std::cout << postRequest.text << std::endl;

Unfortuntly this does not work. When I run the cpp executable I get the following error message: {"detail":[{"type":"json_invalid","loc":["body",0],"msg":"JSON decode error","input":{},"ctx":{"error":"Expecting value"}}]}

Possible Fix

No response

Where did you get it from?

GitHub (branch e.g. master)

Additional Context/Your Environment

TuxxuT commented 2 weeks ago

This also does not work:

std::string json_data{" \"vorname\": \"string\", \"nachname\": \"string\", \"alter\": 0, \"gewicht\": 0 "};

    // POST REQUEST
    cpr::Response postRequest = cpr::Post(cpr::Url{"http://127.0.0.1:8000/items"},
                    cpr::Header{{"Content-Type", "text/plain"}},
                   cpr::Body{json_data});
    std::cout << postRequest.text << std::endl;

    }
COM8 commented 1 week ago

May I suggest:

int main() {
    // Setup curl share
    cpr::Response postRequest = cpr::Post(cpr::Url{"http://127.0.0.1:8000/items"},
                                          cpr::Header{{"Content-Type", "application/json"}},
                                          cpr::Body{R"({ "vorname": "Olaf", "nachname": "Ralf", "alter": 42, "gewicht": 24 })"});
    std::cout << postRequest.text << std::endl;

    return 0;
}

The first one is invalid since there you send the numbers as string and the second example misses the { and }.

TuxxuT commented 1 week ago

Thank you so much! Problem solved.