Recent

Author Topic: Has anyone used Free Pascal to connect with chatGPT (OpenAI)?  (Read 13425 times)

indydev

  • Full Member
  • ***
  • Posts: 118
Has anyone used Free Pascal to connect with chatGPT (OpenAI)?
« on: December 21, 2022, 04:41:43 am »
I am trying to get a simple console application to connect with OpenAI's chatGPT. There are libraries for several languages, but of course they don't have one for Free Pascal. However I was told that I could connect using HTTP and that I should look into using Synapse. I have never used the library, so this is my first attempt at doing this.

This is what I have so far (not working!):

Code: Pascal  [Select][+][-]
  1. program OpenAI;
  2.  
  3. {$mode objfpc}{$H+}
  4. uses
  5.   SysUtils, Classes, httpsend, Crt;
  6.  
  7. const
  8.   GREETING = 'Hello! I am your Assistant. Do you have any questions for me?';
  9.   FAREWELL = 'Thank you for asking me your questions I enjoy helping out when I can. Goodbye!';
  10.  
  11. var
  12.   input: string;
  13.   HTTP: THTTPSend;
  14.   Response: TStringList;
  15.   URL: string;
  16.   APIKey: string;
  17.   i: integer;
  18.  
  19. procedure Initialize;
  20. begin
  21.   URL := 'https://api.openai.com/v1/questions/answers';
  22.   APIKey := 'sk-sjLaiEls3i9l29lzOKA2MjdIwlpSK19jyN3q8D5WvAchK4';  //  <--not real key
  23.  
  24.   HTTP := THTTPSend.Create;
  25.  
  26.   HTTP.MimeType := 'application/json';
  27.   HTTP.UserName := APIKey;
  28.   HTTP.Password := '';
  29.   HTTP.Headers.Add('Content-Type: application/x-www-form-urlencoded');
  30.   HTTP.HTTPMethod('POST', URL);
  31. end;
  32.  
  33. function getInput: string;
  34. begin
  35.   write('> ');
  36.   readln(Result);
  37. end;
  38.  
  39. function isGoodbye(input: string): boolean;
  40. begin
  41.   Result := (input = 'goodbye') or (input = 'bye') or (input = 'quit');
  42. end;
  43.  
  44. function getOpenAI_Response(input: string): TStringList;
  45. var
  46.   Buffer: PChar;
  47. begin
  48.   Buffer := PChar(input);
  49.   Result := TStringList.Create;
  50.   HTTP.Document.Clear;
  51.   HTTP.Document.Write(Buffer^, Length(input));
  52.   Response.LoadFromStream(HTTP.Document);
  53. end;
  54.  
  55. begin
  56.   ClrScr;
  57.   Initialize;
  58.   writeln(GREETING);
  59.   try
  60.     repeat
  61.         input := getInput;
  62.         Response := getOpenAI_Response(input);
  63.         for i := 0 to Response.Count -1 do
  64.         begin
  65.            writeln(Response[i]);
  66.         end;
  67.     until isGoodbye(Lowercase(input));
  68.   Finally
  69.     Response.Free;
  70.     HTTP.Free;
  71.   end;
  72.   writeln(FAREWELL);
  73.   readln;
  74. end.
  75.  


I don't see any examples using HTTP since most of the people connecting just use one of the 8 languages they already support.  If you have a way, or are familiar with httpsend in Synapse I'm looking for a helping hand. Thanks.

Simiba7

  • Newbie
  • Posts: 6
Re: Has anyone used Free Pascal to connect with chatGPT (OpenAI)?
« Reply #1 on: December 22, 2022, 11:21:36 pm »
Hello I am new to Lazarus as well as programming but I would also be very interested to accomplish this. :)

I have managed  to connect to the API with the cURL method and get a response.
However, I always get this error message.


