DEV Community

Yixin Cao
Yixin Cao

Posted on

Building a Web Application with Flask, OpenAI, and Python

This process is fully powered by ChatGPT 3.5. Not tested.

In this tutorial, we'll be building a web application that crawls data from a website, generates text embeddings using OpenAI's API, and answers questions related to OpenAI using the DaVinci model. We'll be using Flask, a popular Python web framework, to build the application.

Prerequisites

Before we get started, make sure you have the following installed:

  • Python 3.x
  • Flask
  • Requests
  • Beautiful Soup
  • OpenAI API Key

You can install Flask and other Python dependencies using pip:

pip install flask requests beautifulsoup4 openai
Enter fullscreen mode Exit fullscreen mode

To get started with the OpenAI API, you'll need to sign up for an API key on their website. Once you have your API key, make sure to keep it safe and don't share it with anyone.

Crawling Data

The first step in building our web application is to crawl data from a website. We'll be using Python's requests and BeautifulSoup libraries to accomplish this.

Here's an example of a Python script that crawls data from a given URL and extracts the title and body of the page:

# import the necessary libraries
import requests
from bs4 import BeautifulSoup

# define a function to crawl data from a URL
def crawl_data(url):
    # retrieve HTML data from the URL
    response = requests.get(url)
    html = response.text

    # use BeautifulSoup to extract data from HTML
    soup = BeautifulSoup(html, 'html.parser')
    title = soup.title.string
    body = soup.body.text.strip()

    # return the extracted data
    return {
        'title': title,
        'body': body
    }
Enter fullscreen mode Exit fullscreen mode

You can customize this function to crawl data from any website of your choice. Just pass the URL of the website to the crawl_data function and it will return a dictionary containing the extracted data.

Embedding Data

The next step is to generate text embeddings using OpenAI's API. Text embeddings are vector representations of text that capture the meaning and context of the text.

To generate text embeddings using OpenAI's API, we'll be using their text_embeddings endpoint. Here's an example of a Python script that generates text embeddings for a given piece of text:

# import the necessary libraries
import openai

# set up the OpenAI API client
openai.api_key = 'YOUR_API_KEY'

# define a function to generate text embeddings
def generate_embeddings(text):
    # generate text embeddings using OpenAI's API
    response = openai.Embedding.create(
        engine='text-davinci-002',
        input=text,
    )

    # return the embeddings as a list of floats
    embeddings = response['embedding']
    return list(map(float, embeddings))
Enter fullscreen mode Exit fullscreen mode

Make sure to replace YOUR_API_KEY with your actual OpenAI API key.

You can use the generate_embeddings function to generate embeddings for the crawled data and save the embeddings to a CSV file for future use.

Flask Web Application

The final step is to build the Flask web application. We'll be using Flask to handle user input, display the UI, and handle the logic of generating text embeddings and answering questions using the DaVinci model.

Here's an example of a Python script that sets up a basic Flask app:

# import the necessary libraries
from flask import Flask, render_template, request
import csv
import os

# set up the Flask app
app = Flask(__name__)

# define a route for the home page
@app.route('/')
def home():
    return render_template('index.html')

# define a route for processing user input
@app.route('/process', methods=['POST'])
def process():
    # get the user input from the form
    user_input = request.form['question']

    # generate embeddings for the user input
    embeddings = generate_embeddings(user_input)

    # load the embeddings for the crawled data from a CSV file
    data_embeddings = []
    with open('data_embeddings.csv', 'r') as f:
        reader = csv.reader(f)
        for row in reader:
            data_embeddings.append(list(map(float, row)))

    # compute the similarity between the user input embeddings and the data embeddings
    similarities = []
    for data_embedding in data_embeddings:
        similarity = cosine_similarity(embeddings, data_embedding)
        similarities.append(similarity)

    # find the index of the most similar data embedding
    max_index = similarities.index(max(similarities))

    # load the crawled data from a CSV file
    data = []
    with open('data.csv', 'r') as f:
        reader = csv.reader(f)
        for row in reader:
            data.append({
                'title': row[0],
                'body': row[1]
            })

    # generate a response using the DaVinci model
    response = openai.Completion.create(
        engine='text-davinci-002',
        prompt=data[max_index]['body'] + '\nQuestion: ' + user_input,
        max_tokens=1024,
        n=1,
        stop=None,
        temperature=0.5,
    )

    # extract the answer from the response
    answer = response.choices[0].text.strip()

    # render the answer template with the answer
    return render_template('answer.html', answer=answer)

Enter fullscreen mode Exit fullscreen mode

This script defines two routes: the home page and the route for processing user input. The home function simply renders the index.html template, which contains a form for the user to enter their question. The process function is called when the user submits the form, and it generates embeddings for the user input, computes the similarity between the user input embeddings and the data embeddings, loads the crawled data from a CSV file, generates a response using the DaVinci model, and renders the answer.html template with the answer.

HTML and CSS Templates

To complete our web application, we need to define the HTML and CSS templates for the UI. Here's an example of the index.html template:

<!DOCTYPE html>
<html>
<head>
    <title>OpenAI Web App</title>
    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <div class="container">
        <h1>Ask a Question about OpenAI</h1>
        <form action="{{ url_for('process') }}" method="POST">
            <label for="question">Question:</label>
            <input type="text" id="question" name="question" required>
            <input type="submit" value="Ask">
        </form>
    </div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

And here's an example of the answer.html template:

<!DOCTYPE html>
<html>
<head>
    <title>OpenAI Web App</title>
    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <div class="container">
        <h1>OpenAI Web App</h1>
        <h2>Question:</h2>
        <p>{{ question }}</p>
        <h2>Answer:</h2>
        <p>{{ answer }}</p>
    </div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

CSS Styles

Finally, we need to define some CSS styles to make our web app look nice. Here's an example of the style.css file:

body {
    font-family: Arial, sans-serif;
    background-color: #f1f1f1;
}

.container {
    width: 80%;
    margin: 0 auto;
    padding-top: 50px;
}

h1 {
    text-align: center;
    color: #333;
}

form {
    margin-top: 20px;
    text-align: center;
}

label {
    display: block;
    margin-bottom: 10px;
    color: #333;
}

input[type="text"] {
    padding: 10px;
    border-radius: 5px;
    border: none;
    width: 60%;
    margin-bottom: 10px;
}

input[type="submit"] {
    padding: 10px;
    background-color: #333;
    color: #fff;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}

.answer {
    margin-top: 20px;
    padding: 20px;
    background-color: #fff;
    border-radius: 5px;
    box-shadow: 0 0 10px rgba(0,0,0,0.2);
}

.answer h2 {
    color: #333;
    margin-bottom: 20px;
}

.answer p {
    color: #333;
    font-size: 18px;
    line-height: 1.5;
}
Enter fullscreen mode Exit fullscreen mode

This file defines styles for the body, container, headings, forms, labels, input fields, and answer section.

Conclusion

In this tutorial, we have built a Flask web application that crawls data from the OpenAI website, generates embeddings for the data using the OpenAI text-embedding engine, and uses the OpenAI text-DaVinci model to answer questions generated by the user. We have also included the code and templates for the web app, as well as CSS styles to make it look nice. This application can be easily extended to crawl and answer questions from other websites as well, making it a useful tool for various natural language processing tasks.

Top comments (0)