What is ChatGPT?
ChatGPT is an Artificial Intelligence(AI) chatbot launched by OpenAI. It is built on top of OpenAI’s GPT-3.
You can try ChatGPT on https://chat.openai.com/chat
When I asked "what is ChatGPT" on chat, I got the below answer
Hello! I am ChatGPT, a large language model developed by OpenAI based on the GPT (Generative Pre-trained Transformer) architecture. I am designed to generate human-like text based on the input I receive from users. I have been trained on a massive amount of text data from the internet and other sources, which enables me to understand and respond to a wide range of topics and questions. You can think of me as a conversational AI that is capable of engaging in natural language conversations with humans.
Create API token
Complete the sign-up at https://openai.com/product
After signing up, you will get a free trial for $18.
Under API key, click "Create new secret key". Copy the key and store it.
Tech Stack
- Visual Studio 2022
- .NET 7
- Blazor Server
Setup application
1. Under Visual Studio, "Create a new project". It will show the available project templates, and we can choose the "Blazor Server App" template.
2. Add a configuration section for OpenAI in the "appsettings.json" file. Replace the ApiKey value with your own created secret key.
{
"OpenAISettings": {
"ApiKey": "Your secret API key goes here"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
3. Add OpenAI-DotNet NuGet package
Add usings for OpenAI-DotNet in the "_imports.razor" file.
@using OpenAI;
@using OpenAI.Chat;
@using OpenAI.Models;
@using OpenAI.Images;
@inject IConfiguration _configuration
@inject IJSRuntime _jsRuntime
3-a. Under the "Pages" folder, add a new Razor Component, "ChatGPT.razor"
Like the traditional razor views in classic MVC application, we can add client-side and server-side logic inside the razor component
@page "/chatgpt"
<PageTitle>ChatGPT</PageTitle>
<style>
.assistant, .user {
position: relative;
font-family: arial;
font-size: 1.1em;
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
}
.assistant:after, .user:after {
content: '';
border: 20px solid transparent;
position: absolute;
margin-top: -30px;
}
.user {
background: #0B93F6;
color: white;
margin-left: 20%;
margin-right: 100px;
top: 30%;
text-align: right;
font-weight: bold;
}
.assistant {
background: #4CAF50;
color: white;
margin-left: 100px;
margin-right: 20%;
font-weight: bold;
}
.msg {
font-size: small;
}
</style>
<p style="font-size:small"><b>Total used tokens:</b> @TotalTokens</p>
<br />
<div id="chatcontainer" style="height:350px; width:100%; overflow: scroll;">
@foreach (var item in messages)
{
<div>
@if (item.Role == "user")
{
<div style="float: right; margin-right: 20px; margin-top: 10px">
<b>User</b>
</div>
<div class="@item.Role">
<div class="msg">
@item.Prompt
</div>
</div>
}
else
{
<div style="float: left; margin-left: 20px; margin-top: 10px">
<b>ChatGPT </b>
</div>
<div class="@item.Role">
<div class="msg">
@if (item.Prompt != null)
{
@((MarkupString)item.Prompt)
}
</div>
</div>
}
</div>
}
@if (_isLoading)
{
<div class="d-flex justify-content-center">
<div class="spinner-border" role="status">
</div>
</div>
}
</div>
<br />
<div class="row">
<div class="col-sm-8">
<input type="text"
class="form-control"
placeholder="Ask me Anything..."
@bind="prompt" />
</div>
<div class="col-sm-4">
<button class="btn btn-success"
@onclick="StartChatGPTService">
Ask Me !
</button>
<button class="btn btn-danger"
@onclick="Clear">
Clear
</button>
</div>
</div>
<p style="color:red">@ErrorMessage</p>
@code {
string ApiKey = string.Empty;
string ErrorMessage = string.Empty;
string prompt = string.Empty;
bool _isLoading = false;
int TotalTokens = 0;
List < Message > messages = new List < Message > ();
protected override void OnInitialized() {
ApiKey = _configuration["OpenAISettings:ApiKey"] ?? "";
}
protected override async Task OnAfterRenderAsync(bool firstRender) {
await _jsRuntime.InvokeAsync < string > ("ScrollToBottom", "chatcontainer");
}
public async Task StartChatGPTService() {
try {
StateHasChanged();
ErrorMessage = string.Empty;
_isLoading = true;
var _openAIClient = new OpenAIClient(new OpenAIAuthentication(ApiKey));
var chatPromptList = new List < ChatPrompt > ();
foreach(var item in messages) {
chatPromptList.Add(new ChatPrompt(item.Role, item.Prompt));
}
chatPromptList.Add(new ChatPrompt("user", prompt));
var chatRequest = new ChatRequest(chatPromptList);
var result = await _openAIClient.ChatEndpoint.GetCompletionAsync(chatRequest);
messages.Add(new Message {
Prompt = prompt,
Role = "user",
Tokens = result.Usage.PromptTokens
});
messages.Add(new Message {
Prompt = result.FirstChoice.Message,
Role = "assistant",
Tokens = result.Usage.CompletionTokens
});
TotalTokens = TotalTokens + result.Usage.TotalTokens;
} catch (Exception ex) {
ErrorMessage = ex.Message;
} finally {
prompt = string.Empty;
_isLoading = false;
StateHasChanged();
}
}
void Clear() {
messages = new List < Message > ();
TotalTokens = 0;
ErrorMessage = string.Empty;
StateHasChanged();
}
public class Message {
public string ? Prompt {
get;
set;
}
public string ? Role {
get;
set;
}
public int Tokens {
get;
set;
}
}
}
Run the application and click the menu ChatGPT.
3-b. Under the "Pages" folder, add a new Razor Component, "ImageGenerator.razor"
@page "/imagegenerator" <PageTitle>Image Generator</PageTitle>
<h2 style="text-align:center">
<b>Model - DALL-E</b>
</h2>
<br />
<h5>
<b>Given a prompt, the model will return a generated image or images.</b>
</h5>
<div class="row">
<div class="col-sm-10">
<input type="text" class="form-control" placeholder="Give me a clue..." @bind="prompt" />
</div>
<div class="col-sm-2">
<button class="btn btn-success" @onclick="StartImageGeneratorService"> Generate </button>
</div>
</div>
<br />
@if (_isLoading)
{
<div class="d-flex justify-content-center">
<div class="spinner-border" role="status">
</div>
</div>
}
else
{
<p>@((MarkupString)GeneratedImage)</p>
}
<p style="color:red">@ErrorMessage</p>
@code {
string ApiKey = string.Empty;
string ErrorMessage = string.Empty;
string prompt = string.Empty;
string GeneratedImage = string.Empty;
bool _isLoading = false;
protected override void OnInitialized() {
ApiKey = _configuration["OpenAISettings:ApiKey"] ?? "";
}
public async Task StartImageGeneratorService() {
try {
StateHasChanged();
ErrorMessage = string.Empty;
GeneratedImage = string.Empty;
_isLoading = true;
var _openAIClient = new OpenAIClient(new OpenAIAuthentication(ApiKey));
var imageResult = await _openAIClient.ImagesEndPoint.GenerateImageAsync(prompt, 3, ImageSize.Small);
foreach(var image in imageResult) {
GeneratedImage += $ @ "<img src='{image}'/> ";
}
} catch (Exception ex) {
ErrorMessage = ex.Message;
} finally {
_isLoading = false;
StateHasChanged();
}
}
}
Run the application and click the menu Image Generator.
We successfully created a Blazor Server OpenAi demo application.
Live preview : https://openai-chatgpt-blazor.herokuapp.com/
The source code for this tutorial is available on GitHub.
Some piece of code was inspired from https://blazorhelpwebsite.com/ by Michael Washington.
Did you catch something I did wrong, or can you improve my implementation? Let me know in the comments!
Happy Documenting!