Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
kleventcov
Product and Topic Expert
Product and Topic Expert

Empowering SAP Build Apps with OpenAI: A New Paradigm in App Development


Watch Now!


 

Introduction


AI or Artificial Intelligence is an idea to teach computers to perform human tasks at a much greater speed and efficiency. What makes AI even more useful is an ability to learn, based on the provided context and material. Furthermore, AI is usually taught to respond in a human manner, often creating a feeling of conversation and familiarity.

In particular, ChatGPT has truly taken internet by storm. Released in November 2022, this OpenAI language model was able to get 1 million users in just 5 days. This is a record-breaking performance, as other popular tech products took months, sometimes even years to reach that capability.

In short, ChatGPT is a chatbot that tries to answer any given question. It has proven to shorten research time for unfamiliar topics. For instance, figuring out an answer to a common question has become a matter of asking the AI, not reading several resources.

In this blog, let's create a Q&A application, based on OpenAI's language models, similar to ChatGPT.

 


ChatGPT and AI trend lines


 

Prerequisites


First, make sure to subscribe to SAP Build Apps and create a new SAP Build Apps - Web & Mobile project. I encourage you to complete a series of onboarding videos, found at the bottom of the screen. This will allow you to better understand further instructions.

Next, sign-up for a free user account at platform.openai.com and generate a new API key in platform.openai.com/api-keys. Take note of the key, as you will need it later. Remember not to share it with others, as the following key can be used to make requests from your account.

Optionally familiarize yourself with OpenAI's documentation to get a better understanding of the technology. In particular, Text completion is the main topic of this blog.

 

Building your application


Let's start by building the foundation of the User Interface. With the use of drag and drop, put the following components to the view canvas: Title, Input field, Button, Spinner and Text. Feel free to change the title label and apply styling to the components.


User Interface


 

Switch over to the Variables view via a slider and open the Page Variables tab.


Page Variables configuration view


 

Here, we want to define all variables that we are going to use in the application. We would need three:

  1. question

    1. This variable will handle user input

    2. Variable value type should be Text



  2. answer

    1. Stores the response from the AI model

    2. Text type as well



  3. thinkingInProgress

    1. Tracks the progress of the execution

    2. Type: True/false




You can create all three by clicking the Plus icon and entering a name in the "Variable name" section on the right. Please pay attention to the variable types, whereas thinkingInProgress will require a type change to True/false.


All the required page variables


Switch back to the view canvas with the same slider and click on the Input field component. From the properties view on the right, you should notice that the Value field has no value. Here, we want to bind it to our question variable. To do so, click on the binding icon (square icon with a cross), then choose "Data and Variables". Select "Page variable" and lastly question. Click Save to apply the binding. You should now see the following:

 


question page variable bound to input field's value


 

Select the Text component, and with the same exact procedure, bind the "Content" property to the page variable answer. Afterward, expand the Advanced Properties drop-down to reveal the "Visible" property. Click on the binding icon (square box) and choose "Formula". Click on the white field with a word 'true' to enter the formula editor. Here, erase all content and paste the following:
NOT(pageVars.thinkingInProgress)

 

To finalize the visibility login, choose the Spinner component and expand the advanced properties. Bind the "Visible" property to variable thinkingInProgress. The idea here is to reverse the visibility of Text and Spinner, making the application show just the spinner when the execution is still in progress. A formula NOT() will modify a True/false variable to the exact opposite value.

Find the final result of all bindings below (Spinner on the left, Text on the right):


Final Properties Configuration


 

Now we approach the last and the most important step: configuring the execution logic. Choose the Button component and expand the Logic Canvas from the bottom of the screen. An image below portrays the final logic. Let's work through each flow function separately.

 


Button Component logic


 

1 - Set page variable


This flow function will be executed first. Here, we want to set the thinkingInProgress variable to True to indicate that the execution has begun. Choose thinkingInProgress in the "Variable name" property and choose True as the "Assigned value".

2 - HTTP request