{,"    ""error"": {","        ""message"": ""We could not parse the JSON body of your request. (HINT: This likely means you aren't using your HTTP library correctly. The OpenAI API expects a JSON payload, but what was sent was not valid JSON. If you have trouble figuring out how to fix this, please send an email to support@openai.com and include any relevant code you'd like help with.)"",","        ""type"": ""invalid_request_error"",","        ""param"": null,","        ""code"": null","    }",


This is the code I used:

Code: Pascal  [Select][+][-]
  1.  
  2. uses  
  3. SysUtils, Classes, Process;
  4.  
  5. var
  6.   url: string;
  7.   AStringList : TStringList;
  8.   Aprocess: TProcess;  
  9.  
  10. begin
  11.    AProcess := TProcess.Create(nil);
  12.    url:='https://api.openai.com/v1/completions';
  13.    AProcess.Executable:='curl';
  14.    //AProcess.Parameters.Add('-X POST');
  15.    AProcess.Parameters.Add(url);
  16.    AProcess.Parameters.Add('-H "Authorization: Bearer API-KEY"');
  17.    AProcess.Parameters.Add('-H "Content-Type: application/json"');
  18.    AProcess.Parameters.Add('-d ''{"model": "text-davinci-003", "prompt": "Say this is a test", "temperature": 0, "max_tokens": 7}''');
  19.  
  20.    AProcess.Options := AProcess.Options + [poWaitOnExit, poUsePipes];
  21.    AProcess.Execute;
  22.    AStringList := TStringList.Create;
  23.    AStringList.LoadFromStream(AProcess.Output);
  24.    Label1.Caption:= AStringList.CommaText;  
  25. end;      
  26.  

Here the question is embedded and the answer will be output in Label1.

(I also asked Chatt-GPT for a possible solution to the problem, it decided to insert the excluded line, but with this I got "Error 400 bad". But maybe it would be the right approach...)

Maybe this will bring you a little further ;)

I would be happy if we could solve the problem.
Happy holidays

ccrause

  • Hero Member
  • *****
  • Posts: 997
Re: Has anyone used Free Pascal to connect with chatGPT (OpenAI)?
« Reply #2 on: December 23, 2022, 06:35:52 am »
I don't see any examples using HTTP since most of the people connecting just use one of the 8 languages they already support.  If you have a way, or are familiar with httpsend in Synapse I'm looking for a helping hand. Thanks.
See making requests in the documentation.  This shows a simple request example. Comparing the headers in the example with your code shows that the Authorization header field seems to be missing.  Also, the query should be packed into a JSON structure, as per example.

ccrause

  • Hero Member
  • *****
  • Posts: 997
Re: Has anyone used Free Pascal to connect with chatGPT (OpenAI)?
« Reply #3 on: December 23, 2022, 07:03:30 am »
Code: Pascal  [Select][+][-]
  1.    AProcess.Parameters.Add('-d ''{"model": "text-davinci-003", "prompt": "Say this is a test", "temperature": 0, "max_tokens": 7}''');

I'm not sure the JSON text should be inside single quotes. Try removing the single quotes before the { and after the  }.  Alternatively replace the single quotes with double quotes (") around the JSON, similar to the other parameters.

Thaddy

  • Hero Member
  • *****
  • Posts: 16523
  • Kallstadt seems a good place to evict Trump to.
Re: Has anyone used Free Pascal to connect with chatGPT (OpenAI)?
« Reply #4 on: December 23, 2022, 09:43:04 am »
Here's a simpler example that works, do not forget to substitute YOUR_API_KEY with your own:
Code: Pascal  [Select][+][-]
  1. program testopenai;
  2. {$mode objfpc}{$ofdef mswindows}{$apptype console}{$endif}
  3. uses Classes, Process;
  4. var
  5.   AStringList : TStrings;
  6.   Aprocess: TProcess;  
  7. begin
  8.    AProcess := TProcess.Create(nil);
  9.    try
  10.      AProcess.Options := AProcess.Options + [poWaitOnExit,poUsePipes];
  11.      AProcess.Executable:='curl.exe';
  12.      AProcess.Parameters.Add('https://api.openai.com/v1/models/text-davinci-003');
  13.      AProcess.Parameters.Add('-H');
  14.      Aprocess.Parameters.Add('"Authorization: Bearer YOUR_API_KEY"'); // do not quote your_APi_KEY!!
  15.      AProcess.Execute;
  16.      try
  17.        AStringList := TStringList.Create;
  18.        AStringList.LoadFromStream(AProcess.Output);    
  19.        Writeln(AStringList.Text);
  20.      finally
  21.        AStringList.Free;
  22.      end;
  23.    Finally  
  24.      AProcess.Free;
  25.    end;
  26. end.
   
