OpenAI OpenAPI Specification - Kotlin
From https://github.com/openai/openai-openapi/blob/master/openapi.yaml
NOTES:
- There is https://github.com/openai/openai-java, which OpenAI describes as
"The official Java library for the OpenAI API", but:
- That "official" library lags behind https://github.com/openai/openai-openapi/blob/master/openapi.yaml
For example, as of 2025/02/12 is is STILL lacking OpenAI's Realtime API (https://platform.openai.com/docs/api-reference/realtime), which is my main use case. openai-java
is actually a nearly fully modernized Kotlin library, so the nameopenai-java
is legacy;
it really should be namedopenai-kotlin
.
- That "official" library lags behind https://github.com/openai/openai-openapi/blob/master/openapi.yaml
- I was initially tempted to inflate this repo to contain multiple openapi-generator generated languages, but for now I am limiting it to Kotlin.
- openapi-generator has >4k open Issues:
https://github.com/OpenAPITools/openapi-generator/issues
So, no promises about the quality of its output.
Maybe one day I will open a PR to auto-generate some of the changes I made manually.
Requirements:
- OpenAPI Generator: https://openapi-generator.tech/docs/installation
Optional:
curl -o openapi-YYYYMMDD.yaml https://raw.githubusercontent.com/openai/openai-openapi/refs/heads/master/openapi.yaml
You don't have to do this.
openapi-generator
supports fetching the specification directly from a url.
I prefer to save a snapshot of the specification that was used for the generation.
time openapi-generator generate -i openapi-YYYYMMDD.yaml -g kotlin -o ./lib --skip-validate-spec --additional-properties=artifactId=openai-kotlin-client,artifactVersion=0.0.1,groupId=com.openai,packageName=com.openai
(< 5 seconds on MacBook Pro M4 Pro)cp lib/build.gradle .
mv lib/gradle* lib/settings.gradle .
echo -e "\ninclude(\":lib\")" >> settings.gradle
- Edit
build.gradle
to be a project file andlib/build.gradle
to be a module file. chmod +x ./gradlew
./gradlew build
(< 20 seconds on MacBook Pro M4 Pro to [eventually; see "Changes"] successfully compile from clean)
All of this is also shown in the openai-kotlin-client.sh
file.
At this point, the build will actually fail.
I had to make some manual changes in order to get it to compile successfully:
- AudioApi.kt:
- change
AudioResponseFormat? = json
toAudioResponseFormat? = AudioResponseFormat.json
- change
timestampGranularities?.value
totimestampGranularities
- change
- remove
data
(data class ...
->class ...
) in:- CreateAssistantRequestToolResourcesFileSearch.kt
- CreateThreadRequestToolResourcesFileSearch.kt
This just got it to COMPILE successfully!
I had to make further changes in order to get it to RUN successfully.
All of my changes can be seen at:
https://github.com/swooby/openai-openapi-kotlin/pull/1/files
When a new spec comes out:
- Make sure to start from a fresh/stashed checkout.
curl -o openapi-YYYYMMDD.yaml https://raw.githubusercontent.com/openai/openai-openapi/refs/heads/master/openapi.yaml
openapi-generator generate -i openapi-YYYYMMDD.yaml -g kotlin -o ./lib --skip-validate-spec --additional-properties=artifactId=openai-kotlin-client,artifactVersion=0.0.1,groupId=com.openai,packageName=com.openai
- optimize imports of
models
; NOTE: This will fail on any file that has a compiler error! mv lib/build.gradle lib/build.gradle.kts
rm -f ./gradle && mv lib/gradle* .
mv lib/settings.gradle ./settings.gradle.kts
- Review each changed file, especially ones that show as modified in:
https://github.com/swooby/openai-openapi-kotlin/pull/1/files- First review with the settings.gradle and build.gradle files.
gradle*
: probably discard all changessettings.gradle.kts
: probably discard all changeslib/build.gradle.kts
: probably discard all changes- While you are here, update any dependencies in
gradle/libs.versions.toml
docs
: probably keep all changestest
: probably keep all changes except...- probably delete
RealtimeResponseCreateParamsMaxResponseOutputTokensTest
- probably delete
RealtimeResponseMaxOutputTokensTest
- probably delete
infrastructure
:AudioApi.kt
: probably discard all changesApiClient.kt
: probably discard all changesBigDecimalAdapter.kt
: probably discard all changesBigIntegerAdapter.kt
: probably discard all changesSerializer.kt
: probably discard all changes
models
:CreateAssistantRequestToolResourcesFileSearch
: keep non-data class (syntax error for data class to have no constructor parameters)CreateThreadRequestToolResourcesFileSearch
: keep non-data class (syntax error for data class to have no constructor parameters)Realtime*
files:
(This can get a little complicated...)RealtimeClientEvent*
: Keep alltype: RealtimeClientEvent*.Type = RealtimeClientEvent*.Type....
one-line assignmentsRealtimeConversationItem
- add/keep
in_progress
to nestedStatus
; undocumented value comes from the server
- add/keep
RealtimeConversationItemContentInner
- add/keep
audio
to nestedType
; undocumented value comes from the server
- add/keep
RealtimeResponse
- change
maxOutputTokens
to typeRealtimeSessionMaxResponseOutputTokens
- add/keep
in_progress
to nestedStatus
; undocumented value comes from the server
- change
RealtimeResponseCreateParams
- change
maxResponseOutputTokens
to typeRealtimeSessionMaxResponseOutputTokens
- change
RealtimeResponseCreateParamsConversation
- add/keep
enum class ... auto, none ...
- add/keep
- move
RealtimeResponseCreateParamsMaxResponseOutputTokens
to commonRealtimeSessionMaxResponseOutputTokens
- move
RealtimeResponseMaxOutputTokens
to commonRealtimeSessionMaxResponseOutputTokens
RealtimeServerEventConversationItemCreated
- add/keep nullable
previousItemId
- add/keep nullable
RealtimeServerEventInputAudioBufferCommitted
:- add/keep nullable
previousItemId
- add/keep nullable
RealtimeSession
- add/keep
@SerializeNull
REALLY?!?!?!? - change
maxResponseOutputTokens
to typeRealtimeSessionMaxResponseOutputTokens
- add/keep
RealtimeSessionCreateRequest
- add/keep
@SerializeNull
- change
maxResponseOutputTokens
to typeRealtimeSessionMaxResponseOutputTokens
- add/keep
RealtimeSessionCreateRequestInputAudioTranscription
- add/keep nested
enum class Model whisper-1 ...
- change
model
to nestedModel
- add/keep nested
RealtimeSessionCreateRequestTurnDetection
- add/keep nested
enum class Type server_vad ...
- change
type
to nestedType
- add/keep nested
RealtimeSessionCreateResponse
- change
maxResponseOutputTokens
to typeRealtimeSessionMaxResponseOutputTokens
- change
- First review with the settings.gradle and build.gradle files.