Skip to content

Commit f150666

Browse files
kinelskiscottaddie
andauthored
Added migration guide (#13)
* Added migration guide * PR feedback * more feedback * why not some more * Update MigrationGuide.md Co-authored-by: Scott Addie <10702007+scottaddie@users.noreply.github.com> * Update MigrationGuide.md Co-authored-by: Scott Addie <10702007+scottaddie@users.noreply.github.com> * keep them coming * Update MigrationGuide.md Co-authored-by: Scott Addie <10702007+scottaddie@users.noreply.github.com> * Update MigrationGuide.md Co-authored-by: Scott Addie <10702007+scottaddie@users.noreply.github.com> * Update MigrationGuide.md Co-authored-by: Scott Addie <10702007+scottaddie@users.noreply.github.com> * Update MigrationGuide.md Co-authored-by: Scott Addie <10702007+scottaddie@users.noreply.github.com> * Update MigrationGuide.md Co-authored-by: Scott Addie <10702007+scottaddie@users.noreply.github.com> * Update MigrationGuide.md Co-authored-by: Scott Addie <10702007+scottaddie@users.noreply.github.com> * Update MigrationGuide.md Co-authored-by: Scott Addie <10702007+scottaddie@users.noreply.github.com> * almost there * minor change for consistency: * Update version --------- Co-authored-by: Scott Addie <10702007+scottaddie@users.noreply.github.com>
1 parent bf21eb5 commit f150666

1 file changed

Lines changed: 341 additions & 0 deletions

File tree

MigrationGuide.md

Lines changed: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
# Guide for migrating to OpenAI 2.0.0-beta.1 or higher from OpenAI 1.11.0
2+
3+
This guide is intended to assist in the migration to the official OpenAI library (2.0.0-beta.1 or higher) from [OpenAI 1.11.0][openai_1110], focusing on side-by-side comparisons for similar operations between libraries. Version 2.0.0-beta.1 will be used for comparison with 1.11.0 but this guide can still be safely used when migrating to higher versions.
4+
5+
Prior to 2.0.0-beta.1, the OpenAI package was a community library not officially supported by OpenAI. See the [CHANGELOG][changelog] for more details.
6+
7+
Familiarity with the OpenAI 1.11.0 package is assumed. For those new to any OpenAI library for .NET, see the [README][readme] rather than this guide.
8+
9+
## Table of contents
10+
- [Client usage](#client-usage)
11+
- [Authentication](#authentication)
12+
- [Highlighted scenarios](#highlighted-scenarios)
13+
- [Chat Completions: Text generation](#chat-completions-text-generation)
14+
- [Chat Completions: Streaming](#chat-completions-streaming)
15+
- [Chat Completions: JSON mode](#chat-completions-json-mode)
16+
- [Chat Completions: Vision](#chat-completions-vision)
17+
- [Audio: Speech-to-text](#audio-speech-to-text)
18+
- [Audio: Text-to-speech](#audio-text-to-speech)
19+
- [Image: Image generation](#image-image-generation)
20+
- [Additional examples](#additional-examples)
21+
22+
## Client usage
23+
24+
The client usage has considerably changed between libraries. While the OpenAI 1.11.0 had a single client, `OpenAIAPI`, from which multiple APIs could be accessed, OpenAI 2.0.0-beta.1 keeps a separate client per API. The following snippets illustrate this difference when invoking the image generation capability from the Image API:
25+
26+
OpenAI 1.11.0:
27+
```cs
28+
OpenAIAPI api = new OpenAIAPI("<api-key>");
29+
ImageResult result = await api.ImageGenerations.CreateImageAsync("Draw a quick brown fox jumping over a lazy dog.", Model.DALLE3);
30+
```
31+
32+
OpenAI 2.0.0-beta.1:
33+
```cs
34+
ImageClient client = new ImageClient("dall-e-3", "<api-key>");
35+
ClientResult<GeneratedImage> result = await client.GenerateImageAsync("Draw a quick brown fox jumping over a lazy dog.");
36+
```
37+
38+
Another major difference highlighted in the snippets above is that OpenAI 2.0.0-beta.1 requires the model to be explicitly set during client instantiation, while the `OpenAIAPI` client allows a model to be specified per call.
39+
40+
The table below illustrates to which client each endpoint of `OpenAIAPI` was ported. Note that the deprecated Completions API is not supported in 2.0.0-beta.1:
41+
42+
Old library's endpoint|New library's client
43+
|-|-
44+
|Chat | ChatClient
45+
|ImageGenerations | ImageClient
46+
|TextToSpeech | AudioClient
47+
|Transcriptions | AudioClient
48+
|Translations | AudioClient
49+
|Moderation | ModerationClient
50+
|Embeddings | EmbeddingClient
51+
|Files | FileClient
52+
|Models | ModelClient
53+
|Completions | Not supported
54+
55+
## Authentication
56+
57+
To authenticate to OpenAI, you must set an API key when creating a client.
58+
59+
OpenAI 1.11.0 allowed setting the API key in 3 different ways:
60+
- Directly from a string
61+
- From an environment variable
62+
- From a configuration file
63+
64+
```cs
65+
OpenAIAPI api;
66+
67+
// Sets the API key directly from a string.
68+
api = new OpenAIAPI("<api-key>");
69+
70+
// Attempts to load the API key from environment variables OPENAI_KEY and OPENAI_API_KEY.
71+
api = new OpenAIAPI(APIAuthentication.LoadFromEnv());
72+
73+
// Attempts to load the API key from a configuration file.
74+
api = new OpenAIAPI(APIAuthentication.LoadFromPath("<directory>", "<filename>"));
75+
```
76+
77+
OpenAI 2.0.0-beta.1 only supports setting it from a string or from an environment variable. The following snippet illustrates the behavior with the `ChatClient`, but other clients behave the same:
78+
79+
```cs
80+
ChatClient client;
81+
82+
// Sets the API key directly from a string.
83+
client = new ChatClient("gpt-3.5-turbo", "<api-key>");
84+
85+
// When no API key string is specified, attempts to load the API key from the environment variable OPENAI_API_KEY.
86+
client = new ChatClient("gpt-3.5-turbo");
87+
```
88+
89+
Note that, unlike the OpenAI 1.11.0, OpenAI 2.0.0-beta.1 will never attempt to load the API key from the `OPENAI_KEY` environment variable. Only `OPENAI_API_KEY` is supported.
90+
91+
## Highlighted scenarios
92+
93+
The following sections illustrate side-by-side comparisons for similar operations between the two libraries, highlighting common scenarios.
94+
95+
### Chat Completions: Text generation
96+
97+
OpenAI 1.11.0:
98+
```cs
99+
OpenAIAPI api = new OpenAIAPI("<api-key>");
100+
Conversation conversation = api.Chat.CreateConversation();
101+
102+
conversation.Model = Model.ChatGPTTurbo;
103+
conversation.AppendSystemMessage("You are a helpful assistant.");
104+
conversation.AppendUserInput("When was the Nobel Prize founded?");
105+
106+
await conversation.GetResponseFromChatbotAsync();
107+
108+
conversation.AppendUserInput("Who was the first person to be awarded one?");
109+
110+
await conversation.GetResponseFromChatbotAsync();
111+
112+
foreach (ChatMessage message in conversation.Messages)
113+
{
114+
Console.WriteLine($"{message.Role}: {message.TextContent}");
115+
}
116+
```
117+
118+
OpenAI 2.0.0-beta.1:
119+
```cs
120+
ChatClient client = new ChatClient("gpt-3.5-turbo", "<api-key>");
121+
List<ChatMessage> messages = new List<ChatMessage>()
122+
{
123+
new SystemChatMessage("You are a helpful assistant."),
124+
new UserChatMessage("When was the Nobel Prize founded?")
125+
};
126+
127+
ClientResult<ChatCompletion> result = await client.CompleteChatAsync(messages);
128+
129+
messages.Add(new AssistantChatMessage(result));
130+
messages.Add(new UserChatMessage("Who was the first person to be awarded one?"));
131+
132+
result = await client.CompleteChatAsync(messages);
133+
134+
messages.Add(new AssistantChatMessage(result));
135+
136+
foreach (ChatMessage message in messages)
137+
{
138+
string role = message.GetType().Name;
139+
string text = message.Content[0].Text;
140+
141+
Console.WriteLine($"{role}: {text}");
142+
}
143+
```
144+
145+
### Chat Completions: Streaming
146+
147+
OpenAI 1.11.0:
148+
```cs
149+
OpenAIAPI api = new OpenAIAPI("<api-key>");
150+
Conversation conversation = api.Chat.CreateConversation();
151+
152+
conversation.Model = Model.ChatGPTTurbo;
153+
conversation.AppendUserInput("Give me a list of Nobel Prize winners of the last 5 years.");
154+
155+
await foreach (string response in conversation.StreamResponseEnumerableFromChatbotAsync())
156+
{
157+
Console.Write(response);
158+
}
159+
```
160+
161+
OpenAI 2.0.0-beta.1:
162+
```cs
163+
ChatClient client = new ChatClient("gpt-3.5-turbo", "<api-key>");
164+
List<ChatMessage> messages = new List<ChatMessage>()
165+
{
166+
new UserChatMessage("Give me a list of Nobel Prize winners of the last 5 years.")
167+
};
168+
169+
await foreach (StreamingChatCompletionUpdate chatUpdate in client.CompleteChatStreamingAsync(messages))
170+
{
171+
if (chatUpdate.ContentUpdate.Count > 0)
172+
{
173+
Console.Write(chatUpdate.ContentUpdate[0].Text);
174+
}
175+
}
176+
```
177+
178+
### Chat Completions: JSON mode
179+
180+
OpenAI 1.11.0:
181+
```cs
182+
OpenAIAPI api = new OpenAIAPI("<api-key>");
183+
ChatRequest request = new ChatRequest()
184+
{
185+
Model = Model.ChatGPTTurbo,
186+
ResponseFormat = request.ResponseFormats.JsonObject,
187+
Messages = new List<ChatMessage>()
188+
{
189+
new ChatMessage(ChatMessageRole.System, "You are a helpful assistant designed to output JSON."),
190+
new ChatMessage(ChatMessageRole.User, "Give me a JSON object listing Nobel Prize winners of the last 5 years.")
191+
}
192+
};
193+
194+
ChatResult result = await api.Chat.CreateChatCompletionAsync(request);
195+
196+
Console.WriteLine(result);
197+
```
198+
199+
OpenAI 2.0.0-beta.1:
200+
```cs
201+
ChatClient client = new ChatClient("gpt-3.5-turbo", "<api-key>");
202+
List<ChatMessage> messages = new List<ChatMessage>()
203+
{
204+
new SystemChatMessage("You are a helpful assistant designed to output JSON."),
205+
new UserChatMessage("Give me a JSON object listing Nobel Prize winners of the last 5 years.")
206+
};
207+
ChatCompletionOptions options = new ChatCompletionOptions()
208+
{
209+
ResponseFormat = ChatResponseFormat.JsonObject
210+
};
211+
212+
ClientResult<ChatCompletion> result = await client.CompleteChatAsync(messages, options);
213+
string text = result.Value.Content[0].Text;
214+
215+
Console.WriteLine(text);
216+
```
217+
218+
### Chat Completions: Vision
219+
220+
OpenAI 1.11.0:
221+
```cs
222+
OpenAIAPI api = new OpenAIAPI("<api-key>");
223+
Conversation conversation = api.Chat.CreateConversation();
224+
byte[] imageData = await File.ReadAllBytesAsync("<file-path>");
225+
226+
conversation.Model = Model.GPT4_Vision;
227+
conversation.AppendUserInput("Describe this image.", ImageInput.FromImageBytes(imageData));
228+
229+
string response = await conversation.GetResponseFromChatbotAsync();
230+
231+
Console.WriteLine(response);
232+
```
233+
234+
OpenAI 2.0.0-beta.1:
235+
```cs
236+
ChatClient client = new ChatClient("gpt-4-vision-preview", "<api-key>");
237+
using FileStream file = File.OpenRead("<file-path>");
238+
BinaryData imageData = await BinaryData.FromStreamAsync(file);
239+
List<ChatMessage> messages = new List<ChatMessage>()
240+
{
241+
new UserChatMessage(
242+
ChatMessageContentPart.CreateTextMessageContentPart("Describe this image."),
243+
ChatMessageContentPart.CreateImageMessageContentPart(imageData, "image/png"))
244+
};
245+
246+
ClientResult<ChatCompletion> result = await client.CompleteChatAsync(messages);
247+
string text = result.Value.Content[0].Text;
248+
249+
Console.WriteLine(text);
250+
```
251+
252+
### Audio: Speech-to-text
253+
254+
OpenAI 1.11.0:
255+
```cs
256+
OpenAIAPI api = new OpenAIAPI("<api-key>");
257+
string result = await api.Transcriptions.GetTextAsync("<file-path>", "fr");
258+
259+
Console.WriteLine(result);
260+
```
261+
262+
OpenAI 2.0.0-beta.1:
263+
```cs
264+
AudioClient client = new AudioClient("whisper-1", "<api-key>");
265+
AudioTranscriptionOptions options = new AudioTranscriptionOptions()
266+
{
267+
Language = "fr"
268+
};
269+
270+
ClientResult<AudioTranscription> result = await client.TranscribeAudioAsync("<file-path>", options);
271+
string text = result.Value.Text;
272+
273+
Console.WriteLine(text);
274+
```
275+
276+
### Audio: Text-to-speech
277+
278+
OpenAI 1.11.0:
279+
```cs
280+
OpenAIAPI api = new OpenAIAPI("<api-key>");
281+
TextToSpeechRequest request = new TextToSpeechRequest()
282+
{
283+
Input = "Hasta la vista, baby.",
284+
Model = Model.TTS_Speed,
285+
Voice = "alloy"
286+
};
287+
288+
await api.TextToSpeech.SaveSpeechToFileAsync(request, "<file-path>");
289+
```
290+
291+
OpenAI 2.0.0-beta.1:
292+
```cs
293+
AudioClient client = new AudioClient("tts-1", "<api-key>");
294+
295+
ClientResult<BinaryData> result = await client.GenerateSpeechFromTextAsync("Hasta la vista, baby.", GeneratedSpeechVoice.Alloy);
296+
BinaryData data = result.Value;
297+
298+
await File.WriteAllBytesAsync("<file-path>", data.ToArray());
299+
```
300+
301+
### Image: Image generation
302+
303+
OpenAI 1.11.0:
304+
```cs
305+
OpenAIAPI api = new OpenAIAPI("<api-key>");
306+
ImageGenerationRequest request = new ImageGenerationRequest()
307+
{
308+
Prompt = "Draw a quick brown fox jumping over a lazy dog.",
309+
Model = Model.DALLE3,
310+
Quality = "standard",
311+
Size = ImageSize._1024
312+
};
313+
314+
ImageResult result = await api.ImageGenerations.CreateImageAsync(request);
315+
316+
Console.WriteLine(result.Data[0].Url);
317+
```
318+
319+
OpenAI 2.0.0-beta.1:
320+
```cs
321+
ImageClient client = new ImageClient("dall-e-3", "<api-key>");
322+
ImageGenerationOptions options = new ImageGenerationOptions()
323+
{
324+
Quality = GeneratedImageQuality.Standard,
325+
Size = GeneratedImageSize.W1024xH1024
326+
};
327+
328+
ClientResult<GeneratedImage> result = await client.GenerateImageAsync("Draw a quick brown fox jumping over a lazy dog.", options);
329+
Uri imageUri = result.Value.ImageUri;
330+
331+
Console.WriteLine(imageUri.AbsoluteUri);
332+
```
333+
334+
## Additional examples
335+
336+
For additional examples, see [OpenAI Examples][examples].
337+
338+
[readme]: https://github.com/openai/openai-dotnet/blob/main/README.md
339+
[changelog]: https://github.com/openai/openai-dotnet/blob/main/CHANGELOG.md
340+
[examples]: https://github.com/openai/openai-dotnet/tree/main/examples
341+
[openai_1110]: https://aka.ms/openai1110

0 commit comments

Comments
 (0)