Search code examples
phpstreamingopenai-api

Stream DATA From openai GPT-3 API using php


I'm having trouble with the OpenAI API, Basically what I'm trying to do is stream each data node that is streamed back from the openai API response and output each data node one at a time as it streams in from the API call, but I have no clue how this is done, I researched for hours and can not find any information on how this can be achieved with PHP.

How can I get my code to output each data node in real time as the API streams in the data?

The Following is the best I can come up with, it outputs all the data at once after the call is complete, but It does not stream in the data.

function openAI(){
  $OPENAI_API_KEY="API_KEY_GOES_HERE";
  $user_id="1";  //  users id optional
   
    $prompt="tell me what you can do for me.";
    $temperature=0.5;  // 1 adds complete randomness  0 no randomness 0.0
    $max_tokens=30;
 
         $data = array('model'=>'text-davinci-002',
              'prompt'=>$prompt,
              'temperature'=>$temperature,
              'max_tokens'=>$max_tokens,
              'top_p'=>1.0,
              'stream'=>TRUE,// stream back response
              'frequency_penalty'=>0.0,
              'presence_penalty'=>0.0,
               'user' => $user_id);

   $post_json= json_encode($data);
   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, 'https://api.openai.com/v1/completions');
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($ch, CURLOPT_POST, 1);
   curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
   curl_setopt($ch, CURLOPT_POSTFIELDS, $post_json);

  $headers = array();
  $headers[] = 'Content-Type: application/json';
  // $headers[] = 'Content-Type: text/event-stream';
   $headers[] = "Authorization: Bearer $OPENAI_API_KEY";
  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

   $result = curl_exec($ch);
   return $result;

  curl_close($ch);
}

echo openAI();

Solution

  • I ended up solving my problem. Hopefully my answer will help someone in the future.

    I made the following additions to my code. This simple logic makes what I inquired about work.

    // This should be at the very top, alternatively can be set in you php.ini file
    @ini_set('zlib.output_compression',0);
    @ini_set('implicit_flush',1);
    // This function discards the contents of the topmost output buffer and turns off this output buffering.
    @ob_end_clean(); 
    

    The following curl_setopt should also be added. I personally added it on the line after CURLOPT_POSTFIELDS

    curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $data) {
      # str_repeat(' ',1024*8) is needed to fill the buffer and will make streaming the data possible
       echo $data.str_repeat(' ',1024*8);
       return strlen($data); 
    });
    

    Alternatively instead of adding str_repeat(' ',1024*8) you can shut off buffering in your web servers config file, e.g.(nginx.conf)

    gzip off;
    proxy_buffering off;