Trying to make openai request with reqwest crate

hello can you give me a suggestion how to fix this? i think i am giving json string in wrong format

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct Gpt3Response {
    completions: Vec<Gpt3Completion>,
}

#[derive(Serialize, Deserialize)]
struct Gpt3Completion {
    text: String,
}

fn main() {
    let api_key = "mykey";
    let prompt = "What is the capital of France?";
    let model = "text-davinci-002";

    let client = reqwest::blocking::Client::new();

    let mut response = client
        .post("https://api.openai.com/v1/engines/davinci/completions")
        .header("Content-Type", "application/json")
        .header("Authorization", format!("Bearer {}", api_key))
.json("{
            "prompt": prompt,
            "model": model,
            "max_tokens": 100,
        }")
        .send();
    let json: Gpt3Response = response.unwrap().json().unwrap();
    let text = &json.completions[0].text;

    println!("{}", text);
}

(Playground)

The literal should escape " with \, ie. \"

.json("{
            \"prompt\": prompt,
            \"model\": model,
            \"max_tokens\": 100,
        }")

or use raw string literals

.json(r#"{
            "prompt": prompt,
            "model": model,
            "max_tokens": 100,
        }"#)

i also tried

and it compiles but i am getting error
thread 'main' panicked at 'called Result::unwrap() on an Err
value: reqwest::Error { kind: Decode, source: Error("mi
ssing field completions", line: 8, column: 1) }', src\main.rs:41:55
i also looking here

but not sure what i missing

2023-01-28 14:00 GMT+01:00, zjp-CN via The Rust Programming Language
Forum notifications@rust-lang.discoursemail.com:

Well, according to your error message your response is missing the completions field, which means that the response from OpenAI is not what you expect when you are parsing your results here:

let json: Gpt3Response = response.unwrap().json().unwrap();

When you look at the example response for the /v1/completions endpoint from the OpenAI link, you'll see that a JSON object is returned that looks like this:

{
    "id": "cmpl-GERzeJQ4lvqPk8SkZu4XMIuR",
    "object": "text_completion",
    "created": 1586839808,
    "model": "text-davinci:003",
    "choices": [
        {
            "text": "\n\nThis is indeed a test",
            "index": 0,
            "logprobs": null,
            "finish_reason": "length"
        }
    ],
    "usage": {
        "prompt_tokens": 5,
        "completion_tokens": 7,
        "total_tokens": 12
    }
}

You are expecting a response that looks like this (based on your Gpt3Response and Gpt3Completion types):

{
    "completions": [ 
        {
            "text": "some text"
        },
        {
            "text": "some other text"
        }
    ]
}

Clearly what you get and what you expect don't match. You need to deserialize the response into a type that matches the response you get from OpenAI.

1 Like

can you try edit my example on playground so it should work?

2023-01-28 15:10 GMT+01:00, Jonas Fassbender via The Rust Programming
Language Forum notifications@rust-lang.discoursemail.com:

Sure, here is a rough example of what I'd expect to be the response types. Bare in mind that I didn't test this against the API. The types of the fields (especially the u64 ones) may be wrong, I'd double check against the API reference:

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct Informations {
    prompt: String,
    model: String,
    temperature: String,
    max_tokens: String,
}

impl Informations {
    fn init(prompt: String, model: String, temperature: String, max_tokens: String) -> Self {
        Self {
            prompt,
            model,
            temperature,
            max_tokens,
        }
    }
}

// OpenAPI documentation for these types can be found here: https://beta.openai.com/docs/api-reference/completions/create

#[derive(Serialize, Deserialize, Debug)]
struct Gpt3Response {
    id: String,
    object: String,
    created: u64,
    model: String,
    choices: Vec<Choice>,
    usage: Usage,
}

#[derive(Serialize, Deserialize, Debug)]
struct Choice {
    text: String,
    index: u64,
    logprobs: Option<u8>,
    finish_reason: String,
}

#[derive(Serialize, Deserialize, Debug)]
struct Usage {
    prompt_tokens: u64,
    completion_tokens: u64,
    total_tokens: u64,
}

fn main() {
    let api_key = "mykey"; // note this key is changed in my computer to be valid.
    let prompt = "What is the capital of France?";
    let model = "text-davinci-003";
    let temperature = "0";
    let tokens = "100";
    let info = Informations::init(
        prompt.to_string(),
        model.to_string(),
        temperature.to_string(),
        tokens.to_string(),
    );
    let client = reqwest::blocking::Client::new();
    let response = client
        .post("https://api.openai.com/v1/completions")
        .header("Content-Type", "application/json")
        .header("Authorization", format!("Bearer {}", api_key))
        .json(&info)
        .send();
        
    let json: Gpt3Response = response.unwrap().json().unwrap();
    
    println!("{:#?}", json);
}

Playground.

i tried your example that you gave me and i also tried to do like i
did in this link

and it worked but after i parsed json at the end it shows
Running target\x86_64-pc-windows-msvc\release\openai.exe
thread 'main' panicked at 'called Result::unwrap() on an Err
value: reqwest::Error { kind: Decode, source: Error("missing field
id", line: 1, column: 199) }', src\main.rs:57:55
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
error: process didn't exit successfully:
target\x86_64-pc-windows-msvc\release\openai.exe (exit code: 101)
ress any key to continue . . .

2023-01-28 16:42 GMT+01:00, Jonas Fassbender via The Rust Programming
Language Forum notifications@rust-lang.discoursemail.com:

but when i tried to print json before it making struct i got:
{"id":"cmpl-6dhtj3L1bTWbxACKU9TwzYBOIyw8Q","object":"text_completion","created":1674921555,"model":"text-davinci-003","choices":[{"text":"\n\nParis.","index":0,"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":7,"completion_tokens":4,"total_tokens":11}}

there is code that works fine

it would be even better if I could have an edit box instead of a file
and write a prompt there and instead of writing to the file to be in a
non-rewritable edit field, but that will probably be difficult

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.