Share My Creation Integrating GPT-3 API into Android Applications

Integrating GPT-3 API into Android Applications

In this post, we will explore how to consume the GPT-3 API in an Android application using the B4X language. B4X is a set of programming tools that allows developers to create cross-platform applications for iOS, Android, and desktop platforms using a single codebase. By leveraging the power of B4X and the GPT-3 API, we can build intelligent and responsive applications that can generate human-like text and language.

Technical Aspects

To consume the GPT-3 API in our Android application, we will first need to obtain an API key from the OpenAI website. Once we have the API key, we can use the B4X OkHtttps library to make HTTP requests to the GPT-3 API endpoints. We will need to construct the request headers and body according to the API documentation, and then parse the response to extract the generated text.

We can use various B4X UI controls, such as EditText, TextView, and Button, to create a simple user interface for our application. We can then bind event handlers to these controls to trigger the API requests and display the generated text to the user. We can also implement error handling and input validation to ensure that our application functions correctly and gracefully handles any errors or exceptions.

Conclusion

By combining the power of B4X and the GPT-3 API, we can create intelligent and responsive Android applications that can generate natural language text. With B4X's cross-platform capabilities, we can also extend our application to other platforms, such as iOS and desktop, using the same codebase. The possibilities are endless, and we can unleash our creativity and innovation to build amazing applications that push the boundaries of what is possible with technology.
 

Attachments

  • Backup openAi teste 2023-01-24 00.15.zip
    201.3 KB · Views: 735
Last edited:

JackKirk

Well-Known Member
Licensed User
Longtime User
I am very interested in this technology to provide a help chatbot to my major apps.

To educate myself I have extracted Abdull's code essential component (subroutine [generate_gpt3_response] in [ChatUI] activity) turned it into a class, tidied it up a bit, anglicized it and documented extensively.

Create a class with name ChatGPT and insert this code:

