• Blog
  • Text generation capabilities with Delphi FMX Application via OpenAI API

Text generation capabilities with Delphi FMX Application via OpenAI API

GPT models

Publish date:
Discover more of what matters to you

Today, artificial intelligence (AI) is used to solve various tasks. Modern services based on artificial intelligence allow users to translate text into different languages with a high level of accuracy and relevance.

Based on the user’s request, it is possible to generate various images and even videos. It is necessary just to provide a description in the form of text and submit it to a specialized service.

With Google Speech services, you can convert human speech into text. The technical capabilities of the OpenAI company also enable the generation of human speech based on text provided by the user.

In this article, we will consider text generation at the user’s request with the help of the AI capabilities based on OpenAI GPT models in our Embarcadero Delphi FMX application via the OpenAI API.

To create an account on OpenAI, you need to follow the link https://platform.openai.com/  and click on the “Sign Up” button.

You can either create a new account or use your Google account. For using your existing account, you should choose the “Continue with Google” option.

Then, you need to choose the necessary Google account and just click on it.

Account selection

To work with OpenAI, it is necessary to generate an API key.

You should generate a secret API key, which is possible to do by clicking on “Create new secret key”.

Now you should enter a name for the key and click on “Create secret key”.

The API Key is generated. For its further use in our Delphi FMX app, you need to copy and save it. For security reasons, it can be copied only once. When you open your account later, it won’t be available for being copied. To save it, you need to click on “Copy”.

To proceed to the description of API for text generation, you should click on “Documentation”.

Then, you need to select the “API reference” tab.

And after that, you need to opt for “Chat”.

Description of the capabilities of the developed TChatGPT class for text generation based on user input and extracting the generated text from the JSON response received from OpenAI 

As an example, we will provide a description of the required text for generation using the OpenAI API. We will also receive the response in JSON format with our generated text in a Delphi FMX application through the API. Additionally, we will extract the generated text from the JSON response received from OpenAI.

For the convenience of working with the OpenAI API for text generation, we have developed a special class called TChatGPT.

This class contains a constructor that accepts an object of the TNetHttpClient class and a string constant OpenAIApiKey. This constant holds the secret API key that we previously saved for further use.

The FormatJSON function allows us to format the JSON response received from OpenAI and display it to the user in a convenient and readable form.

The SendTextToChatGPT method takes a string constant Text as a parameter, which contains the description required for generating OpenAI text.

FNetHttpClient accepts the URL as a parameter for sending a POST request with the description required for generating text by OpenAI.

Additionally, FNetHttpClient accepts an object of the TMultiPartFormData class and a dynamic array Headers (of type TArray<TNameValuePair>). MultiPartFormData contains the user’s request for text generation. Headers contains the OpenAI API Key header (Authorization parameter), previously obtained by us, and the content type (Content-Type parameter). The object JObj of the TJSONObject class contains parameters such as role and content (which actually contains the description for text generation). The object JArr of the TJSONArray class contains the messages array of our JSON request for text generation. The object JObjOut of the TJSONObject class essentially contains the entire formatted JSON request for text generation using OpenAI. Here, parameters such as the GPT model version (model) and the accuracy of the generated OpenAI text (temperature) are also included. After the POST request is executed, the JSON response from OpenAI is stored in the ResponseContent object of the TStringStream class.

The SendTextToChatGPT method returns the JSON response from OpenAI as a string.

The MessageContentFromChatGPT method allows us to extract only the generated text from the JSON response received from OpenAI. It takes a string constant JsonAnswer as an input parameter, which contains the JSON response from OpenAI.

The method returns the generated text from OpenAI as a string.