« Last Edit: December 23, 2022, 09:46:33 am by Thaddy »
But I am sure they don't want the Trumps back...

Simiba7

  • Newbie
  • Posts: 6
Re: Has anyone used Free Pascal to connect with chatGPT (OpenAI)?
« Reply #5 on: December 23, 2022, 10:13:38 am »
Quote
I'm not sure the JSON text should be inside single quotes. Try removing the single quotes before the { and after the  }.  Alternatively replace the single quotes with double quotes (") around the JSON, similar to the other parameters.

Good day, thank you very much for your answer. I tried the following two options and still got the same error message as above....

Code: Pascal  [Select][+][-]
  1. AProcess.Parameters.Add('-d {"model": "text-davinci-003", "prompt": "Say this is a test", "temperature": 0, "max_tokens": 7}');

and

Code: Pascal  [Select][+][-]
  1. AProcess.Parameters.Add('-d "{"model": "text-davinci-003", "prompt": "Say this is a test", "temperature": 0, "max_tokens": 7}"');

Do you have any idea what the problem could be?
Thank you very much for your time.

Simiba7

  • Newbie
  • Posts: 6
Re: Has anyone used Free Pascal to connect with chatGPT (OpenAI)?
« Reply #6 on: December 23, 2022, 10:17:28 am »
Here's a simpler example that works, do not forget to substitute YOUR_API_KEY with your own:
Code: Pascal  [Select][+][-]
  1. program testopenai;
  2. {$mode objfpc}{$ofdef mswindows}{$apptype console}{$endif}
  3. uses Classes, Process;
  4. var
  5.   AStringList : TStrings;
  6.   Aprocess: TProcess;  
  7. begin
  8.    AProcess := TProcess.Create(nil);
  9.    try
  10.      AProcess.Options := AProcess.Options + [poWaitOnExit,poUsePipes];
  11.      AProcess.Executable:='curl.exe';
  12.      AProcess.Parameters.Add('https://api.openai.com/v1/models/text-davinci-003');
  13.      AProcess.Parameters.Add('-H');
  14.      Aprocess.Parameters.Add('"Authorization: Bearer YOUR_API_KEY"'); // do not quote your_APi_KEY!!
  15.      AProcess.Execute;
  16.      try
  17.        AStringList := TStringList.Create;
  18.        AStringList.LoadFromStream(AProcess.Output);    
  19.        Writeln(AStringList.Text);
  20.      finally
  21.        AStringList.Free;
  22.      end;
  23.    Finally  
  24.      AProcess.Free;
  25.    end;
  26. end.


Hello, thank you very much for your answer.

That worked amazingly well for me too and I got a response from the API! :)

Do you have any idea how I could make a request to https://api.openai.com/v1/completions with this method?
I just can't get my head around that.

Thanks a lot

Thaddy

  • Hero Member
  • *****
  • Posts: 16523
  • Kallstadt seems a good place to evict Trump to.
