Skip to content

Commit

Permalink
Added embeding endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
metjuperry committed Dec 5, 2022
1 parent 49f24f3 commit 9e9fe47
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 54 deletions.
65 changes: 65 additions & 0 deletions OpenAI_API/Embedding/EmbeddingEndpoint.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Authentication;
using System.Text;
using System.Threading.Tasks;

namespace OpenAI_API.Embedding
{
public class EmbeddingEndpoint
{
OpenAIAPI Api;
/// <summary>
/// This allows you to set default parameters for every request, for example to set a default temperature or max tokens. For every request, if you do not have a parameter set on the request but do have it set here as a default, the request will automatically pick up the default value.
/// </summary>
public EmbeddingRequest DefaultCompletionRequestArgs { get; set; } = new EmbeddingRequest();

/// <summary>
/// Constructor of the api endpoint. Rather than instantiating this yourself, access it through an instance of <see cref="OpenAIAPI"/> as <see cref="OpenAIAPI.Completions"/>.
/// </summary>
/// <param name="api"></param>
internal EmbeddingEndpoint(OpenAIAPI api)
{
this.Api = api;
}

public async Task<EmbeddingResult> CreateEmbeddingAsync(string input)
{
return await CreateEmbeddingAsync(new EmbeddingRequest() { input = input });
}

public async Task<EmbeddingResult> CreateEmbeddingAsync(EmbeddingRequest request)
{
if (Api.Auth?.ApiKey is null)
{
throw new AuthenticationException("You must provide API authentication. Please refer to https://github.com/OkGoDoIt/OpenAI-API-dotnet#authentication for details.");
}

request.Model = Api.UsingEngine;

HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Api.Auth.ApiKey);
client.DefaultRequestHeaders.Add("User-Agent", "okgodoit/dotnet_openai_api");

string jsonContent = JsonConvert.SerializeObject(request, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
var stringContent = new StringContent(jsonContent, UnicodeEncoding.UTF8, "application/json");

var response = await client.PostAsync($"https://api.openai.com/v1/embeddings", stringContent);
if (response.IsSuccessStatusCode)
{
string resultAsString = await response.Content.ReadAsStringAsync();

var res = JsonConvert.DeserializeObject<EmbeddingResult>(resultAsString);

return res;
}
else
{
throw new HttpRequestException("Error calling OpenAi API to get completion. HTTP status code: " + response.StatusCode.ToString() + ". Request body: " + jsonContent);
}
}

}
}
25 changes: 25 additions & 0 deletions OpenAI_API/Embedding/EmbeddingRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;

namespace OpenAI_API.Embedding
{
public class EmbeddingRequest
{
/// <summary>
/// ID of the model to use. You can use the List models API to see all of your available models, or see our Model overview for descriptions of them.
/// </summary>
[JsonIgnore]
public Engine Model { get; set; }

[JsonProperty("model")]
public string ModelName { get => Model.EngineName; }

/// <summary>
/// The suffix that comes after a completion of inserted text.
/// </summary>
[JsonProperty("input")]
public string input { get; set; }
}
}
43 changes: 43 additions & 0 deletions OpenAI_API/Embedding/EmbeddingResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;

namespace OpenAI_API.Embedding
{
public class EmbeddingResult
{
[JsonProperty("object")]

public string Object { get; set; }

[JsonProperty("data")]
public Data[] Data { get; set; }

}

public class Data
{
[JsonProperty("object")]

public string Object { get; set; }

[JsonProperty("embedding")]
public float[] Embedding { get; set; }

[JsonProperty("index")]
public int Index { get; set; }

}

public class Usage
{
[JsonProperty("prompt_tokens")]
public int PromptTokens { get; set; }

[JsonProperty("total_tokens")]
public int TotalTokens { get; set; }

}

}
2 changes: 1 addition & 1 deletion OpenAI_API/Engine/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public Engine()
/// <summary>
/// Most capable GPT-3 model. Can do any task the other models can do, often with less context. In addition to responding to prompts, also supports inserting completions within text.
/// </summary>
public static Engine Davinci => new Engine("text-davinci-002") { Owner = "openai", Ready = true };
public static Engine Davinci => new Engine("text-davinci-003") { Owner = "openai", Ready = true };

/// <summary>
/// The default Engine to use in the case no other is specified. Defaults to <see cref="Davinci"/>
Expand Down
101 changes: 52 additions & 49 deletions OpenAI_API/OpenAIAPI.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Newtonsoft.Json;
using OpenAI_API.Embedding;
using System;
using System.Collections.Generic;
using System.IO;
Expand All @@ -9,53 +10,55 @@