The source code of the TChatGPT class is provided below.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
unit ChatGPTHelper;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes,
System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics,
FMX.Dialogs, FMX.Memo.Types, FMX.ScrollBox, FMX.Memo, FMX.StdCtrls,
FMX.Controls.Presentation, System.Net.URLClient, System.Net.HttpClient,
System.Net.HttpClientComponent, JSON, System.Threading,
System.Net.Mime, System.Generics.Collections;
type
IChatGPTHelper = interface
function SendTextToChatGPT(const Text: string): string;
end;
TChatGPT = class(TInterfacedObject, IChatGPTHelper)
private
FNetHttpClient: TNetHTTPClient;
FOpenAIApiKey: string;
FText: string;
function FormatJSON(const JSON: string): string;
function SendTextToChatGPT(const Text: string): string;
public
constructor Create(const NetHttpClient: TNetHTTPClient;
const OpenAIApiKey: string);
class function MessageContentFromChatGPT(const JsonAnswer: string): string;
end;
implementation
{ TFirebaseAuth }
constructor TChatGPT.Create(const NetHttpClient: TNetHTTPClient;
const OpenAIApiKey: string);
begin
FNetHttpClient := NetHttpClient;
if OpenAIApiKey <> '' then
FOpenAIApiKey := OpenAIApiKey
else
begin
ShowMessage('OpenAI API key is empty!');
Exit;
end;
end;
function TChatGPT.FormatJSON(const JSON: string): string;
var
JsonObject: TJsonObject;
begin
JsonObject := TJsonObject.ParseJSONValue(JSON) as TJsonObject;
try
if Assigned(JsonObject) then
Result := JsonObject.Format()
else
Result := JSON;
finally
JsonObject.Free;
end;
end;
class function TChatGPT.MessageContentFromChatGPT(const JsonAnswer: string): string;
var
Mes: TJsonArray;
JsonResp: TJsonObject;
begin
JsonResp := nil;
try
JsonResp := TJsonObject.ParseJSONValue(JsonAnswer) as TJsonObject;
if Assigned(JsonResp) then
begin
Mes := TJsonArray(JsonResp.Get('choices').JsonValue);
Result := TJsonObject(TJsonObject(Mes.Get(0)).Get('message').JsonValue).GetValue('content').Value;
end
else
Result := '';
finally
JsonResp.Free;
end;
end;
function TChatGPT.SendTextToChatGPT(const Text: string): string;
var
JArr: TJsonArray; JObj, JObjOut: TJsonObject; Request: string;
ResponseContent: TStringStream; MultipartFormData: TMultipartFormData;
Headers: TArray<TNameValuePair>; I: Integer; StringStream: TStringStream;
begin
JArr := nil;
JObj := nil;
JObjOut := nil;
MultipartFormData := nil;
ResponseContent := nil;
StringStream := nil;
try
SetLength(Headers, 2);
Headers[0] := TNameValuePair.Create('Authorization', FOpenAIApiKey);
Headers[1] := TNameValuePair.Create('Content-Type', 'application/json');
JObj := TJsonObject.Create;
JObj.Owned := False;
JObj.AddPair('role', 'user');
JArr := TJsonArray.Create;
JArr.AddElement(JObj);
Self.FText := Text;
JObj.AddPair('content', FText);
JObjOut := TJsonObject.Create;
JObjOut.AddPair('model', 'gpt-3.5-turbo');
JObjOut.AddPair('messages', Trim(JArr.ToString));
JObjOut.AddPair('temperature', TJSONNumber.Create(0.7));
Request := JObjOut.ToString.Replace('\', '');
for I := 0 to Length(Request) – 1 do
begin
if ((Request[I] = '"') and (Request[I + 1] = '[')) or
((Request[I] = '"') and (Request[I – 1] = ']')) then
begin
Request[I] := ' ';
end;
end;
ResponseContent := TStringStream.Create;
MultipartFormData := TMultipartFormData.Create;
StringStream := TStringStream.Create(Request, TEncoding.UTF8);
MultipartFormData.Stream.LoadFromStream(StringStream);
FNetHttpClient.Post('https://api.openai.com/v1/chat/completions',
MultipartFormData, ResponseContent, Headers);
Result := FormatJSON(ResponseContent.DataString);
finally
StringStream.Free;
ResponseContent.Free;
MultipartFormData.Free;
JObjOut.Free;
JArr.Free;
JObj.Free;
end;
end;
end.

Implementation of text generation capabilities using the OpenAI API in our FMX Delphi application

To interact with the OpenAI API, specifically for sending POST requests to OpenAI in our Delphi FMX application, we will utilize the TNetHttpClient component.

 We will input the description required for text generation using the TMemo component.

The JSON response from OpenAI and the separately generated text based on user input are also displayed using the TMemo component.

The ability to send a POST request to OpenAI to obtain the generated text is implemented in the event handler of a button (the TButton class from the Standard tab of the component palette).

Let’s consider the implementation of text generation capability using the OpenAI API with our Delphi FMX application. In the button event handler “Send Request To GPT”, we declare an object GPTHelper (type IChatGPTHelper) to work with OpenAI and a string variable JsonAnswer to store the JSON response, which will contain the generated text.

Next, we will need to call the constructor of the TChatGPT class and pass our object NetHttpClient1 ( the TNetHttpClient class) and the field FOpenAIApiKey with our OpenAI API Key. We will pass the secret OpenAI API Key in the OnCreate method of the main form.

To ensure the proper functioning of the application during the execution of the request to OpenAI, we need to utilize the TTask class and its Run method. This allows us to perform the POST request in a parallel thread, preventing the application from freezing during operation. Additionally, we should call the SendTextToChatGPT method, passing the description text for generation from the text field of the TMemo component.

The JSON response from OpenAI will be stored in the variable JsonAnswer.

To update the state of components, specifically assigning the received response from OpenAI in JSON (the string variable JsonAnswer, which holds the response from OpenAI) to the Text property of the multiline input fields ResponseMemo (where we will display the raw JSON response) and MessageMemo (where we will display the generated text using OpenAI) of the TMemo class, we should use the TThread.Synchronize method.

We will extract the generated text from the JSON response using the MessageContentFromChatGPT method. The input parameter of this method will be the variable JsonAnswer.

The code for the event handler of the “Send Request To GPT” button is provided below.

123456789101112131415161718192021
procedure TForm1.Button1Click(Sender: TObject);
var
GPTHelper: IChatGPTHelper;
JsonAnswer: string;
begin
GPTHelper := TChatGPT.Create(NetHTTPClient1, FOpenAIApiKey);
ResponseMemo.Lines.Clear;
MessageMemo.Lines.Clear;
TTask.Run(
procedure
begin
JsonAnswer := GPTHelper.SendTextToChatGPT(RequestMemo.Text);
TThread.Synchronize(nil,
procedure
begin
ResponseMemo.Text := JsonAnswer;
MessageMemo.Text := TChatGPT.MessageContentFromChatGPT(JsonAnswer);
TabControl1.GotoVisibleTab(1);
end);
end);
end;

Let’s demonstrate the functionality of our Embarcadero Delphi FMX application.

Subscribe to our newsletter and get amazing content right in your inbox.

This field is required
This field is required Invalid email address

Thank you for subscribing!
See you soon... in your inbox!

confirm your subscription, make sure to check your promotions/spam folder

Tags

Subscribe to our newsletter and get amazing content right in your inbox.

You can unsubscribe from the newsletter at any time

This field is required
This field is required Invalid email address

You're almost there...

A confirmation was sent to your email

confirm your subscription, make sure to check
your promotions/spam folder