B4X:
'This class is based on:
'https://www.b4x.com/android/forum/threads/gpt-3.145654/#content
'by Abdull Cadre
'
'All I have done is extract Abdull's code essential component (subroutine
'[generate_gpt3_response] in [ChatUI] activity) turned it into a class, tidied
'it up a bit, anglicized it and documented extensively
'
'All basically for my own education - many thanks to Abdull for doing all
'original research
Sub Class_Globals
 
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
 
End Sub

Public Sub Query(query_string As String) As ResumableSub
 
    Try
 
        'Following parameter explanations I have primarily taken from
        'https://accessibleai.dev/post/generating_text_with_gpt_and_python/
        'with a few additions from various googlings

        'More googling and I found the definitive source:
        'https://platform.openai.com/docs/api-reference/introduction
        'there are a lot more options than used in this class
 
        '"n": 1
        'number of completions to generate
 
        '"stop": "None"
        'an optional setting to control response generation

        '"model": "text-davinci-003"
        'model to be used
        'see https://beta.openai.com/docs/models/gpt-3
 
        '"max_tokens": 350
        'maximum tokens in prompt AND response
 
        '"temperature": 0.5
        'level of creativity in response
        'a higher value means model will take more risks, try 0.9 for more
        'creative applications, and 0 for ones with a well-defined answer

        Dim m As Map = CreateMap("n": 1, "stop": "None", "model": "text-davinci-003", _
                                 "prompt": query_string, "max_tokens": 350, "temperature": 0.5)

        Dim js As JSONGenerator
        js.Initialize(m)

        'Uncomment this if you want to see raw JSON string generated
        'Log(js.ToString)
 
        Dim response As String
 
        Dim req As HttpJob
        req.Initialize("", Me)
        req.PostString("https://api.openai.com/v1/completions", js.ToString)
 
        'Abdull has supplied his own account API key which is very generous of
        'him but you should not use it
        'req.GetRequest.SetHeader("Authorization","Bearer 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")
 
        'You can quite easily generate your own account API key by following
        'https://accessibleai.dev/post/generating_text_with_gpt_and_python/
        'under heading [Getting a GPT-3 API Key]
        req.GetRequest.SetHeader("Authorization", "Bearer sk-youraccountAPIkey")
 
        'If you generate your own account API key then Abdull's organisation
        'key will be of no use to you
        'req.GetRequest.SetHeader("OpenAI-Organization", "org-TV3YOqDRg5DXvAUcL7dC6lI9")
 
        'If your account default organisation is "Personal" then you can supply
        'a blank organisation key - or just comment this line out
        req.GetRequest.SetHeader("OpenAI-Organization", "")
 
        req.GetRequest.SetContentType("application/json")
 
        Wait For (req) JobDone(req As HttpJob)
 
        If req.Success Then
  
            'Uncomment this line if you want to see raw JSON response
            'Log(req.GetString)
  
            Dim parser As JSONParser
  
            parser.Initialize(req.GetString)
  
            Dim jRoot As Map = parser.NextObject
  
            Dim choices As List = jRoot.Get("choices")
  
            For Each colchoices As Map In choices
      
                Dim text As String = colchoices.Get("text")
      
                If response <> "" Then response = response & CRLF
      
                response = response & text.Trim
      
            Next
 
        Else
  
            response = "ERROR: " & req.ErrorMessage
 
        End If
 
        req.Release
 
    Catch
 
        response = "ERROR: " & LastException
 
    End Try
 
    Return response

End Sub

I have tested this class under B4A with code of the form:

B4X:
    Private wrk_chat As ChatGPT
    wrk_chat.Initialize
    Wait For (wrk_chat.Query("what is the absolute best investment")) Complete (response As String)
    Log(response)
    Return

Obviously you can put all the bells and whistles around this to create a proper user experience.

I haven't tested it but the class should also be usable directly in B4i and B4J.

Note that GPT-3 with "model": "text-davinci-003" is not exactly ChatGPT, see:

https://dev.to/ben/the-difference-between-chatgpt-and-gpt-3-19dh

So the class maybe should be called GPT_3 or similar and not ChatGPT.

A bit more googling seems to suggest that an official ChatGPT API "will be released soon" - hopefully this means that ChatGPT will be just another GPT-3 model and the only change in the above may be to change:

"model": "text-davinci-003" to whatever

Happy coding and thanks again to Abdull...
 
Last edited:

cliv

Member
Licensed User
Longtime User
Sometimes the following error occurs:
ResponseError. Reason: java.net.SocketTimeoutException: timeout, Response::
java.net.SocketTimeoutException: timeout
    at okhttp3.internal.http2.Http2Stream$StreamTimeout.newTimeoutException(Http2Stream.kt:677)
    at okhttp3.internal.http2.Http2Stream$StreamTimeout.exitAndThrowIfTimedOut(Http2Stream.kt:686)
    at okhttp3.internal.http2.Http2Stream.takeHeaders(Http2Stream.kt:143)
    at okhttp3.internal.http2.Http2ExchangeCodec.readResponseHeaders(Http2ExchangeCodec.kt:96)
    at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.kt:106)
    at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:79)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
    at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)
    at anywheresoftware.b4h.okhttp.OkHttpClientWrapper.executeWithTimeout(OkHttpClientWrapper.java:175)
    at anywheresoftware.b4h.okhttp.OkHttpClientWrapper.access$0(OkHttpClientWrapper.java:172)
    at anywheresoftware.b4h.okhttp.OkHttpClientWrapper$ExecuteHelper.run(OkHttpClientWrapper.java:220)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:463)
    at java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
    at java.lang.Thread.run(Thread.java:1012)
ResponseError. Reason: java.net.SocketTimeoutException: timeout, Response:
java.net.SocketTimeoutException: timeout
Log reader error: java.io.InterruptedIOException: read interrupted
-1 received
writer error
java.lang.InterruptedException
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.reportInterruptAfterWait(AbstractQueuedSynchronizer.java:2056)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2090)
    at java.util.concurrent.ArrayBlockingQueue.take(ArrayBlockingQueue.java:417)
    at anywheresoftware.b4a.remotelogger.Connector$Writer.run(Connector.java:160)
    at java.lang.Thread.run(Thread.java:1012)
Starting remote logger. Port: 8152
After accept
 

B4XDev

Member
Licensed User

I wonder if GPT-3 is experiencing the same downtime issues as ChatGPT is. If so, that would explain the timeout errors. I can barely use ChatGPT these days. It is constantly unavailable due to heavy usage loads.
 

cliv