namespace OpenAI_API
{
/// <summary>
/// Entry point to the OpenAPI API, handling auth and allowing access to the various API endpoints
/// </summary>
public class OpenAIAPI
{
/// <summary>
/// The API authentication information to use for API calls
/// </summary>
public APIAuthentication Auth { get; set; }

/// <summary>
/// Specifies which <see cref="Engine"/>/model to use for API calls
/// </summary>
public Engine UsingEngine { get; set; } = Engine.Default;

/// <summary>
/// Creates a new entry point to the OpenAPI API, handling auth and allowing access to the various API endpoints
/// </summary>
/// <param name="apiKeys">The API authentication information to use for API calls, or <see langword="null"/> to attempt to use the <see cref="APIAuthentication.Default"/>, potentially loading from environment vars or from a config file.</param>
/// <param name="engine">The <see cref="Engine"/>/model to use for API calls, defaulting to <see cref="Engine.Davinci"/> if not specified.</param>
public OpenAIAPI(APIAuthentication apiKeys = null, Engine engine = null)
{
this.Auth = apiKeys.ThisOrDefault();
this.UsingEngine = engine ?? Engine.Default;
Completions = new CompletionEndpoint(this);
Engines = new EnginesEndpoint(this);
Search = new SearchEndpoint(this);
}

/// <summary>
/// Text generation is the core function of the API. You give the API a prompt, and it generates a completion. The way you “program” the API to do a task is by simply describing the task in plain english or providing a few written examples. This simple approach works for a wide range of use cases, including summarization, translation, grammar correction, question answering, chatbots, composing emails, and much more (see the prompt library for inspiration).
/// </summary>
public CompletionEndpoint Completions { get; }

/// <summary>
/// The API endpoint for querying available Engines/models
/// </summary>
public EnginesEndpoint Engines { get; }

/// <summary>
/// The API lets you do semantic search over documents. This means that you can provide a query, such as a natural language question or a statement, and find documents that answer the question or are semantically related to the statement. The “documents” can be words, sentences, paragraphs or even longer documents. For example, if you provide documents "White House", "hospital", "school" and query "the president", you’ll get a different similarity score for each document. The higher the similarity score, the more semantically similar the document is to the query (in this example, “White House” will be most similar to “the president”).
/// </summary>
public SearchEndpoint Search { get; }





}
/// <summary>
/// Entry point to the OpenAPI API, handling auth and allowing access to the various API endpoints
/// </summary>
public class OpenAIAPI
{
/// <summary>
/// The API authentication information to use for API calls
/// </summary>
public APIAuthentication Auth { get; set; }

/// <summary>
/// Specifies which <see cref="Engine"/>/model to use for API calls
/// </summary>
public Engine UsingEngine { get; set; } = Engine.Default;

/// <summary>
/// Creates a new entry point to the OpenAPI API, handling auth and allowing access to the various API endpoints
/// </summary>
/// <param name="apiKeys">The API authentication information to use for API calls, or <see langword="null"/> to attempt to use the <see cref="APIAuthentication.Default"/>, potentially loading from environment vars or from a config file.</param>
/// <param name="engine">The <see cref="Engine"/>/model to use for API calls, defaulting to <see cref="Engine.Davinci"/> if not specified.</param>
public OpenAIAPI(APIAuthentication apiKeys = null, Engine engine = null)
{
this.Auth = apiKeys.ThisOrDefault();
this.UsingEngine = engine ?? Engine.Default;
Completions = new CompletionEndpoint(this);
Engines = new EnginesEndpoint(this);
Search = new SearchEndpoint(this);
Embeddings = new EmbeddingEndpoint(this);

}

/// <summary>
/// Text generation is the core function of the API. You give the API a prompt, and it generates a completion. The way you “program” the API to do a task is by simply describing the task in plain english or providing a few written examples. This simple approach works for a wide range of use cases, including summarization, translation, grammar correction, question answering, chatbots, composing emails, and much more (see the prompt library for inspiration).
/// </summary>
public CompletionEndpoint Completions { get; }

/// <summary>
/// The API endpoint for querying available Engines/models
/// </summary>
public EnginesEndpoint Engines { get; }

/// <summary>
/// The API lets you do semantic search over documents. This means that you can provide a query, such as a natural language question or a statement, and find documents that answer the question or are semantically related to the statement. The “documents” can be words, sentences, paragraphs or even longer documents. For example, if you provide documents "White House", "hospital", "school" and query "the president", you’ll get a different similarity score for each document. The higher the similarity score, the more semantically similar the document is to the query (in this example, “White House” will be most similar to “the president”).
/// </summary>
public SearchEndpoint Search { get; }

public EmbeddingEndpoint Embeddings { get; }



}
}
8 changes: 4 additions & 4 deletions OpenAI_API/OpenAI_API.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
Expand All @@ -18,9 +18,9 @@
<AssemblyOriginatorKeyFile>okgodoit-signing.pfx</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
<PackageId>OpenAI</PackageId>
<Version>1.2.0</Version>
<AssemblyVersion>1.2.0.0</AssemblyVersion>
<FileVersion>1.2.0.0</FileVersion>
<Version>1.2.2</Version>
<AssemblyVersion>1.2.2.0</AssemblyVersion>
<FileVersion>1.2.2.0</FileVersion>
</PropertyGroup>

<ItemGroup>
Expand Down

0 comments on commit 9e9fe47

Please sign in to comment.