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 view
#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