Let's design this flow function according to the OpenAI API Reference. We can see the following cURL POST request example available:
curl https://api.openai.com/v1/completions \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-d '{
"model": "gpt-3.5-turbo",
"prompt": "Say this is a test",
"max_tokens": 7,
"temperature": 0
}'

 

Firstly, we can deduct that https://api.openai.com/v1/completions is the destination URL. Secondly, there are 2 required headers: Content-Type and Authorization, and the body of the request is a JSON object with four keys.

Begin by installing the HTTP Request flow function from the Marketplace (Relevant Documentation). Connect it to the end of the Set page variable.

For URL, put the destination URL mentioned previously. Choose POST as the HTTP method. Expand the "Optional Inputs" drop-down to reveal more settings. Open the Headers list and fill in the values in the following way, substituting <API_KEY> with the key obtained on OpenAI's website:

  • Header 1

    • header: Content-Type

    • value: application/json



  • Header 2

    • header: Authorization

    • value: Bearer <API_KEY>




Your list should look the following way:


Headers List


 

Next, open the binding icon for "Request body" and choose 'Formula'. Paste the following:
{ "model": "gpt-3.5-turbo", "prompt": pageVars.question,  "max_tokens": 250,  "temperature": 0.5 }

Here, we define 4 core values: AI model to be used (model), the question (prompt), measure of randomness (max_tokens) and originality (temperature). The following request is compatible with all GPT-3 and Codex models, so feel free to modify the model value. Use gpt-3.5-turbofor the most advanced model. The max_token value allows you to define the maximum randomness and length of a response, check out the Tokenizer tool to explore the correlation between sentence complexity and amount of tokens needed. Temperature is the measure of 'creativity' which takes values between 0 and 1. Finally, save the formula.

3 - Alert (Optional)


Alert is responsible for error handling. Connect it to the third output of HTTP request and bind its "Dialog title" to 'Output value of another node' → 'HTTP request' → 'Error' → Save. This way, you will get an error message if the API request fails.

4 - Set page variable


Connect this flow function to the first output of the HTTP request. Since this output means success, we need to indicate that the execution has concluded. To do so, simply reverse step 1 - bind thinkingInProgress to False.

5 - Set page variable


Lastly, let's input the result of the API request to the answer variable. Bind the "Assigned value" to the following formula:
STRING(outputs["HTTP request"].resBodyParsed.choices[0].text)

You may notice that the formula editor will show a warning. This happens because the formula does not have access to HTTP requests' result just yet, so it does not guarantee that the desired object will be available. Since we are sure of the response existing, this warning can be dismissed.

Conclusion


The app is now ready! We can test it by navigating to the Launch tab and opening the preview portal. Kindly find a video demonstration below:







In this blog, we have built a simple app, powered by GPT-3. With the same concept, you can now go far and beyond and create anything you put your mind to. While AI is a fast-growing field, it is still far from being even close to humans, so always be tolerant of mistakes that the language model can make.

 

👉 Stay tuned for more.

Disclaimer:
SAP notes that posts about potential uses of generative AI and large language models are merely the individual poster's ideas and opinions, and do not represent SAP's official position or future development roadmap. SAP has no legal obligation or other commitment to pursue any course of business, or develop or release any functionality, mentioned in any post or related content on this website.


18 Comments
NicofromSAP
Advisor
Advisor
Very well written! Thank you for this article.

Would be interesting to see, if it also could work with the wrapper in some way: GitHub - mmabrouk/chatgpt-wrapper: API for interacting with ChatGPT using Python and from Shell.
Dan_Wroblewski
Developer Advocate
Developer Advocate
Wondering use case 🤖
kleventcov
Product and Topic Expert
Product and Topic Expert

It seems like this wrapper has a library, so you can quite easily turn it into a public API with Flask. Since any API can be integrated to SAP Build Apps, it surely can work. See an example here: https://docs.appgyver.com/docs/custom-api

Farid
Active Participant
Excellent, easy to follow, works as a charm !

 
isimic
Discoverer
Great and very useful article. Tnx
LeandroRibeiro
Participant
A very good article!

For me who is studying and learning SAP Build APP, articles like these are very useful ( with a clear step by step guide ) .