Re: Has anyone used Free Pascal to connect with chatGPT (OpenAI)?
« Reply #7 on: December 23, 2022, 01:47:17 pm »
Here's the same in pure Pascal, no need for curl:
Code: Pascal  [Select][+][-]
  1. program fpopenai;
  2. {$mode objfpc}{$ifdef mswindows}{$apptype console}{$endif}{$H+}
  3. uses classes, fphttpclient,opensslsockets;
  4. const
  5.   API_KEY='<Your API Key>';
  6.   model ='{"model": "text-davinci-003", "prompt": "Say this is a test", "temperature": 0, "max_tokens": 7}';
  7. var
  8.   Client:TfpHttpClient;  
  9. begin
  10.   Client :=TfpHttpClient.Create(nil);
  11.   Try
  12.     Client.AllowRedirect:= true;
  13.     Client.RequestHeaders.Add('Authorization: Bearer '+API_KEY); // replace API_KEY with yours, see above
  14.     writeln(Client.Get('https://api.openai.com/v1/models/text-davinci-003'));
  15.   finally
  16.    Client.Free
  17.   end;
  18. end.
'
Note that I also can't get the POST data to work, not wit this code, nor with the process approach.
But the above code works.
I believe that you have to issue a completion request first.
« Last Edit: December 23, 2022, 03:35:29 pm by Thaddy »
But I am sure they don't want the Trumps back...

ccrause

  • Hero Member
  • *****
  • Posts: 997
Re: Has anyone used Free Pascal to connect with chatGPT (OpenAI)?
« Reply #8 on: December 23, 2022, 02:05:56 pm »
Quote
I'm not sure the JSON text should be inside single quotes. Try removing the single quotes before the { and after the  }.  Alternatively replace the single quotes with double quotes (") around the JSON, similar to the other parameters.

Good day, thank you very much for your answer. I tried the following two options and still got the same error message as above....

Code: Pascal  [Select][+][-]
  1. AProcess.Parameters.Add('-d {"model": "text-davinci-003", "prompt": "Say this is a test", "temperature": 0, "max_tokens": 7}');

and

Code: Pascal  [Select][+][-]
  1. AProcess.Parameters.Add('-d "{"model": "text-davinci-003", "prompt": "Say this is a test", "temperature": 0, "max_tokens": 7}"');

Do you have any idea what the problem could be?
Thank you very much for your time.

Posting content containing double quotes appears to be tricky (depending on the OS or shell, see e.g. this, this and this).   Seems like the original attempt using single quotes around the JSON is generally thought to be correct, but there must be some interference from the executing shell environment.  Perhaps using TfpHttpClient will result in a more general solution where escaping of the JSON content is not interfered with by the shell environment.

Thaddy

  • Hero Member
  • *****
  • Posts: 16523
  • Kallstadt seems a good place to evict Trump to.
Re: Has anyone used Free Pascal to connect with chatGPT (OpenAI)?
« Reply #9 on: December 23, 2022, 03:04:59 pm »
WORKING!!!
Code: Pascal  [Select][+][-]
  1. program fpopenai_3;
  2. {$mode objfpc}{$ifdef mswindows}{$apptype console}{$endif}{$H+}
  3. uses classes, fphttpclient,opensslsockets;
  4. const
  5.   API_KEY='<API_KEY>';
  6.   model ='{"model": "text-davinci-003", "prompt": "Say this is a test", "temperature": 0, "max_tokens": 7}';
  7. var
  8.   Client:TfpHttpClient;  
  9. begin
  10.   Client :=TfpHttpClient.Create(nil);
  11.   Try
  12.     Client.AllowRedirect:= true;
  13.     Client.RequestHeaders.Add('Content-Type: application/json');
  14.     Client.RequestHeaders.Add('Authorization: Bearer '+API_KEY); // replace API_KEY with yours, see above
  15.     writeln(Client.Get('https://api.openai.com/v1/models/text-davinci-003'));
  16.     Client.RequestBody:=TStringStream.Create(model);   // This was the culprit
  17.     writeln(Client.Post('https://api.openai.com/v1/completions'));    
  18.   finally
  19.     Client.RequestBody.Free;
  20.     Client.Free;
  21.   end;
  22. end.