Member
Licensed User
Longtime User
I wonder if GPT-3 is experiencing the same downtime issues as ChatGPT is. If so, that would explain the timeout errors. I can barely use ChatGPT these days. It is constantly unavailable due to heavy usage loads.
Maybe it has something to do with the phone (Xiaomi Redmi Note 9).
Implementation in javascript works very well as does the application written in vb6.
The error generally occurs on the 2-3 question, if the question is more complex, so the waiting time is longer.
Even if the timeout is long (sometimes 45 sec-1 min) in javascript (web app) or even in vb6 app work very well and this error does not appear.
 
Last edited:

JackKirk

Well-Known Member
Licensed User
Longtime User
I try to add
B4X:
req.GetRequest.Timeout=60000
But sometimes error appears after 1 min, sometimes it works
Well try Timeout=120000 for 2 minutes...
 

natesobol

Member
Licensed User
Well try Timeout=120000 for 2 minutes...
I have it set for 3 minutes and I frequently get timeouts at 30 seconds. These are requests for 900+ word pieces of writing though.

Sometimes you'll get an answer after multiple failed attempts. The more complex the question, the less of a likelihood that it'll output successfully.



It would be cool if there was a way to get a text stream like chatGPT outputs, there's a setting for it in the API, but not sure how you'd implement it in B4i.

 
Last edited:

JackKirk

Well-Known Member
Licensed User
Longtime User
See:

https://www.b4x.com/android/forum/threads/raw-chatgpt-subroutine-for-b4x.146775/

for a raw "real" ChatGPT class.
 

PABLO2013

Well-Known Member
Licensed User
Longtime User
Greetings, thank you very much, I tried your work and it gives me this, I know how to do it, thank you
B4X:
{"n":1,"stop":"None","model":"text-davinci-003","prompt":"qqq","max_tokens":350,"temperature":0.5}
*** Receiver (httputils2service) Receive (first time) ***
ResponseError. Reason: , Response: {
    "error": {
        "message": "Incorrect API key provided: sk-3kOtp***************************************in5v. You can find your API key at https://platform.openai.com/account/api-keys.",
        "type": "invalid_request_error",
        "param": null,
        "code": "invalid_api_key"
    }
}
{
    "error": {
        "message": "Incorrect API key provided: sk-3kOtp***************************************in5v. You can find your API key at https://platform.openai.com/account/api-keys.",
        "type": "invalid_request_error",
        "param": null,
        "code": "invalid_api_key"
    }
}

 

Beja

Expert
Licensed User
Longtime User

Looks, great.. the log indicated a missing lib. I didn't know where this ib is..

B4A Version: 12.80
Parsing code. Error
Error parsing program.
Error description: Unknown type: axrlottieimageview
Are you missing a library reference?
Error occurred on line: 23 (Main)
Dim LottieView As AXrLottieImageView
 

Abdull Cadre

Active Member
Licensed User
 

Abdull Cadre

Active Member
Licensed User
Check your api key
 
ASI ME FUNCIONO

Sub generate_gpt3_response(sTexto As String):
Sub generate_gpt3_response(sTexto As String)
    Try
        Processing
       
        '<--CAMBIOS
        Dim chat_string As String
        chat_string = "{""model"":""gpt-4-turbo"",""messages"":[{""role"": ""system"", ""content"":""" &sTexto & """}]}"
        '<--CAMBIOS END
       
        Dim req As HttpJob
        req.Initialize("",Me)
        req.PostString("https://api.openai.com/v1/chat/completions",chat_string)  '<--CAMBIOS
        req.GetRequest.SetHeader("Authorization","Bearer API-KEY")
        req.GetRequest.SetHeader("OpenAI-Organization","org-SJ4L2WxrPrpRfIWHgkW44Ce1")
        req.GetRequest.SetContentType("application/json")
        Wait For (req) jobdone(req As HttpJob)
        If req.Success Then
            sucessResponse      
            Log(req.GetString)
            Dim parser As JSONParser
            parser.Initialize(req.GetString)
            Dim jRoot As Map = parser.NextObject
            Dim choices As List = jRoot.Get("choices")
            For Each colchoices As Map In choices
                Dim Text As Map = colchoices.Get("message")
                Escreve_Bot(Text.Get("content"))
                Log("textoooo"&colchoices)
            Next
        Else
            edEscrever.Enabled=True
            Log(req.ErrorMessage)
        End If
        req.Release
    Catch
        Log(LastException)
    End Try
   
End Sub
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…