Skip to content

Commit 975151c

Browse files
committed
Add code snippets for text generation
1 parent 5478400 commit 975151c

File tree

3 files changed

+157
-0
lines changed

3 files changed

+157
-0
lines changed

Package.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,10 @@ let package = Package(
4444
.process("GoogleAITests/GenerateContentResponses"),
4545
]
4646
),
47+
.testTarget(
48+
name: "CodeSnippetTests",
49+
dependencies: ["GoogleGenerativeAI"],
50+
path: "samples"
51+
),
4752
]
4853
)

samples/APIKey.swift

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import Foundation
16+
import XCTest
17+
18+
/// A private wrapper for `APIKey`, hiding it from test files.
19+
private enum APIKeyCodeSnippet {
20+
// The implementation of `APIKey` for use in documentation code snippets; shown in
21+
// https://ai.google.dev/gemini-api/docs/quickstart?lang=swift
22+
// [START setup_api_key]
23+
enum APIKey {
24+
// Fetch the API key from `GenerativeAI-Info.plist`
25+
static var `default`: String {
26+
guard let filePath = Bundle.main.path(forResource: "GenerativeAI-Info", ofType: "plist")
27+
else {
28+
fatalError("Couldn't find file 'GenerativeAI-Info.plist'.")
29+
}
30+
let plist = NSDictionary(contentsOfFile: filePath)
31+
guard let value = plist?.object(forKey: "API_KEY") as? String else {
32+
fatalError("Couldn't find key 'API_KEY' in 'GenerativeAI-Info.plist'.")
33+
}
34+
if value.starts(with: "_") {
35+
fatalError(
36+
"Follow the instructions at https://ai.google.dev/tutorials/setup to get an API key."
37+
)
38+
}
39+
return value
40+
}
41+
}
42+
// [END setup_api_key]
43+
}
44+
45+
/// Protocol to ensure that the `APIKey` APIs do not diverge.
46+
protocol APIKeyProtocol {
47+
static var `default`: String { get }
48+
}
49+
50+
extension APIKeyCodeSnippet.APIKey: APIKeyProtocol {}
51+
52+
/// An implementation of `APIKey` for use in code snippet tests only.
53+
enum APIKey: APIKeyProtocol {
54+
static let apiKeyEnvVar = "API_KEY"
55+
56+
static var `default`: String {
57+
guard let apiKey = ProcessInfo.processInfo.environment[apiKeyEnvVar] else {
58+
return ""
59+
}
60+
return apiKey
61+
}
62+
}

samples/TextGeneration.swift

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import GoogleGenerativeAI
16+
import XCTest
17+
18+
@available(iOS 15.0, macOS 11.0, macCatalyst 15.0, *)
19+
final class TextGeneration: XCTestCase {
20+
override func setUpWithError() throws {
21+
try XCTSkipIf(APIKey.default.isEmpty, "`\(APIKey.apiKeyEnvVar)` environment variable not set.")
22+
}
23+
24+
func testTextOnlyPrompt() async throws {
25+
// [START text_gen_text_only_prompt]
26+
let generativeModel =
27+
GenerativeModel(
28+
// Specify a Gemini model appropriate for your use case
29+
name: "gemini-1.5-flash",
30+
// Access your API key from your on-demand resource .plist file (see "Set up your API key"
31+
// above)
32+
apiKey: APIKey.default
33+
)
34+
35+
let prompt = "Write a story about a magic backpack."
36+
let response = try await generativeModel.generateContent(prompt)
37+
if let text = response.text {
38+
print(text)
39+
}
40+
// [END text_gen_text_only_prompt]
41+
}
42+
43+
func testTextOnlyPromptStreaming() async throws {
44+
// [START text_gen_text_only_prompt_streaming]
45+
let generativeModel =
46+
GenerativeModel(
47+
// Specify a Gemini model appropriate for your use case
48+
name: "gemini-1.5-flash",
49+
// Access your API key from your on-demand resource .plist file (see "Set up your API key"
50+
// above)
51+
apiKey: APIKey.default
52+
)
53+
54+
let prompt = "Write a story about a magic backpack."
55+
// Use streaming with text-only input
56+
for try await response in generativeModel.generateContentStream(prompt) {
57+
if let text = response.text {
58+
print(text)
59+
}
60+
}
61+
// [END text_gen_text_only_prompt_streaming]
62+
}
63+
64+
func testMultimodalOneImagePrompt() async throws {
65+
// [START text_gen_multimodal_one_image_prompt]
66+
let generativeModel =
67+
GenerativeModel(
68+
// Specify a Gemini model appropriate for your use case
69+
name: "gemini-1.5-flash",
70+
// Access your API key from your on-demand resource .plist file (see "Set up your API key"
71+
// above)
72+
apiKey: APIKey.default
73+
)
74+
75+
#if canImport(UIKit)
76+
guard let image = UIImage(systemName: "cloud.sun") else { fatalError() }
77+
#elseif canImport(AppKit)
78+
guard let image = NSImage(systemSymbolName: "cloud.sun", accessibilityDescription: nil)
79+
else { fatalError() }
80+
#endif
81+
82+
let prompt = "What's in this picture?"
83+
84+
let response = try await generativeModel.generateContent(image, prompt)
85+
if let text = response.text {
86+
print(text)
87+
}
88+
// [END text_gen_multimodal_one_image_prompt]
89+
}
90+
}

0 commit comments

Comments
 (0)