OpenAI class using hbCurl
Posted: Tue May 09, 2023 6:42 pm
Hello Fivewinners;
For what's worth and in case anyone is interested, I share the class I wrote to query OpenAI for ICD10 diagnosis codes. It works really nice.
I think the only external function I use here is LogData() and I will share it if anyone wants it.
How you parse the response for the output you seek may be different.
Happy coding.
Reinaldo.
For what's worth and in case anyone is interested, I share the class I wrote to query OpenAI for ICD10 diagnosis codes. It works really nice.
I think the only external function I use here is LogData() and I will share it if anyone wants it.
How you parse the response for the output you seek may be different.
Happy coding.
Reinaldo.
Code: Select all | Expand
#INCLUDE "hbClass.ch"
#INCLUDE "hbcurl.ch"
#DEFINE CRLF CHR(13)+CHR(10)
CLASS TOpenAI
DATA hCurl
DATA httpcode
DATA nError INIT 0
DATA Response
DATA Prompt
DATA model INIT "text-davinci-003"
DATA cUrl INIT "https://api.openai.com/v1/completions"
DATA max_tokens INIT 2048
DATA temperature INIT 0
DATA top_p INIT 1
DATA frequency_penalty INIT 0.00
DATA presence_penalty INIT 0.00
DATA cLogFile INIT "TOpenAI.log"
DATA nMaxLogSize INIT 32768
DATA lDebug INIT .F.
METHOD New()
METHOD End()
METHOD Send()
METHOD Reset()
//parses response fetching ICD10 codes coded by OpenAI.
METHOD GetICD10sFromResponse()
ENDCLASS
//------------------------------------------------------------------------------------------------
METHOD New() CLASS TOpenAI
::hCurl := curl_easy_init()
RETURN Self
//------------------------------------------------------------------------------------------------
METHOD Send() CLASS TOpenAI
LOCAL aheaders
Local httpcode
Local cJson
Local h := { => }
curl_easy_setopt( ::hCurl, HB_CURLOPT_POST, .T. )
curl_easy_setopt( ::hCurl, HB_CURLOPT_URL, ::cUrl )
//curl_easy_setopt( ::hCurl, HB_CURLOPT_PASSWORD, OPENAI_API_KEY )
//http header could also be an array of headers
aheaders := { "Content-Type: application/json", ;
"Authorization: Bearer " + OPENAI_API_KEY }
curl_easy_setopt( ::hCurl, HB_CURLOPT_HTTPHEADER, aheaders )
curl_easy_setopt( ::hCurl, HB_CURLOPT_USERNAME, '' )
curl_easy_setopt( ::hCurl, HB_CURLOPT_DL_BUFF_SETUP )
curl_easy_setopt( ::hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F. )
hb_HSet( h, "model", ::model )
hb_HSet( h, "prompt", ::Prompt )
hb_HSet( h, "max_tokens", ::max_tokens )
hb_HSet( h, "temperature", ::temperature )
hb_HSet( h, "frequency_penalty", ::frequency_penalty )
hb_HSet( h, "presence_penalty", ::presence_penalty )
cJson := hb_jsonEncode( h )
curl_easy_setopt( ::hcurl, HB_CURLOPT_POSTFIELDS, cJson ) //cPostFields )
::nError := curl_easy_perform( ::hCurl )
curl_easy_getinfo( ::hCurl, HB_CURLINFO_RESPONSE_CODE, @httpcode )
::httpcode := httpcode
IF ::nError == HB_CURLE_OK
::Response = curl_easy_dl_buff_get( ::hCurl )
IF ::lDebug
LogData( ::cLogFile, { "prompt", ::Prompt, "model", ::model }, ::nMaxLogSize )
LogData( ::cLogFile, ::Response, ::nMaxLogSize )
ENDIF
Else
LogData( ::cLogFile, { "TTOpenAI prompt was:", ::Prompt }, ::nMaxLogSize )
LogData( ::cLogFile, { "Error Num:", ::nError, "Httpcode:", ::httpcode }, ::nMaxLogSize )
LogData( ::cLogFile, { "Response:", ::Response }, ::nMaxLogSize )
LogData( ::cLogFile, curl_easy_strerror( ::nError ), ::nMaxLogSize )
ENDIF
return ::Response
//------------------------------------------------------------------------------------------------
METHOD Reset() CLASS TOpenAI
curl_easy_reset( ::hCurl )
::nError := HB_CURLE_OK
::Response := Nil
return NIL
//------------------------------------------------------------------------------------------------
METHOD End() CLASS TOpenAI
curl_easy_cleanup( ::hCurl )
::hCurl := Nil
return NIL
/*------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------*/
METHOD GetICD10sFromResponse() CLASS TOpenAI
LOCAL aICD10s := {}
LOCAL aParsed, iter, acodelines, code
LOCAL a := {}
LOCAL aKeys
LOCAL hResponse := hb_jsonDecode( ::Response )
if ::lDebug
LogData( ::cLogFile, { "hb_isHash( hResponse )", hb_isHash( hResponse ), ;
"hb_HHasKey( hResponse, 'choices' )", hb_HHasKey( hResponse, "choices" ) } )
aKeys := HGetKeys( hResponse )
LogData( ::cLogFile, aKeys, ::nMaxLogSize )
ENDIF
IF hb_isHash( hResponse ) .AND. ;
hb_HHasKey( hResponse, "choices" )
if HB_ISARRAY( hResponse[ "choices" ] )
a := hResponse[ "choices" ]
endif
FOR iter := 1 TO LEN( a )
IF hb_HHasKey( a[ iter ], "text" )
acodelines := hb_ATokens( a[ iter ][ "text" ], CRLF )
FOR EACH Code IN acodelines
aParsed := hb_ATokens( Code, "-" )
AADD( aIcd10s, aParsed )
NEXT
ENDIF
NEXT iter
ENDIF
RETURN aICD10s