Skip to content

Commit 7278ddb

Browse files
authored
Added AIProxy details to the README (#24)
1 parent e053028 commit 7278ddb

File tree

4 files changed

+90
-13
lines changed

4 files changed

+90
-13
lines changed

Examples/SwiftOpenAIExample/SwiftOpenAIExample/AIProxyIntroView.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct AIProxyIntroView: View {
3636
.disabled(partialKey.isEmpty)
3737
Spacer()
3838
Group {
39-
Text("You can now use SwiftOpenAI for development and production! AI Proxy keeps your OpenAI API key secure. To configure AI Proxy for your project, or to learn more about how it works, please see the docs at ") + Text("[this link](https://www.aiproxy.pro/docs).")
39+
Text("You can now use SwiftOpenAI for development and production! AIProxy keeps your OpenAI API key secure. To configure AIProxy for your project, or to learn more about how it works, please see the docs at ") + Text("[this link](https://www.aiproxy.pro/docs).")
4040
}
4141
.font(.caption)
4242
}
@@ -46,7 +46,7 @@ struct AIProxyIntroView: View {
4646
}
4747

4848
private var aiproxyService: some OpenAIService {
49-
// Attention AI Proxy customers!
49+
// Attention AIProxy customers!
5050
//
5151
// Please do not let a `deviceCheckBypass` slip into an archived version of your app that you distribute (including through TestFlight).
5252
// Doing so would allow an attacker to use the bypass themselves.

Examples/SwiftOpenAIExample/SwiftOpenAIExample/ServiceSelectionView.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ struct ServiceSelectionView: View {
2727

2828
NavigationLink(destination: AIProxyIntroView()) {
2929
VStack(alignment: .leading) {
30-
Text("AI Proxy Service")
30+
Text("AIProxy Service")
3131
.padding(.bottom, 10)
3232
Group {
33-
Text("Use this service to test SwiftOpenAI functionality with requests proxied through AI Proxy for key protection.")
33+
Text("Use this service to test SwiftOpenAI functionality with requests proxied through AIProxy for key protection.")
3434
}
3535
.font(.caption)
3636
.fontWeight(.light)

README.md

+84-7
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@ An open-source Swift package designed for effortless interaction with OpenAI's p
1515
- [Getting an API Key](#getting-an-api-key)
1616
- [Installation](#installation)
1717
- [Usage](#usage)
18-
- [Azure OpenAI](#azure-openAI)
18+
- [Azure OpenAI](#azure-openai)
19+
- [AIProxy](#aiproxy)
1920
- [Collaboration](#collaboration)
2021

2122
## Description
2223

23-
`SwiftOpenAI` is an open-source Swift package that streamlines interactions with **all** OpenAI's API endpoints, now with added support for Azure and Assistant stream APIs.
24+
`SwiftOpenAI` is an open-source Swift package that streamlines interactions with **all** OpenAI's API endpoints, now with added support for Azure, AIProxy, and Assistant stream APIs.
2425

2526
### OpenAI ENDPOINTS
2627

@@ -63,6 +64,17 @@ To interact with OpenAI services, you'll need an API key. Follow these steps to
6364

6465
For more information, consult OpenAI's [official documentation](https://platform.openai.com/docs/).
6566

67+
⚠️ Please take precaution to keep your API key secure per [OpenAI's guidance](https://platform.openai.com/docs/api-reference/authentication):
68+
69+
> Remember that your API key is a secret! Do not share it with others or expose
70+
> it in any client-side code (browsers, apps). Production requests must be
71+
> routed through your own backend server where your API key can be securely
72+
> loaded from an environment variable or key management service.
73+
74+
SwiftOpenAI has built-in support for AIProxy, which is a backend for AI apps, to satisfy this requirement.
75+
To configure AIProxy, see the instructions [here](#aiproxy).
76+
77+
6678
## Installation
6779

6880
### Swift Package Manager
@@ -1021,11 +1033,11 @@ let content: ChatCompletionParameters.Message.ContentType = .text(prompt)
10211033
let parameters = ChatCompletionParameters(messages: [.init(role: .user, content: content)], model: .gpt41106Preview, tools: [tool])
10221034
let chatCompletionObject = try await service.startStreamedChat(parameters: parameters)
10231035
```
1024-
For more details about how to also uploadin base 64 encoded images in iOS check the [ChatFunctionsCalllDemo](https://github.com/jamesrochabrun/SwiftOpenAI/tree/main/Examples/SwiftOpenAIExample/SwiftOpenAIExample/ChatFunctionsCall) demo on the Examples section of this package.
1036+
For more details about how to also uploading base 64 encoded images in iOS check the [ChatFunctionsCalllDemo](https://github.com/jamesrochabrun/SwiftOpenAI/tree/main/Examples/SwiftOpenAIExample/SwiftOpenAIExample/ChatFunctionsCall) demo on the Examples section of this package.
10251037

10261038
### Vision
10271039

1028-
[Vison](https://platform.openai.com/docs/guides/vision) API is available for use; developers must access it through the chat completions API, specifically using the gpt-4-vision-preview model. Using any other model will not provide an image description
1040+
[Vision](https://platform.openai.com/docs/guides/vision) API is available for use; developers must access it through the chat completions API, specifically using the gpt-4-vision-preview model. Using any other model will not provide an image description
10291041

10301042
Usage
10311043
```swift
@@ -1038,7 +1050,7 @@ let chatCompletionObject = try await service.startStreamedChat(parameters: param
10381050

10391051
![Simulator Screen Recording - iPhone 15 - 2023-11-09 at 17 12 06](https://github.com/jamesrochabrun/SwiftOpenAI/assets/5378604/db2cbb3b-0c80-4ac8-8fe5-dbb782b270da)
10401052

1041-
For more details about how to also uploadin base 64 encoded images in iOS check the [ChatVision](https://github.com/jamesrochabrun/SwiftOpenAI/tree/main/Examples/SwiftOpenAIExample/SwiftOpenAIExample/Vision) demo on the Examples section of this package.
1053+
For more details about how to also uploading base 64 encoded images in iOS check the [ChatVision](https://github.com/jamesrochabrun/SwiftOpenAI/tree/main/Examples/SwiftOpenAIExample/SwiftOpenAIExample/Vision) demo on the Examples section of this package.
10421054

10431055
### Embeddings
10441056
Parameters
@@ -2179,7 +2191,7 @@ let parameters = MessageParameter(role: "user", content: prompt")
21792191
let message = try await service.createMessage(threadID: threadID, parameters: parameters)
21802192
```
21812193
2182-
Retireve Message.
2194+
Retrieve Message.
21832195
```swift
21842196
let threadID = "thread_abc123"
21852197
let messageID = "msg_abc123"
@@ -2652,5 +2664,70 @@ let parameters = ChatCompletionParameters(
26522664
let completionObject = try await service.startChat(parameters: parameters)
26532665
```
26542666
2655-
### Collaboration
2667+
## AIProxy
2668+
2669+
### What is it?
2670+
2671+
[AIProxy](https://www.aiproxy.pro) is a backend for AI apps that proxies requests from your app to OpenAI.
2672+
You can use this service to avoid exposing your OpenAI key in your app.
2673+
We offer AIProxy support so that developers can build **and** distribute apps using SwiftOpenAI.
2674+
2675+
### How does my SwiftOpenAI code change?
2676+
2677+
SwiftOpenAI supports proxying requests through AIProxy with a small change to your integration code.
2678+
2679+
Instead of initializing `service` with:
2680+
2681+
let apiKey = "your_openai_api_key_here"
2682+
let service = OpenAIServiceFactory.service(apiKey: apiKey)
2683+
2684+
Use:
2685+
2686+
#if DEBUG && targetEnvironment(simulator)
2687+
let service = OpenAIServiceFactory.service(
2688+
aiproxyPartialKey: "hardcode_partial_key_here",
2689+
aiproxyDeviceCheckBypass: "hardcode_device_check_bypass_here"
2690+
)
2691+
#else
2692+
let service = OpenAIServiceFactory.service(
2693+
aiproxyPartialKey: "hardcode_partial_key_here"
2694+
)
2695+
#endif
2696+
2697+
The `aiproxyPartialKey` and `aiproxyDeviceCheckBypass` values are provided to you on the [AIProxy developer dashboard](https://developer.aiproxy.pro).
2698+
2699+
⚠️ It is important that you do not let the `aiproxyDeviceCheckBypass` token leak into a distribution
2700+
build of your app (including TestFlight distributions). Please retain the conditional compilation
2701+
checks that are present in the sample code above.
2702+
2703+
#### What is the `aiproxyDeviceCheckBypass` constant?
2704+
2705+
AIProxy uses Apple's [DeviceCheck](https://developer.apple.com/documentation/devicecheck) to ensure
2706+
that requests received by the backend originated from your app on a legitimate Apple device.
2707+
However, the iOS simulator cannot produce DeviceCheck tokens. Rather than requiring you to
2708+
constantly build and run on device during development, AIProxy provides a way to skip the
2709+
DeviceCheck integrity check. The token is intended for use by developers only. If an attacker gets
2710+
the token, they can make requests to your AIProxy project without including a DeviceCheck token, and
2711+
thus remove one level of protection.
2712+
2713+
#### What is the `aiproxyPartialKey` constant?
2714+
2715+
This constant is intended to be **included** in the distributed version of your app. As the name implies, it is a
2716+
partial representation of your OpenAI key. Specifically, it is one half of an encrypted version of your key.
2717+
The other half resides on AIProxy's backend. As your app makes requests to AIProxy, the two encrypted parts
2718+
are paired, decrypted, and used to fulfill the request to OpenAI.
2719+
2720+
#### How to setup my project on AIProxy?
2721+
2722+
Please see the [AIProxy integration guide](https://www.aiproxy.pro/docs/integration-guide.html)
2723+
2724+
2725+
### ⚠️ Disclaimer
2726+
2727+
Contributors of SwiftOpenAI shall not be liable for any damages or losses caused by third parties.
2728+
Contributors of this library provide third party integrations as a convenience. Any use of a third
2729+
party's services are assumed at your own risk.
2730+
2731+
2732+
## Collaboration
26562733
Open a PR for any proposed change pointing it to `main` branch.

Sources/OpenAI/Public/Service/OpenAIServiceFactory.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ public class OpenAIServiceFactory {
7272
/// #endif
7373
///
7474
/// - Parameters:
75-
/// - aiproxyPartialKey: The partial key provided in the 'API Keys' section of the AI Proxy dashboard.
75+
/// - aiproxyPartialKey: The partial key provided in the 'API Keys' section of the AIProxy dashboard.
7676
/// Please see the integration guide for acquiring your key, at https://www.aiproxy.pro/docs
77-
/// - aiproxyDeviceCheckBypass: The bypass token that is provided in the 'API Keys' section of the AI Proxy dashboard.
77+
/// - aiproxyDeviceCheckBypass: The bypass token that is provided in the 'API Keys' section of the AIProxy dashboard.
7878
/// Please see the integration guide for acquiring your key, at https://www.aiproxy.pro/docs
7979
/// - configuration: The URL session configuration to be used for network calls (default is `.default`).
8080
/// - decoder: The JSON decoder to be used for parsing API responses (default is `JSONDecoder.init()`).

0 commit comments

Comments
 (0)