Well, needs some beautification for the output, but we are getting there.
The output is valid and correct, see the last line:
Code: Bash  [Select][+][-]
  1.   "permission": [
  2.     {
  3.       "id": "modelperm-Dtl0tncKKco7k8ccFSZgdUA5",
  4.       "object": "model_permission",
  5.       "created": 1671664268,
  6.       "allow_create_engine": false,
  7.       "allow_sampling": true,
  8.       "allow_logprobs": true,
  9.       "allow_search_indices": false,
  10.       "allow_view": true,
  11.       "allow_fine_tuning": false,
  12.       "organization": "*",
  13.       "group": null,
  14.       "is_blocking": false
  15.     }
  16.   ],
  17.   "root": "text-davinci-003",
  18.   "parent": null
  19. }
  20.  
  21. {"id":"cmpl-6Qd8mRpAVR1rww75XNVAAwnrRitTh","object":"text_completion","created":1671805004,"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}}
« Last Edit: December 23, 2022, 05:06:20 pm by Thaddy »
But I am sure they don't want the Trumps back...

Thaddy

  • Hero Member
  • *****
  • Posts: 16523
  • Kallstadt seems a good place to evict Trump to.
Re: Has anyone used Free Pascal to connect with chatGPT (OpenAI)?
« Reply #10 on: December 23, 2022, 04:54:44 pm »
I have tested some more stuff after spending half a day getting it to work. It all works if you prepare the POST correctly.
I wasn't aware of that OpenAI but it is really interesting. Think I will do some more experiments.

Note that I prefer my pure Pascal solution over TProcess and curl.
(curl could have been done with libcurl instead of TProcess, btw. I did not fix that for Windows for nothing....  O:-) :) )
« Last Edit: December 23, 2022, 05:07:53 pm by Thaddy »
But I am sure they don't want the Trumps back...

Simiba7

  • Newbie
  • Posts: 6
Re: Has anyone used Free Pascal to connect with chatGPT (OpenAI)?
« Reply #11 on: December 23, 2022, 05:26:13 pm »
Wow thank you so much for your work! I am new to the forum and overwhelmed by the help I get here! :o

I still have a (hopefully) small problem to get your code to run...

I don't have a console because I'm using a GUI project so I want to output the answer by label.

but i only get the following text as answer. This does not contain the answer to the question (So I only get one answer in label 1). Also, with label2 I always get the error "Stream read Error". I am really new to Lazarus and I would be very happy if I could get it to run.

Code: Pascal  [Select][+][-]
  1. {
  2.   "id": "text-davinci-003",
  3.   "object": "model",
  4.   "created": 1669599635,
  5.   "owned_by": "openai-internal",
  6.   "permission": [
  7.     {
  8.       "id": "modelperm-Dtl0tncKKco7k8ccFSZgdUA5",
  9.       "object": "model_permission",
  10.       "created": 1671664268,
  11.       "allow_create_engine": false,
  12.       "allow_sampling": true,
  13.       "allow_logprobs": true,
  14.       "allow_search_indices": false,
  15.       "allow_view": true,
  16.       "allow_fine_tuning": false,
  17.       "organization": "*",
  18.       "group": null,
  19.       "is_blocking": false
  20.     }
  21.   ],
  22.   "root": "text-davinci-003",
  23.   "parent": null
  24. }
  25.  

Here is the code used:

