Building a Django-based AI Chatbot (similar to ChatGPT)

Building a Django-based AI Chatbot (similar to ChatGPT)

·

9 min read

        }     _  _                                    _ 
  __| |(_)__ _ _ _  __ _ ___   _ __ _ _ ___ (_)___ __| |_ 
 / _` || / _` | ' \/ _` / _ \ | '_ \ '_/ _ \| / -_) _|  _|
 \__,_|/ \__,_|_||_\__, \___/ | .__/_| \___// \___\__|\__|
     |__/          |___/      |_|         |__/

GENERAL INTRODUCTION

→ Introduction

ChatGPT is a powerful language model developed by OpenAI. It is based on the GPT (Generative Pre-trained Transformer) architecture and is trained on a large dataset of text from the internet. ChatGPT is able to generate human-like text and can be used for a variety of natural language processing tasks such as language translation, text summarization, and conversation generation.

In this simple and straight forward tutorial, I will be guiding you on how to create an interactive AI chat app just like ChatGPT.

→ Features

  • User Authentication

  • Artificial Intelligence Chat

  • Storage of chat history

  • Clea194194194194r Chat

  • User Authentication

→ Requirements

I will presume you already have a basic knowledge of Python, Django, HTML, CSS and Bootstrap because these are what we will be using to achieve the task.

Alright, let get started...

GENERAL SETUP

→ Creating virtual environment.

Firstly, we will create a virtual env using the code below.

pip install the Creating virtual environment.virtual environment.

pip install virtualenv

Create and activate the virtual environment below;

virtualenv venv
source vevn/bin/activate

→ Installing necessary packages.

Now, we will install the necessary packages using the command below.

pip install django
pip install requests
pip install openai

→ Django Setup

Next, we will set up our site by creating a new project using the command below.

udjango-admin startproject chatproject .

Then we will create our Django app using the code below.tstarted/introduction/tstarted/introduction/tstarted/introduction/

python manage.py startapp chatappu

Next, Add the newly created chatapp to your project settings (Chatprojects/settings) just like it as been highlighted below.

CREATING THE FUNCTIONALITIES

→ Model, views, forms and URL

Firstly, we will create our model using the code below;

# models.py

from django.db import models
from django.contrib.auth.models import User