I thank you for your effort.

Interesting that it wasn't necessary to use data resources such as REST API, OData integration to integrate with the OPENAI API.

Reading only the blog title, I thought I would have to create some kind of data resource to consume the API.

Another very useful point are the formulas used. Do you have any tips like:

Which formulas are essential to know? Which ones will most apps use? What is a good way to practice and learn these formulas?

Kind regards.
EsmeeX
Product and Topic Expert
Product and Topic Expert
Hi Leandro, thank you for the questions! The topic of formulas is indeed complex, and I wanted to let you know that we're planning some specific learning content around formulas. In the meantime, feel free to check out our docs about formulas. And let us know any feedback 😊
MarkFogle
Advisor
Advisor
Hi Leandro,

Regarding the use of a data entity to access the API, see this blog where I took that approach rather than using an HTTP Flow function.

Regards,

Mark
sukhpreetdhatt
Advisor
Advisor
0 Kudos
This is awesome!

 

kirill_l  Is there a way to potentially integrate this with MS Teams to pull specific documents?

 

Best,
mpredolim
Participant
0 Kudos
Great job kirill_l !

I´m having an issue using the API authorization. I generated the API KEY and i followed all those steps you described but i´m having this error saying i didn´t provide an API key:
{
"error": {
"message": "You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer YOUR_KEY), or as the password field (with blank username) if you're accessing the API from your browser and are prompted for a username and password. You can obtain an API key from https://platform.openai.com/account/api-keys.",
"type": "invalid_request_error",
"param": null,
"code": null
}
}


i´m using this properties into HTTP flow function:





Thanks!
Mauricio Predolim
kleventcov
Product and Topic Expert
Product and Topic Expert
Hi,

 

You should check for extra space in the Authorization header. It can be before "Bearer" or between "Bearer" and the key. Also, make sure that you have the latest version of this flow function by installing all latest updates from the marketplace.
mpredolim
Participant
0 Kudos
Thanks, i will try it.
mpredolim
Participant
I have found the issue...Exceed quota limit using free subscription. Now i´m using a paid subscription and it´s working like a charm!

Thanks.
Mauricio Predolim
patrosrinivasa
Participant
0 Kudos
hello kirill_l,

I have followed all the steps but while testing i am getting below error. Can you please help here!

my payload is:

{ "model": "gpt-3.5-turbo", "messages": [{"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "Hello!"}], "prompt": pageVars.question, "max_tokens": 500, "temperature": 0.5 }

URL: https://api.openai.com/v1/chat/completions METHOD: POST

Error message:

{
"error": {
"message": "Unrecognized request argument supplied: prompt",
"type": "invalid_request_error",
"param": null,
"code": null
}
}

 

 

 

 
patrosrinivasa
Participant
0 Kudos
Hello mpred74,

Glad to hear that your scenario is working well. I am facing 1 issue, Can you help me here

I am able to get AI response in "content" but unable to see in Buildapps output field. I have added formulae as per Point 5 described in above blog.
STRING(outputs["HTTP request"].resBodyParsed.choices[0].text)


 

 

Thanks in Advance,

Patro
mpredolim
Participant
0 Kudos

Hi Patro,

Have you done this step please?


You should bind the variable to the text component in order to show the answer from chatGPT. Please revise this step and see if it works for you 🙂

Regards,
Mauricio Predolim

patrosrinivasa
Participant
0 Kudos
Hello Mauricio Predolim, Thanks for reply.

Yes. I have done everything as per mentions steps in blog. Please check all bindings for input,spinner,output field controls. Here is screenshot of input,spinner and Text bindings. Can you check and suggest what I am missing!!


 

Regards

Patro

bindings

TillHeinen
Participant
0 Kudos

Hi @patrosrinivasa 

I guess I am a bit too late, but maybe other readers experience the same.

It's importants to use the different output ports of the HTTP request. If the Alert and ongoing process use the same port, it didn't work out for me. So I put both 'Set variables'-steps to Port 1and Output port 3 is for errors.

TillHeinen_0-1712321247776.png

 

Regards 

Till