Code: Pascal  [Select][+][-]
  1.  
  2. uses classes, fphttpclient, opensslsockets;
  3. const
  4.     API_KEY='Custom_API-Key';
  5.     model ='{"model": "text-davinci-003", "prompt": "Say this is a test", "temperature": 0, "max_tokens": 7}';
  6.   var
  7.     Client:TfpHttpClient;
  8.     Body:TStringStream;
  9.   begin
  10.     Client :=TfpHttpClient.Create(nil);
  11.     Body :=TStringStream.Create;
  12.     Body.Write(Model,Length(model));
  13.     Try :(
  14.       Client.AllowRedirect:= true;
  15.       Client.RequestHeaders.Add('Content-Type: application/json');
  16.       Client.RequestHeaders.Add('Authorization: Bearer '+API_KEY); // replace API_KEY with yours, see above
  17.       Label1.Caption:=(Client.Get('https://api.openai.com/v1/models/text-davinci-003'));
  18.       Client.RequestBody:=Body;
  19.       Label2.Caption:=(Client.Post('https://api.openai.com/v1/completions'));
  20.     finally
  21.      Body.Free;
  22.      Client.Free;
  23.     end;
  24.   end;      

Thanks again to all for your help!

Quote
I wasn't aware of that OpenAI but it is really interesting.
Their work is truly breathtaking!

Thaddy

  • Hero Member
  • *****
  • Posts: 16523
  • Kallstadt seems a good place to evict Trump to.
Re: Has anyone used Free Pascal to connect with chatGPT (OpenAI)?
« Reply #12 on: December 23, 2022, 05:54:58 pm »
Well, I am a server guy and do not much in user interfacing, but I am sure someone here can translate my code into a button click using the TfpHTTPclient component and fpJson for formatting... Indeed it is a small problem, very small.  :D :)
I can do that too of course, but enough for today.
It works and the logic works for the entire API and with any model.

Tnx for the fun day! Merry Christmas.

(Note that I edited the code somewhat to less lines)
« Last Edit: December 23, 2022, 06:36:04 pm by Thaddy »
But I am sure they don't want the Trumps back...

Simiba7

  • Newbie
  • Posts: 6
Re: Has anyone used Free Pascal to connect with chatGPT (OpenAI)?
« Reply #13 on: December 23, 2022, 07:10:40 pm »
Thank you so much for your work! I also wish you Merry Christmas.

I have no idea why, but the code works now :)
If anyone is interested, that would be the code which prints the API response in a label when a button is pressed:

Code: Pascal  [Select][+][-]
  1. uses
  2. classes, SysUtils, Forms, fphttpclient, opensslsockets;
  3.  
  4. procedure TForm1.Button1Click(Sender: TObject);
  5.  
  6. const
  7.   API_KEY='Custom_API-Key';
  8.   model ='{"model": "text-davinci-003", "prompt": "Say this is a test", "temperature": 0, "max_tokens": 7}';
  9.  
  10. var
  11.   Client:TfpHttpClient;
  12.  
  13. begin
  14.   Client :=TfpHttpClient.Create(nil);
  15.   Try
  16.     Client.AllowRedirect:= true;
  17.     Client.RequestHeaders.Add('Content-Type: application/json');
  18.     Client.RequestHeaders.Add('Authorization: Bearer '+API_KEY); // replace API_KEY with yours, see above
  19.     Client.RequestBody:=TStringStream.Create(model);
  20.     Label1.Caption:=(Client.Post('https://api.openai.com/v1/completions'));
  21.  
  22.   finally
  23.     Client.RequestBody.Free;
  24.     Client.Free;
  25.  
  26.   end;
  27. end;    
  28.  

This code outputs the following:
Code: Pascal  [Select][+][-]
  1. {"id":"cmpl-6QgmYn44ANDSuOQDBjdaXeutlYRmq","object":"text_completion","created":1671819002,"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}}
  2.  

Now my last request would be to print only the pure response text, so in this case "This is indeed a Test".

If someone knows how this could work I would appreciate your advice. I will try to figure it out and keep you updated.

Thanks to all.
« Last Edit: December 23, 2022, 07:29:47 pm by Simiba7 »

Thaddy

  • Hero Member
  • *****
  • Posts: 16523
  • Kallstadt seems a good place to evict Trump to.
Re: Has anyone used Free Pascal to connect with chatGPT (OpenAI)?
« Reply #14 on: December 23, 2022, 07:27:48 pm »
That is simple with fpjson. I leave that to you as an excersice. :o

Of course the documentation contains an example:
https://www.freepascal.org/docs-html/current/fcl/fpjson/index.html

Spoiler: the trick is in the findpath.
You seem quite capable of solving that.
« Last Edit: December 23, 2022, 07:35:44 pm by Thaddy »
But I am sure they don't want the Trumps back...

 

TinyPortal © 2005-2018