{"id":21647406,"url":"https://github.com/fitomad/openai-dotnet","last_synced_at":"2026-04-12T20:42:52.636Z","repository":{"id":211746886,"uuid":"729865237","full_name":"fitomad/openai-dotnet","owner":"fitomad","description":"OpenAI .NET library written in C# for GTP and Dall-E models.","archived":false,"fork":false,"pushed_at":"2024-05-14T09:13:40.000Z","size":100,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-25T05:09:29.860Z","etag":null,"topics":["chatgpt","csharp","dall-e-3","dalle-2","dotnet","openai"],"latest_commit_sha":null,"homepage":"https://www.nuget.org/packages/Fitomad.OpenAI/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fitomad.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":"fitomad","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2023-12-10T15:42:45.000Z","updated_at":"2024-05-21T13:26:46.000Z","dependencies_parsed_at":"2024-12-06T19:56:39.330Z","dependency_job_id":"2d5c1907-a0e7-46ce-8302-d3dff0b1fe8a","html_url":"https://github.com/fitomad/openai-dotnet","commit_stats":null,"previous_names":["fitomad/openai-dotnet"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fitomad%2Fopenai-dotnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fitomad%2Fopenai-dotnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fitomad%2Fopenai-dotnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fitomad%2Fopenai-dotnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fitomad","download_url":"https://codeload.github.com/fitomad/openai-dotnet/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244531013,"owners_count":20467391,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chatgpt","csharp","dall-e-3","dalle-2","dotnet","openai"],"created_at":"2024-11-25T06:49:48.433Z","updated_at":"2026-04-12T20:42:47.591Z","avatar_url":"https://github.com/fitomad.png","language":"C#","funding_links":["https://ko-fi.com/fitomad"],"categories":[],"sub_categories":[],"readme":"# OpenAI .NET library\n\nFitomad.OpenAI is a **community-maintained .NET library** that allows you to access the powerful AI models from OpenAI, such as GPT, DALL-E, and Whisper, through a simple and intuitive interface. You can use this framework to generate text, code, images, audio, and more, with just a few lines of code. \n\nFitomad.OpenAI provides various options to customize your requests and responses. Whether you want to create a chatbot, a content generator, a sentiment analyzer, a translator, or any other AI-powered application, Fitomad.OpenAI can help you achieve your goals with ease and efficiency.\n\nThe framework makes a heavy usage of the [Builder pattern](https://en.wikipedia.org/wiki/Builder_pattern) to create requests and settings objects.\n\nCurrently I bring support for the following OpenAI models:\n\n- Chat Completion\n    - Text\n    - Image explanation\n- Image\n- Audio\n    - Create speech\n    - Translation\n    - Transcription\n- Moderation\n- Models\n\n## OpenAI API key storage recommendations\n\nAPI key is a sensitive information part that must be keep safe during your development and deployment process.\n\nI strongly recommend **the usage of environment variables** when you deploy your solition to store your OpenAI API key.\n\nDuring the development stage you could use user-secrets technology to store the API key.\n\n### User secrets\n\nThis is the recommended storage system for development. For a detailed information about the usage of this storage system, please refer to [Safe storage of app secrets in development in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-8.0\u0026tabs=linux) article.\n\n```cs\nvar configuration = new ConfigurationBuilder()\n    .AddUserSecrets\u003cImageTests \u003e()\n    .Build();\n\n_apiKey = configuration.GetValue\u003cstring\u003e(\"OpenAI:ApiKey\");\n```\n\n### Environment variables\n\nEnvironment variables are used to avoid storage of app secrets in code or in local configuration files. Environment variables override configuration values for all previously specified configuration sources.\n\n```cs\nusing Fitomad.OpenAI;\n\n...\n\nvar openAISettings = new OpenAISettingsBuilder()\n    .WithApWithApiKeyFromEnvironmentVariableiKey(\"OpenAI:ApiKey\")\n    .Build();\n```\n\n## Dependency Injection. Create an `OpenAIClient` instance\n\nTo create a `OpenAIClient` instance, the entry point to the whole Fitomad.OpenAI framework, developers must use DI.\n\nI provide a helper method registered as an `IServiceCollection` extension named `AddOpenAIHttpClient` which receives an `OpenAISettings` object as parameter.\n\nThis is an example of DI in an Unit Testing (xunit) environment.\n\n```cs\nvar aiSettings = new OpenAISettingsBuilder()\n    .WithApiKey(_apiKey)\n    .Build();\n\nvar services = new ServiceCollection();\nservices.AddOpenAIHttpClient(settings: aiSettings);\n```\n\nBelow this lines you will find an example of the usage of DI in ASP.NET\n\n```cs\nusing Fitomad.OpenAI;\n\n...\n\nvar developApiKey = builder.Configuration[\"OpenAI:ApiKey\"];\n\nvar openAISettings = new OpenAISettingsBuilder()\n    .WithApiKey(developApiKey)\n    .Build();\n\nbuilder.Services.AddOpenAIHttpClient(settings: openAISettings);\n```\n\nAnd now, thanks to the built-on DI container available in .NET we can use the `OpenAIClient` registered type \n\n```cs\n...\n\n[ApiController]\n[Route(\"games\")]\npublic class GameController: ControllerBase\n{\n    private IOpenAIClient _openAIClient;\n\n    public GameController(IOpenAIClient openAIClient)\n    {\n        _openAIClient = openAIClient;\n    }\n\n    ...\n}\n```\n\n## Chat Completion\n\nMaybe, the best known endpoint available in the API, Fitomad.OpenAI framework allows developers to invoke to different operations\n\n- Chats\n- Image content explanation\n\n### Chat\n\nHere's an example of a chat completion where developer set de *mood* to shool teacher and ask about what is and star (in Spanish 🇪🇸😜)\n```cs\nusing Fitomad.OpenAI;\nusing Fitomad.OpenAI.Entities.Chat;\nusing Fitomad.OpenAI.Endpoints.Chat;\n\nChatRequest request = new ChatRequestBuilder()\n    .WithModel(ChatModelType.GPT_3_5_TURBO)\n    .WithSystemMessage(\"Eres un profesor de alumnos de 10 años.\")\n    .WithUserMessage(\"Explícame qué es una estrella.\")\n    .WithTemperatute(Temperature.Precise)\n    .WithReponseFormat(ChatResponseFormat.Text)\n    .Build();\n\nChatResponse chatResponse = await client.ChatCompletion.CreateChatAsync(request);\n```\nThe GPT model answer is available in the `Choices` property, that is a `Choice type` that stores the messages in the property `ReceivedMessage`, a `Message` record type.\n\n### Image Explanation\n\nNo need of builder object to create the request, simply pass the image url and user question to method and done!.\n\n```cs\nvar imageUrl = \"https://upload.wikimedia.org/wikipedia/commons/a/ae/Vel%C3%A1zquez_-_La_Fragua_de_Vulcano_%28Museo_del_Prado%2C_1630%29.jpg\"; \nvar question = \"¿Qué cuadro es este?\";\n\nvar imageExplanationResponse = await _client.ChatCompletion.ExplainImageAsync(imageUrl, userQuestion: question);\n```\n\nIn the example above I ask GTP to exaplain the image \"La Fragua de Vulcano\" by Diego de Velázquez available in the Museo Nacional del Prado.\n\nThe response from GTP model must be treated in the same way as I describe in the *Chat* section.\n\n## Image\n\n```cs\nImageRequest request = new ImageRequestBuilder()\n    .WithModel(ImageModelKind.DALL_E_3)\n    .WithPrompt(\"Un paisaje urbano, con algunos rascacielos de fondo aplicando el estilo de Dalí.\")\n    .WithImagesCount(1)\n    .WithSize(DallE3Size.Square)\n    .WithQuality(DallE3Quality.HD)\n    .WithStyle(DallE3Style.Vivid)\n    .WithResponseFormat(ImageResponseFormat.Url)\n    .Build();\n\nImageResponse imageResponse = await client.Image.CreateImageAsync(request);\n```\n\nThe images created by DALL-E are available in the `Images` property of the `ImageResponse` record. The `Images` is an array of `ImageUrl`.\n\n## Audio\n\nSupport the *create speech*, *translation* and *transcription* operations.\n\n### Speech\n\n```cs\nprivate const string ElQuijote = \"En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga antigua, rocín flaco y galgo corredor. Una olla de algo más vaca que carnero, salpicón las más noches, duelos y quebrantos los sábados, lantejas los viernes, algún palomino de añadidura los domingos, consumían las tres partes de su hacienda.\";\n\nSpeechRequest request = new SpeechRequestBuilder()\n    .WithModel(SpeechModelType.TTS_1)\n    .WithVoice(VoiceType.Onyx)\n    .WithResponseFormat(SpeechResponseFormat.MP3)\n    .WithInput(ElQuijote)\n    .Build();\n\nSpeechResponse response = await _client.Audio.CreateSpeech(request);\n```\n\n### Transcription\n\n```cs\nTranscriptionRequest request = new TranscriptionRequestBuilder()\n    .WithModel(TranscriptionModelType.Whisper1)\n    .WithResponseFormat(TranscriptionResponseFormat.Json)\n    .WithFile(\"/path/to/audio-file.mp3\")\n    .Build();\n\nTranscriptionResponse response = await _client.Audio.CreateTranscription(request);\n```\n\nThe transcription will be stored in the `Text` property in the `TranscriptionResponse`.\n\n### Translation\n\n```cs\nTranslationRequest request = new TranslationRequestBuilder()\n    .WithModel(TranslationModelType.Whisper1)\n    .WithResponseFormat(TranslationResponseFormat.Json)\n    .WithFile(\"/path/to/audio-file.mp3\")\n    .Build();\n\nTranslationResponse response = await _client.Audio.CreateTranslation(request);\n```\n\nThe translation will be stored in the `Text` property in the `TranslationResponse`.\n\n## Moderation\n\nAs OpenAI said, moderation represents policy compliance report by OpenAI's content moderation model against a given input.\n\n```cs\nconst string ElBuscon = \"Yo, señora, soy de Segovia. Mi padre se llamó Clemente Pablo, natural del mismo pueblo; Dios le tenga en el cielo. Fue, tal como todos dicen, de oficio barbero, aunque eran tan altos sus pensamientos que se corría de que le llamasen así, diciendo que él era tundidor de mejillas y sastre de barbas.\";\n\nvar moderationRequest = new ModerationRequestBuilder()\n    .WitnInput(ElBuscon)\n    .WithModel(ModerationModelType.TextModerationLatest)\n    .Build();\n\nModerationResponse response = await _client.Moderation.CreateModeration(moderationRequest);\n```\n\nYou will check the results thanks two different properties named `Values` and `Scores`.\n\nThe `Values` property is a data structure with boolean properties that indicates if the text is *positive* in some of the moderated categories.\n\nThe `Scores` property is a data structure like `Values` but instead of booleand presents `double` properties that show the *score* in each moderated category for the given text.\n\n## Models\n\nFetch a list of models available in the API. Fitomad.OpenAI framework bring support for *list*, *retreive* and *delete* operations.\n\nThis is one of the most simple endpoints, and you will not need a builder object to create a request, simply invoke the methods presented in the `ModelEndpoint` class.\n\nList operation \n\n```cs\nModelListResponse response = await _client.Models.List();\n```\n\nRetrieve a given model.\n\n```cs\nModelResponse response = await _client.Models.Retrieve(model: modelName);\n```\n\nDelete a model.\n\n```cs\nModelDeletedResponse response = await _client.Models.Delete(model: modelName);\n```\n\n## Changes\n\n### 1.0.2\n\n- Chat endpoint models brings support the following:\n    - `gpt-4o` 🚀\n    - `gpt-4-turbo`\n    - `gpt-4-turbo-2024-04-09`\n    - `gpt-4-turbo-preview`\n\n### 0.2.1\n\n- New package icon 🎉\n- Namespace `Fitomad.OpenAI.Models` now is `Fitomad.OpenAI.Endpoints`\n- Enumeration `TemperatureKind` now is `Temperature` and has been moved to `Fitomad.OpenAI.Endpoints` namespace.\n- Enumeration `ImageModelKind` now is `ImageModelType`\n- Enumeration `ChatModelKind` now is `ChatModelType`\n- Method `AddOpenAIHttpClient` is now in `Fitomad.OpenAI` namespace.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffitomad%2Fopenai-dotnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffitomad%2Fopenai-dotnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffitomad%2Fopenai-dotnet/lists"}