{"id":25658422,"url":"https://github.com/swooby/openai-openapi-kotlin","last_synced_at":"2026-05-10T03:37:14.192Z","repository":{"id":279046662,"uuid":"918272530","full_name":"swooby/openai-openapi-kotlin","owner":"swooby","description":"OpenAI OpenAPI Specification - Kotlin","archived":false,"fork":false,"pushed_at":"2025-02-23T11:55:51.000Z","size":739,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-23T12:27:51.991Z","etag":null,"topics":["kotlin","kotlin-android","openai","openai-api","openai-realtime","openai-realtime-api","openapi"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/swooby.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-17T15:41:01.000Z","updated_at":"2025-01-29T18:18:38.000Z","dependencies_parsed_at":"2025-02-23T12:39:06.145Z","dependency_job_id":null,"html_url":"https://github.com/swooby/openai-openapi-kotlin","commit_stats":null,"previous_names":["swooby/openai-openapi-kotlin"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swooby%2Fopenai-openapi-kotlin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swooby%2Fopenai-openapi-kotlin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swooby%2Fopenai-openapi-kotlin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swooby%2Fopenai-openapi-kotlin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swooby","download_url":"https://codeload.github.com/swooby/openai-openapi-kotlin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240396784,"owners_count":19794729,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kotlin","kotlin-android","openai","openai-api","openai-realtime","openai-realtime-api","openapi"],"created_at":"2025-02-24T00:21:03.824Z","updated_at":"2026-05-10T03:37:14.181Z","avatar_url":"https://github.com/swooby.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# openai-openapi-kotlin\n\n**OpenAI OpenAPI Specification - Kotlin**\n\nFrom https://github.com/openai/openai-openapi/blob/master/openapi.yaml\n\nNOTES:\n* There is https://github.com/openai/openai-java, which OpenAI describes as\n  \"The official Java library for the OpenAI API\", but:\n  1. That \"official\" library lags behind https://github.com/openai/openai-openapi/blob/master/openapi.yaml  \n     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.\n  2. `openai-java` is actually a nearly fully modernized Kotlin library, so the name\n     `openai-java` is legacy;  \n     it really should be named `openai-kotlin`.\n* I was initially tempted to inflate this repo to contain multiple openapi-generator\n  generated languages, but for now I am limiting it to Kotlin.\n* openapi-generator has \u003e4k open Issues:  \n  https://github.com/OpenAPITools/openapi-generator/issues  \n  So, no promises about the quality of its output.  \n  Maybe one day I will open a PR to auto-generate some of the changes I made manually.\n\nRequirements:\n* OpenAPI Generator: https://openapi-generator.tech/docs/installation\n\nOptional:\n1. `curl -o openapi-YYYYMMDD.yaml https://raw.githubusercontent.com/openai/openai-openapi/refs/heads/master/openapi.yaml`\n\nYou don't have to do this.  \n`openapi-generator` supports fetching the specification directly from a url.  \nI prefer to save a snapshot of the specification that was used for the generation.\n\n## Generate Whole OpenAI API\n1. `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`  \n   (\u003c 5 seconds on MacBook Pro M4 Pro)\n2. `cp lib/build.gradle .`\n3. `mv lib/gradle* lib/settings.gradle .`\n4. `echo -e \"\\ninclude(\\\":lib\\\")\" \u003e\u003e settings.gradle`\n5. Edit `build.gradle` to be a project file and `lib/build.gradle` to be a module file.\n6. `chmod +x ./gradlew`\n7. `./gradlew build`  \n(\u003c 20 seconds on MacBook Pro M4 Pro to [eventually; see \"Changes\"] successfully compile from clean)\n\nAll of this is also shown in the `openai-kotlin-client.sh` file.\n\n## Changes\nAt this point, the build will actually fail.  \nI had to make some manual changes in order to get it to compile successfully:\n1. AudioApi.kt:\n   1. change `AudioResponseFormat? = json` to `AudioResponseFormat? = AudioResponseFormat.json`\n   2. change `timestampGranularities?.value` to `timestampGranularities`\n2. remove `data` (`data class ...`-\u003e`class ...`) in:\n   1. CreateAssistantRequestToolResourcesFileSearch.kt\n   2. CreateThreadRequestToolResourcesFileSearch.kt\n\nThis just got it to **COMPILE** successfully!\n\nI had to make further changes in order to get it to **RUN** successfully.  \n\nAll of my changes can be seen at:  \nhttps://github.com/swooby/openai-openapi-kotlin/pull/1/files\n\n## Updates\nWhen a new spec comes out:\n1. Make sure to start from a fresh/stashed checkout.\n2. `rm -r ./lib/src`\n3. `curl -o openapi-YYYYMMDD.yaml https://raw.githubusercontent.com/openai/openai-openapi/refs/heads/master/openapi.yaml`\n4. `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`\n5. Fix generated gradle files:\n   1. `mv lib/build.gradle lib/build.gradle.kts`\n   2. `rm -f ./gradle \u0026\u0026 mv lib/gradle* .`\n   3. `mv lib/settings.gradle ./settings.gradle.kts`\n   4. Compare/Review with the settings.gradle and build.gradle files.\n       1. `gradle*`: probably discard all changes\n       2. `settings.gradle.kts`: probably discard all changes\n       3. `lib/build.gradle.kts`: probably discard all changes\n   5. While you are here, update any dependencies in `gradle/libs.versions.toml`\n6. Consistently format all generated code with `./gradlew spotlessApply`\n7. Fix generated code compiler errors:  \n   TODO: Open an OpenAPI or OpenAI bug on these... \n   1. `apis/AudioApi`\n      1. add/keep `AudioResponseFormat.json`\n      2. add/keep `timestampGranularities?.value`\n   2. `models/CreateAssistantRequestToolResourcesFileSearch`: keep non-data class  \n      (compiler error to have data class with no constructor parameters)\n   3. `models/CreateThreadRequestToolResourcesFileSearch`: keep non-data class  \n      (compiler error to have data class with no constructor parameters)\n8. Review each changed file, especially ones that show as modified in:  \n   https://github.com/swooby/openai-openapi-kotlin/pull/1/files\n   1. `apis` \u0026 `docs`: probably keep all changes\n   2. `infrastructure`:\n      1. `ApiClient.kt`: probably discard all changes\n      2. `BigDecimalAdapter.kt`: probably discard all changes\n      3. `BigIntegerAdapter.kt`: probably discard all changes\n      4. `Serializer.kt`: probably discard all changes\n   3. `models`: probably keep all changes except...\n      1. `Realtime*` files:  \n         (This can get a little complicated...)\n         1. `RealtimeClientEvent*`: Keep all `type: RealtimeClientEvent*.Type = RealtimeClientEvent*.Type....` one-line assignments  \n            These help a lot to simplify sending client events. \n         2. `RealtimeConversationItem`\n            1. add/keep `in_progress` in nested `Status`; undocumented value comes from the server\n         3. `RealtimeConversationItemContentInner`\n            1. add/keep `audio` in nested `Type`; undocumented value comes from the server\n         4. `RealtimeResponse`\n            1. change/keep `maxOutputTokens` to type `RealtimeSessionMaxResponseOutputTokens`\n            2. add/keep `in_progress` in nested `Status`; undocumented value comes from the server\n         5. `RealtimeResponseCreateParams`\n            1. change/keep `maxResponseOutputTokens` to type `RealtimeSessionMaxResponseOutputTokens`\n         6. `RealtimeResponseCreateParamsConversation`\n            1. add/keep `enum class ... auto, none ...`\n         7. move `RealtimeResponseCreateParamsMaxResponseOutputTokens` to common `RealtimeSessionMaxResponseOutputTokens`  \n            This empty class would cause a runtime deserialization exception.\n         8. move `RealtimeResponseMaxOutputTokens` to common `RealtimeSessionMaxResponseOutputTokens`\n            This empty class would cause a runtime deserialization exception.\n         9. `RealtimeServerEventConversationItemCreated`\n            1. add/keep nullable `previousItemId`; null value comes from the server\n         10. `RealtimeServerEventInputAudioBufferCommitted`:\n             1. add/keep nullable `previousItemId`; null value comes from the server\n         11. `RealtimeSession`\n             1. `model`\n                1. add/keep javadoc\n                2. change/keep type to `kotlin.String?` \n             2. change/keep `maxResponseOutputTokens` to type `RealtimeSessionMaxResponseOutputTokens`\n         12. `RealtimeSessionCreateRequest`\n             1. add/keep `@SerializeNull`\n             2. change/keep `maxResponseOutputTokens` to type `RealtimeSessionMaxResponseOutputTokens`\n             3. nested `enum class Model`\n                1. change/keep javadoc\n                2. change/keep `gpt-4o-realtime-preview ...` simplification;  \n                   The generated names leave out `gpt-4o-`.\n         13. `RealtimeSessionCreateRequestInputAudioTranscription`\n             1. add/keep nested `enum class Model whisper-1 ...`\n             2. change/keep `model` to nested `Model`\n         14. `RealtimeSessionCreateRequestTurnDetection`\n             1. add/keep nested `enum class Type server_vad ...`\n             2. change/keep `type` to nested `Type` \n         15. `RealtimeSessionCreateResponse`\n             1. change/keep `maxResponseOutputTokens` to type `RealtimeSessionMaxResponseOutputTokens`\n         16. restore/reset/keep `RealtimeSessionMaxResponseOutputTokens` \n         16. delete `RealtimeSessionModel`  \n             This empty class would cause a runtime deserialization exception.\n   4. `test`: probably keep all changes except...\n      1. revert `RealtimeResponseCreateParamsMaxResponseOutputTokensTest`  \n         detected as a rename from `RealtimeSessionMaxResponseOutputTokensTest`\n      2. delete `RealtimeResponseMaxOutputTokensTest`\n      3. delete `RealtimeSessionModelTest`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswooby%2Fopenai-openapi-kotlin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswooby%2Fopenai-openapi-kotlin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswooby%2Fopenai-openapi-kotlin/lists"}