1

I have a FastAPI backend 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 an Axios request configured like this:

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 goes through without getting a 442 error, but prompt and stop attributes would result in None in my read_completions function. What am I doing wrong?

0

2 Answers 2

2

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 at least, attempts to send) body parameters.

Option 1 - Send JSON data

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")
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(response => {
            console.log(response);
        })
        .catch(error => {
            console.error(error);
        });
}

Option 2 - Send Form data

Adjust your endpoint to expect Form data. Also, if you need to define a parameter as a List, please have a look at this on how to do that properly.

from typing import Optional, List

@app.post("/engines/completions")
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': 'application/x-www-form-urlencoded'
            },
        })
        .then(response => {
            console.log(response);
        })
        .catch(error => {
            console.error(error);
        });
}
1

Use data instead of body on your axios' options.

See Request Config on axios documentation,

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.