Access OpenAI ChatGPT Official API using Swift.
- OpenAI like API, written on Swift.
- Works on all Apple platforms and Linux.
- Full Swift Concurrency and Swift 6 integration.
- Supported ChatCompletion (text generation), and later Assistant API, Audio (voice generation, text transcriptions), Image generation functions.
Current project based on a ChatGPTSwift package.
- OpenAI like API, not one class for all functions.
- Full Swift Concurrency integration without data races,
unchecked @Sendableand other non-Sendable classes. - Added the ability to use your own server URL for requests (it is relevant if necessary to use proxy).
- Used actual version of OpenAPI.yaml.
- Used friendly ChatGPT models an other names, such as
.gpt4oinstead of.gpt_hyphen_4o,.textEventStreaminstead of.text_event_hyphen_streamand etc. - Improved bugs in internal logic.
- Removed logic of store messages list (
historyListproperty). It was an outdated solution that requires improvements, and now Assistants API is able to reduce the size of the context in auto mode. - Removed deprecated support of CocoaPods.
- iOS/tvOS 16 and above
- macOS 13 and above
- watchOS 9 and above
- Linux
By default, the current Swift version compatible with the package is 6.0, but you can use it with previous versions of language.
In Swift 5.7 a new syntax for regular expressions (/_regex_here_/) was added, which is used in this package. Up until Swift 6.0, its usage in SPM packages was restricted with the flag -enable-bare-slash-regex, although no issues arose when used in applications. If I manually add this flag to the package target, you will not be able to connect the package from my GitHub (using remote packages with unsafe flags not possible).
To work around this limitation, do the following:
- Clone the package for local inclusion in your project.
- In the Package.swift file, change the Swift version to 5.10 (or another required version)
// swift-tools-version: 5.10- Add the flag -enable-bare-slash-regex in the SwiftGPT target initializer
swiftSettings: [.unsafeFlags(["-enable-bare-slash-regex"])]- File > Swift Packages > Add Package Dependency
- Add https://github.com/DobbyWanKenoby/SwiftGPT.git
Register for API key from OpenAI.
Specify global configuration, that are common to all sessions, using static properties of type OpenAI.Configuration. You can later override the settings on individually for each session.
Firstly set API key:
OpenAI.Configuration.apiKey = .apiKey("API_KEY")If you require more complex logic of working with an API key, then use APIKeyProvider. Below is an example in which the API key is requested asynchronously from a remote server, and during this time, all requests will wait for the completion of the retrieval process.
// Custom APIKeyProvider imlementation
actor ServiceAPIKeyProvider: OpenAI.APIKeyProvider {
private var _apiKey: String?
var apiKey: String {
get async throws {
// Wait while API key not setted
while _apiKey == nil {
try Task.checkCancellation()
await Task.yield()
}
return _apiKey!
}
}
init(apiKey: String? = nil) {
_apiKey = apiKey
}
func fetchAPIKey() async throws -> String {
_apiKey = nil
let newAPIKey = try await // ... fetching logic
_apiKey = newAPIKey
}
}
// Set provider to global configuration
let provider = ServiceAPIKeyProvider(apiKey: "API_KEY")
OpenAI.Configuration.apiKey = .provider(provider)You can specify server URL:
OpenAI.Configuration.url = "https://you_own_proxy_chatgpt.com"Other sesttings you can see in specification of
OpenAI.Configuration.
ChatCompletions type allow you generate text from a promt.
First create OpenAI.Chat instance with passing used model:
// Pass model version
let chat = OpenAI.Chat(model: .gpt4o)if current package have not KeyPath with needed model, you can use another OpenAI.Chat.init to pass custom model name:
// Pass textual name of model
let chat = OpenAI.Chat(model: .custom("gpt-4o-2024-11-20"))There are 2 APIs: stream and normal
A normal HTTP request and response lifecycle. Server will send the complete text (it will take more time to response):
let response = try await chat.completions(promt: "Please tell me about Space")
print(response)The server will stream chunks of data until complete, the method AsyncThrowingStream which you can loop using For-Loop like so:
let stream = try await chat.streamCompletions(promt: "What is ChatGPT?")
for try await line in stream {
print(line)
}Optionally, you can pass additional configuration to completions method. Because OpenAI.Chat is a generic, you must take certain using configuration-type. You can do this using the property ConfigurationType of OpenAI.Chat instance:
// Create empty configuration
var configuration = chat.ConfigurationType.init()
// Configure
configuration.maxTokens = 100
configuration.temperature = 0.8
// Pass configuration to completion method
let response = chat.completion(promt: "What is ChatGPT?", configuration: configuration)To learn more about those parameters, you can visit the official ChatGPT API documentation and ChatGPT API Introduction Page
Optionally, you can pass developer (system) message and history of messages to request. Just use properties from completions method:
let response = try await chat.completions(
promt: "Please tell me about Space",
developerText: "You a senior Swift developer with 20 years of experience",
previousMessages: [/** Array with previous messages**/]
)Some models use
developerkey, and some -systemkey for developer-provided instructions that the model should follow (parametermessagesin HTTP-request, see official API documentation for additional info). SwiftGPT incapsulate this logic and use needed key automatically. Only when you createOpenAI.Chatinstance withinit(customModelName:)you need to specify which keys to use (propertydeveloperMessageKeyin configuration instance).
You can pass image to completions request. Just use image property:
let image: Data = ...
let response = try await chat.completions(
promt: "Is there an notebook on this image?",
image: image
) If you want to contribute to the project by adding new parameters to existing APIs or creating new APIs, simply create a Merge Request.
- Add parameters to ChatCompetions (such as tools and etc)
- Add Audio (TTS, STT) API
- Add Assistants API
- Add Image Generation API