class Chat(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    user_input = models.TextField( verbose_name="User Input", null=True)
    ai_response = models.TextField( verbose_name="User Input", null=True)
    timestamp = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = 'Chat'
        verbose_name_plurasignupl = 'Chats'

Here in the model, we have created our Chat mode to store the conversation history with the following fields;

user: This inherited from the User model.

user_input: This is the user query.

ai_response: This will be the AI response.

timestamp: This will store the time of each message input and response.

Next, we will create a new file name forms.py inside and chatapp, the we will create our forms for the Registration

# forms.py

from django import forms
from django.contrib.auth.models import User

class SignUpForm(forms.ModelForm):
    username = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control form-control-lg'}), max_length=30, required=True)
    email = forms.CharField(
        widget=forms.EmailInput(attrs={'class':'form-control form-control-lg'}), max_length=100, required=True)
    password = forms.CharField(
        widget=forms.PasswordInput(attrs={'class':'form-control form-control-lg'}), required=True)

    class Meta:
        model = User
        fields = ['username', 'email', 'password']
        widgets = {
            'password': forms.PasswordInput(),
        }

Next, we will create our views;

# views.py

# Importing neccessary models.
# rendering and redirect
from django.shortcuts import render, redirect
# authentication
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
# Forms
from .forms import SignUpForm 


# Signup view
def signup(request):
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            user = form.save()
            login(request, user)
4.            return redirect('index')
    else:
        form = SignUpForm()
    return render(request, 'signup.html', {'form': form})


# Login View
def signin(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            return redirect('index')
        e# Openai module
import openailse:
            return render(request, 'signin.html', {'error': 'Invalid login credentials'})
    else:
        return render(request, 'signin.html')

# Logout View
def logout_view(request):
    logout(request)
    return redirect('login')

Next, we will create our chat view

We will need to create views to handle the user input, pass it to the OpenAI API, and return the AI's response to the user

# views.py

# Openai module
import openai


# Sending of request and saving it in our model
D
@login_required(redirect_field_name='signin')
def AiChat(request):
    # Form verification
    if request.method == 'POST':
        user_input = request.POST.get('user_input')
        ai_response = generate_response(user_input)
        # Saving both user_input and ai_response in the database
        Chat.objects.create(user=request.user, user_input=user_input, ai_response=ai_response)D

    else:
        # if user did not enter any input nothing should be sent
        user_input = ''
        ai_response # return redirect('chat')# return redirect('chat')= ''
    # Displaying the chat history base on user
    chat_history = Chat.objects.filter(user=request.user)


    context = {
        'user_input': user_input,
        'chatbot_response': ai_response,
        '4.chat_history': chat_history,

    }
    return render(request, 'index.html', context)

# Generating response from openai Library
# Use the OpenAI API to generate a response
openai.api_key = "YOUR_API_KEY"
def generate_response(user_input):

    prompt = (f"User: {userI I _input}"
             )D
    completions = openai.Completion.create(
        engine="text-davinci-002",
        prompt=prompt,
        max_tokens=1024,
        n=1,
        stop=None,
        temperature=0.5,
    )

    message = completions.choices[0].text
    return message.strip()


# Clear chat
def clear_chat(request):
    # clear the 'name' field for all records in the 'MyModel' model
    Chat.objects.all().delete()
    return redirect('index')

This code will use the openai.CompDletion.create() method to generate a response using your stored model and the provided prompt (the user's chat input). The response will be returned in the completions.choices[0].text field and can be rendered back to the user iIn the chat application.

You will need to replace YOUR_API_KEY with your own API key and model engine ID. You can find more information on how to use stored models with the OpenAI API in the API documentation.

→ Creating the urlpatterns

URLS→ We will create a new file called urls.py inside our chatapp

# chatapp/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('signup/', views.signup, name='signup'),
    path('signin/', views.signin, name='login'),
    path('logout/', views.logout_view, name='logout'),
    path('clear_chat/', views.clear_chat, name='clear'),
]URLS

→ Firstly, we will create a new folder in our root directory called templates.→ Now, we will add the newly created urls to our project urls.

from django.contrib import admin
from django.urls import path, include
from chatapp.views import *

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', AiChat, name='index'),

]

TEMPLATES

Our next step is to configure our templates.

Firstly, we will create a new folder in our root directory called templates.

Next, we will configure the newly created templates folder in the settings.py

Firstly, we will create a new folder in our root directory called templates.

Next, we will starts create the three files we will be needing, which are the login page, signup page and index page.

→ Let'Templatess start with the signup page

<!-- Signup.html -->

  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scaleTemplates=1.0">
      <title>Create a new account</title>

      <!-- Font Awesome -->
  <link
  href="htPagetps://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"
  rel=TemplatesTemplates"stylesheet"
  />
  <!-- Google Fonts -->
  <link
  href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
  rel="stylesheet"
  />
  <!-- MDB -->
  <link
  href="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.0.0/mdb.min.css"
  rel="stylesheet"
  />

  </head>
  <bodyTemplates>

  </body>
  </html>
  <section class="vh-100" style="background-color: #0d234d;">
      <div class="container py-5 h-100">
        <div class="row d-flex justify-content-center align-items-center Templatesh-100">
          <div class="col-12 col-md-8 col-lg-6 col-xl-5">
            <div class="card shadow-2-strong" style="border-radius: 1rem;">
              <div class="card-body p-5 text-center">

                <h3 class="mb-5">Sign Up</h3>

        Templates  PagePagePage      <form action="" method="post">
                  {% csrf_token %}
                  <div class="form-outline mb-4">
                    {{ form.username }}
                    <label class="form-label" for="username">Username</label>
                  </div→ >

                  <div class="form-outline mb-4">
                      {{ form.email }}

                    <label class="form-label" for="typeEmailX-2">Email</label>
                  </div>

                  <div class="form-outline mb-4">
                      {{ form.password }}
Templates
                    <label class="form-label" for="typePasswordX-2">Password</label>
                  </div>

                  {% if error %}
          <p style="color:red">{{ error }}</p>
      {%Templates ePagePagePagendif %}


                  <button class="btn btn-primary btn-lg btn-block" type="submit">Register</button><p class="mt-3"> Already have an account? <a href="{% url 'login'%}">Login</a></p>

                </form>

              </div>
            </div>
          </div>
        </div>
      </div>
    </section>

    <!-- MDB -->
  <script
  type="text/javascript"
  src="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.0.0/mdb.min.js"
  ></scripPagePagePaget>→ Sign in Page
    </body>
    </html>

→ Sign in Page

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Create a new account</title>

    <!-- Font Awesome -->
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"
rel="stylesheet"
/>
<!-- Google Fonts -->
<link
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
rel="stylesheet"
/>
<!-- MDB -->
<link
href="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.0.0/mdb.min.css"
rel="stylesheet"
/>

</head>
<body>

</body>
</html>
<section class="vh-100" style="background-color: #0d234d;">
    →Th<div class="container py-5 h-100">
      <div class="row d-flex justify-content-center align-items-center h-100">
        <div class="col-12 col-md-8 col-lg-6 col-xl-5">
          <div class="card shadow-2-strong" style="border-radius: 1rem;">
            <div class="card-body p-5 text-center">

    →Th          <h3 class="mb-5">Sign In</h3>

              <form action="" method="post">
                {% csrf_token %}
                <div class="form-outline mb-4">
                  <input type="text" id="username" name='username' class="form-control form-control-lg" />
                  <label class="form-label" for="username">Username</label>
                </div>



                <div class="form-outline mb-4">
                  <input type="password" id="typePasswordX-2" name='password' class="form-control form-control-lg" />
                  <label class="form-label" for="typePasswordX-2">Password</label>
                </div>




                <button class="btn btn-primary btn-lg btn-block" type="submit">Login</button>
                <p class="mt-3"> Already have an account? <a href="{% url →Th'signup'%}">Signup</a></p>

              </form>

              {% if error %}→ Index Page→ Index Page→ Index Page→ Index Page
        <p style="color:red">{{ error }}</p>
    {% endif %}

            </div>
          </div>
        </div>
      </div>
    </div>
  </section>

  <!-- MDB -->
<script
type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/6.0.0/mdb.min.js"Index PageIndex PageIndex Page
></script>
  </body>
  </html>

→ Index Page

<!doctype html>→Th
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">

    <title>Chat App</title>



  </head>
  <body>



    <br>
      <div class="container">
        <div class="row">
              <div class="col-md-6 mx-auto">
                  <div class="card">
                      <div class="card-header text-center">
                          <span>AI Chat Bot</span>
                      </div>
                      <div class="card-body chat-care">
                          <ul class="chat">

                            <hr>
→Th→Th→Th


        {% for message in chat_history %}
        {% if message.user_input %}
                              <li class="agent clearfix">

                                  <span class="chat-img left clearfix mx-2">
                                      <img src="data:image/png;base64,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→Th→Th→ThhzvqzkFaXQRWo0Z5IwgEztIvEAVm+NUML88V113ycqSmnPn5zXt5N59LjiFbk6ub7AR/m0u1JbmyYS9ccGpuFMJ0wZ+d3M/uA1/sMlOn+8H0GAAuPeb9j/TJbgHjX49cvxFDvwXzbckn8h94RMjAwMDAwMDAwMDAw+DH+AWzxQp1lVVyEAAAAAElFTkSuQmCC" alt="Agent" class="img-circle" />
                                  </span>
                                  <div class="chat-body clearfix">
                                      <div class="header clearfix">
                                          <strong class="primary-font">{{message.user}} </strong> <small class="right text-muted mr-4">
                                              <span class="glyphicon glyphicon-time"></span>{{ message.timestamp|timesince }} ago</small>
                                      </div>
                                      <p>
                                        {{ message.user_input }}
                                      </p>
                                  </div>
                          →Th    </li>

        {% endif %}

                              {% if message.ai_response %}
                              <li class="admin clearfix">
                                  <span class="chat-img right clearfix  mx-2">
                                      <img src="https://cdn-icons-png.flaticon.com/512/1985/1985496.png" alt="Admin" class="img-circle ai_img" />
                                  </span>
                                  <div class="chat-body clearfix">
                                      <div class="header clearfix">
                                          <small class="left text-muted"><span class="glyphicon glyphicon-time"></span>{{ message.timestamp|timesince }} ago</small>
                                          <strong class="right primary-font">AI</strong>
                                      </div>
                                      <p>
                                          {{ message.ai_response }}
                                      </p>
                                  </div>
                              </li>

                              {% endif %}                            

→Th→Th
        {% endfor %}
                          </ul>
                      </div>
                      <div class="card-footer">
                        <form method="post">
                            {% csrf_token %}
                          <div class="input-group">
                              <input id="btn-input" type="text" name="user_input" class="form-control input-sm" placeholder="Type your message here..." />

                              <span class="input-group-btn">

                                  <button class="btn btn-primary" id="btn-chat" type='submit'>
                                      Send</button>
                              </span>
                          →Th</div>
                        </form>
                        <div class="row justify-content-center">
                          <a class="btn btn-info mt-3 mr-2" id="btn-chat" href="{% url 'clear' %}">Clear Chat</a>
                        <a class="btn btn-danger mt-3" id="btn-chat" href="{% url 'logout' %}">
                          Logout </a>
                        </div>
                      </div>
                  </div>
              </div>
          </div>
      </div> 
        <!-- Optional JavaScript -->
        <!-- jQuery first, then Popper.js, then Bootstrap JS -->
        <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.16.0/dist/umd/popper.min.js" integrity="sha384-fA23ZRQ3G/J53mElWqVJEGJzU0sTs+SvzG8fXVWP+kJQ1lwFAOkcUOysnlKJC33U" crossorigin="anonymous"></→Th→Thscript>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
        </body>
        </html>

→ The pages should look like the images below;

CONCLUSION

I hope you’ve found this tutorial useful and have learned how to create an interactive AI chat app just like ChatGPT. Feel free to expand your knowledge by researching more, customizing the platform.

You can get the final code here194

I look forward to seeing the projects you create using this tutorial. If you don't mind, please share them with me and let me know your thoughts about the tutorial in the comments section or in the Tech Titans Community on WhatsApp. Your input and experiences are valuable to me and the community!