I have a fastapi configured as such: @app.post("/engines/completions")
async def read_completions(
# engine_id:str,
prompt: Optional[str] = None,
max_tokens: Optional[int] = 16,
temperature: Optional[float] = 1.0,
top_p: Optional[float] = 1.0,
top_k: Optional[int] = 40,
n: Optional[int] = 1,
stream: Optional[bool] = False,
logprobs: Optional[int] = None,
echo: Optional[bool] = False,
stop: Optional[list] = None,
presence_penalty: Optional[float] = 0.0001,
frequency_penalty: Optional[float] = 0.0001,
best_of: Optional[int] = 1,
recursive_depth: Optional[int] = 0,
recursive_refresh: Optional[int] = 0,
logit_bias: Optional[Dict[str, float]] = None,
):
and a axios request configured like so
let stop = "stuff";
let prompt ="test";
let url = "http://localhost:8000/engines/completions";
const options = {
method: "POST",
headers: { "content-type": "application/json"},
timeout: 2000000,
body: {stop, prompt},
url,
};
axios(options)
My request will go through without a 442, but prompt and stop will evaluate as None in my read_completions function.
What am I doing wrong?
CodePudding user response:
Use data instead of body on your axios' options.
See Request Config on axios documentation,
CodePudding user response:
My request will go through without a 442
Your request goes through, as all parameters are defined as optional. Thus, not receiving these parameters, the server won't complain.
but prompt and stop will evaluate as None in my read_completions function.
They are both None (null), as the server never received any values for them. Your endpoint expects these parameters being Query parameters, however, your client sends (or actually, attempts to send) body parameters.
Option 1
Adjust your endpoint to expect Form data. Also, if you are going to define a parameter to be a List, please have a look at this on how to do that properly.
from typing import Optional, List
@app.post("/engines/completions")
async def read_completions(
prompt: Optional[str] = Form(None),
stop: Optional[List[str]] = Form(None)
):
return {"prompt": prompt, "stop list": stop}
Then, your client side should look like this:
function uploadFormData() {
var formData = new FormData();
var alphaArray = ['A', 'B', 'C','D','E'];
for (var i = 0; i < alphaArray.length; i ) {
formData.append('stop', alphaArray [i]);
}
formData.append("prompt", "test");
axios({
method: 'post',
url: '/engines/completions',
data: formData,
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
})
.then(function(response) {
console.log(response);
})
.catch(function(response) {
console.log(response);
});
}
Option 2
Adjust your endpoint to expect JSON (body) parameters. In FastAPI, you could do that using either Body parameters or Pydantic models. The example below uses the latter.
from pydantic import BaseModel
from typing import Optional, List
class Item(BaseModel):
prompt: str = None
stop: Optional[List[str]] = None
@app.post("/engines/completions")
async def read_completions(item: Item):
return {"prompt": item.prompt, "stop list": item.stop}
Finally, the client side should look like the below:
function uploadJSONdata() {
axios({
method: 'post',
url: '/engines/completions',
data: JSON.stringify({"prompt": "test", "stop": ['A', 'B', 'C','D','E']}),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
})
.then(function(response) {
console.log(response);
})
.catch(function(response) {
console.log(response);
});
}
