Linguistic Email Composer Web Application Using OpenAI and Langchain

Edula Vinay Kumar Reddy 11 Aug, 2023 • 11 min read

Introduction

In this article, we will see how to build a web application using OpenAI with the help of Langchain. This web app allows users to convert unstructured emails into properly formatted English. Users can input their email text, specify the desired tone and dialect (formal/informal and American/British English), and the app will provide a beautifully formatted email in the selected style. We cant build scale applications every time, just copy-pasting the prompts with our queries; instead, let’s get started and build this amazing “Professional Email Writer” tool.

Web Application Using OpenAI | Langchain

Learning Objectives

  • To learn how to build a beautiful web application using Streamlit.
  • To understand what prompt engineering is and how to create effective prompts for generating emails.
  • To learn how to query OpenAI LLM using Langchain’s PromptTemplate.
  • To learn how to deploy Python applications using Streamlit.

This article was published as a part of the Data Science Blogathon.

Streamlit Setup

First, we need to understand what streamlit is, how it works, and how to set it up for our use case. Streamlit allows us to create web applications in Python and host them locally and on the web. First, go to your terminal and install streamlit using the below command

pip install streamlit

Create an empty Python file for our script and run the file using the below command

python -m streamlit run [your_file_name.py]

This will start an empty streamlit app in the address localhost:8501. Open your browser and search for this address to visualize the app. One of the cool things about this app is you can make edits to your code base, and it will automatically update your app in the browser.

Build Frontend

Let’s start our code by adding a header and page title to our application. I am naming it as “Professional Email Writer”

#Importing Streamlit library.
import streamlit as st
# Set up Streamlit app with Header and Title
st.set_page_config(page_title="Professional Email Writer", page_icon=":robot:")
st.header("Professional Email Writer")

Output:

Web Application Using OpenAI | Langchain

Next, we need input from the user to know which email the user wants. For this, we use the text_area function provided by streamlit.

# Get the user input email text
def getEmail():
    input_text = st.text_area(label="Email Input", label_visibility='collapsed',
                              placeholder="Your Email...", key="input_text")
    return input_text

input_text = getEmail()

Output:

 Source: Author

Next, we need to have two dropdowns to ask the user which tone user is expecting in his email, i.e., Formal and Informal and also which English dialect the user is expecting, i.e., American English, British English.

# Display dropdowns for selecting tone and dialect
column1, column2 = st.columns(2)
with column1:
    tone_drop_down = st.selectbox(
        'Which tone would you like your email to have?',
        ('Formal', 'Informal'))

with column2:
    dialect_drop_down = st.selectbox(
        'Which English Dialect would you like?',
        ('American', 'British'))

The above code will create two columns, each containing a dropdown using the selectbox() function.

Output:

 Source: Author

We need to emphasize that anytime users update these selections, it should rerun the entire app for us. Think of it as a big refresh every time you toggle something on in the dropdowns.

Prompt Engineering

Now we need to take the email input given by the user and pass it with a prompt template through Langchain with the configuration that the user has selected from the dropdowns. Then we need to get the properly formatted output from OpenAI.

To do so, we need to set up a prompt template. We need to do some prompt Engineering for optimized output in this prompt template. Prompt engineering is a process of constructing prompts using which we can ask our queries to language models and fetch accurate results. You can modify this template based on your needs.

1. The prompt should clearly describe what the user is giving input. For example,

    Below is an email that may be unstructured and poorly worded.

2. The prompt should clearly explain what language model should give output. For example,

Your goal is to:

  • Format the email properly
  • Convert the input email into the tone specified in curly braces.
  • Convert the input email into the dialect specified in curly braces.
  • Please start the email with a warm introduction. Add the introduction if you need to.

3. The prompt should contain examples to ensure that model will be aware of output expectations.

4. Finally, the prompt should clearly indicate what user inputs are and what each input refers to.

Below is the prompt that we created by following the above rules

# Define the template for the email conversion task
template = """
    Below is an email that may be unstructured and poorly worded.
    Your goal is to:
    - Format the email properly
    - Convert the input email into the tone specified in curly braces. 
    - Convert the input email into the dialect specified in curly braces.

    Take these examples of different tones as reference:
    - Formal: We went to Hyderabad for the weekend. We have a lot of things to tell you.
    - Informal: Went to Hyderabad for the weekend. Lots to tell you.  

    Below are some examples of words in different dialects:
    - American: Garbage, cookie, green thumb, parking lot, pants, windshield, 
      French Fries, cotton candy, apartment
    - British: Green fingers, car park, trousers, windscreen, chips, candyfloss, 
      flag, rubbish, biscuit

    Example Sentences from each dialect:
    - American: As they strolled through the colorful neighborhood, Sarah asked her 
                friend if he wanted to grab a coffee at the nearby café. The fall 
                foliage was breathtaking, and they enjoyed the pleasant weather, 
                chatting about their weekend plans.
    - British: As they wandered through the picturesque neighbourhood, Sarah asked her 
               friend if he fancied getting a coffee at the nearby café. The autumn 
               leaves were stunning, and they savoured the pleasant weather, chatting 
               about their weekend plans.

    Please start the email with a warm introduction. Add the introduction if you need to.
    
    Below is the email, tone, and dialect:
    TONE: {tone}
    DIALECT: {dialect}
    EMAIL: {email}
    
    YOUR {dialect} RESPONSE:
"""

Now create the prompt using PromptTemplate class by Langchain, using which we can inject our user inputs into the prompt.

#Importing PromptTemplate class
from langchain import PromptTemplate
# Create a PromptTemplate instance to manage the input variables and the template
prompt = PromptTemplate(
    input_variables=["tone", "dialect", "email"],
    template=query_template,
)

Load Language Model

Make sure you have your OpenAI API Keys available with you. If not, follow the below steps.

  • Go to ‘https://openai.com/ and create your account.
  • Login into your account and select ‘API’ on your dashboard.
  • Now click on your profile icon, then select ‘View API Keys’.
  • Select ‘Create new secret key’, copy it, and save it.
Web Application Using OpenAI | Langchain | Large Language Model

Code for OpenAI API Key

Below is a code for the function that takes OpenAI API Key as input from the user using the text_input() function and displays the sample API Key as a placeholder.

# Display text input for OpenAI API Key
def fetchAPIKey():
    input_text = st.text_input(
        label="OpenAI API Key ",  placeholder="Ex: vk-Cb8un42twmA8tf...", key="openai_api_key_input")
    return input_text

# Get the OpenAI API Key from the user
openai_api_key = fetchAPIKey()

Output:

OpenAI API Key | Web Application Using OpenAI | Langchain

We need to ensure that our API key is either in our script, which is not recommended because we don’t want to code it hard anywhere, or it should be in our environment variables that our code can pull from. One way to create environmental variables is by using a separate .env file.

Steps for Environmental Variables

Follow the below steps for creating environmental variables:

1: Open your terminal and Install python-dotenv package using the command “pip install python dotenv”.

2: Create a file named “.env”.

3: Store your API Key in the below format

API_KEY=your_api_key_here

4: Load dotenv package and fetch your environmental variables using that package

from dotenv import load_dotenv
import os

# Load the environment variables from the .env file
load_dotenv()

# Access the API key using os.environ
openai_api_key = os.environ.get("API_KEY")

This method protects your API keys from accidentally exposing API Keys directly in your code. Keep this file secure instead of sharing publicly.

However, as OpenAI API allows a limited number of API requests, we will ask users to input their API keys instead of giving ours. In this case, we will load OpenAI with a temperature equal to 0.7, which means it will be creative. The below code throws us an error if we pass an invalid OpenAI API Key. Further, we must show appropriate warnings if the user enters invalid keys.

#Importing OpenAI Library
from langchain.llms import OpenAI
# Function to load the Language Model
def loadLanguageModel(api_key_openai):
    llm = OpenAI(temperature=.7, openai_api_key=api_key_openai)
    return llm

Example

Let us give a sample example to the user so that the user can understand what he should give as input and what he can expect in return. Let’s create a “Show an Example” button in the front. The below function updates the text box with a sample unstructured and poorly worded email query.

# Function to update the text box with an example email
def textBoxUpdateWithExample():
    print("in updated")
    st.session_state.input_text = "Vinay I am starts work at yours office from monday"

# Button to show an example email
st.button("*Show an Example*", type='secondary',
          help="Click to see an example of the email you will be converting.", on_click=textBoxUpdateWithExample)
st.markdown("### Your Email:")

Output:

 Source: Author

Next, we need to ensure that the user has inputted his API key, and also, he should have given some query in the text box before invoking the language model. If he invokes the model without API Key or invalid API, we need to show proper instructions to the user to fetch the correct secret key.

# If the user has provided input_text, proceed with email conversion
if input_text:
    if not openai_api_key:
        # If API Key is not provided, show a warning
        st.warning(
            'Please insert OpenAI API Key. Instructions [here](https://help.openai.com/en/articles/4936850-where-do-i-find-my-secret-api-key)', icon="⚠️")
        st.stop()
    # Load the Language Model with the provided API Key
    llm = loadLanguageModel(api_key_openai=openai_api_key)
    # Format the email using the PromptTemplate and the Language Model
    prompt_with_email = prompt.format(
        tone=tone_drop_down, dialect=dialect_drop_down, email=input_text)
    formatted_email = llm(prompt_with_email)
    # Display the formatted email
    st.write(formatted_email)

Output:

 Source: Author

If the user inputs the correct API key and proper email text in the text box, we format the prompt using the email text and configurations entered by the user, i.e., tone, and dialect. Then we will pass this prompt into our language model, and the LLM will give us the response as a properly formatted email which we will show the user under the “Your Email” tab using the streamlit write() function.

Deploy the Application

Follow the below steps to deploy the application:

1: First, we must push our code into the GitHub repository. Before pushing, create a requirements.txt file containing a list of all the dependencies of our code.

  • langchain
  • openai
  • streamlit

2: Head to streamlit.io and create an account by authorizing GitHub.

3: Login into your streamlit account.

4: Click on create a new app and pass all the details of the GitHub repository. Under the Main file path, give the name of the file which contains the Python script. Finally, click on deploy.

 Source: Author

5: Save the App URL. After a few minutes, you can see your application live on the web using that URL.

 Source: Author

Complete Implementation

# Import required libraries
from langchain import PromptTemplate
import streamlit as st
from langchain.llms import OpenAI

# Define the template for the email conversion task
query_template = query_template = """
    Below is an email that may be unstructured and poorly worded.
    Your goal is to:
    - Format the email properly
    - Convert the input email into the tone specified in curly braces. 
    - Convert the input email into the dialect specified in curly braces.

    Take these examples of different tones as reference:
    - Formal: We went to Hyderabad for the weekend. We have a lot of things to tell you.
    - Informal: Went to Hyderabad for the weekend. Lots to tell you.  

    Below are some examples of words in different dialects:
    - American: Garbage, cookie, green thumb, parking lot, pants, windshield, 
                French Fries, cotton candy, apartment
    - British: Green fingers, car park, trousers, windscreen, chips, candyfloss, 
               flag, rubbish, biscuit

    Example Sentences from each dialect:
    - American: As they strolled through the colorful neighborhood, Sarah asked her 
                friend if he wanted to grab a coffee at the nearby café. The fall 
                foliage was breathtaking, and they enjoyed the pleasant weather, 
                chatting about their weekend plans.
    - British: As they wandered through the picturesque neighbourhood, Sarah asked her 
               friend if he fancied getting a coffee at the nearby café. The autumn 
               leaves were stunning, and they savoured the pleasant weather, chatting 
               about their weekend plans.

    Please start the email with a warm introduction. Add the introduction if you need to.
    
    Below is the email, tone, and dialect:
    TONE: {tone}
    DIALECT: {dialect}
    EMAIL: {email}
    
    YOUR {dialect} RESPONSE:
"""

# Create a PromptTemplate instance to manage the input variables and the template
prompt = PromptTemplate(
    input_variables=["tone", "dialect", "email"],
    template=query_template,
)

# Function to load the Language Model
def loadLanguageModel(api_key_openai):
    llm = OpenAI(temperature=.7, openai_api_key=api_key_openai)
    return llm

# Set up Streamlit app with Header and Title
st.set_page_config(page_title="Professional Email Writer", page_icon=":robot:")
st.header("Professional Email Writer")

# Create columns for the Streamlit layout
column1, column2 = st.columns(2)

# Display text input for OpenAI API Key
def fetchAPIKey():
    input_text = st.text_input(
        label="OpenAI API Key ",  placeholder="Ex: vk-Cb8un42twmA8tf...", key="openai_api_key_input")
    return input_text

# Get the OpenAI API Key from the user
openai_api_key = fetchAPIKey()

# Display dropdowns for selecting tone and dialect
column1, column2 = st.columns(2)
with column1:
    tone_drop_down = st.selectbox(
        'Which tone would you like your email to have?',
        ('Formal', 'Informal'))

with column2:
    dialect_drop_down = st.selectbox(
        'Which English Dialect would you like?',
        ('American', 'British'))

# Get the user input email text
def getEmail():
    input_text = st.text_area(label="Email Input", label_visibility='collapsed',
                              placeholder="Your Email...", key="input_text")
    return input_text

input_text = getEmail()

# Check if the email exceeds the word limit
if len(input_text.split(" ")) > 700:
    st.write("Maximum limit is 700 words. Please enter a shorter email")
    st.stop()

# Function to update the text box with an example email
def textBoxUpdateWithExample():
    print("in updated")
    st.session_state.input_text = "Vinay I am starts work at yours office from monday"

# Button to show an example email
st.button("*Show an Example*", type='secondary',
          help="Click to see an example of the email you will be converting.", on_click=textBoxUpdateWithExample)
st.markdown("### Your Email:")

# If the user has provided input_text, proceed with email conversion
if input_text:
    if not openai_api_key:
        # If API Key is not provided, show a warning
        st.warning(
            'Please insert OpenAI API Key. Instructions [here](https://help.openai.com/en/articles/4936850-where-do-i-find-my-secret-api-key)', icon="⚠️")
        st.stop()
    # Load the Language Model with the provided API Key
    llm = loadLanguageModel(api_key_openai=openai_api_key)
    # Format the email using the PromptTemplate and the Language Model
    prompt_with_email = prompt.format(
        tone=tone_drop_down, dialect=dialect_drop_down, email=input_text)
    formatted_email = llm(prompt_with_email)
    # Display the formatted email
    st.write(formatted_email)

Conclusion

In this article, we have seen how to create a beautiful web application using OpenAI LLM with the help of Langchain. We started with installing and setting up Streamlit. Then we created a frontend interface to take user inputs like tone, dialect, and email text from the user. After that, we created an effective prompt to query the language model using these inputs. Next, we initialized the OpenAI model using API keys by passing the prompt we created using Langchain. Finally, we deployed the application into the web using Streamlit.

Key Takeaways

  • Using the Streamlit library in Python, we can build interactive web applications.
  • Prompt engineering plays crucial for fetching optimized results from the Language model.
  • OpenAI LLM can be easily used in our Python applications using the OpenAI library and its secret keys.
  • Using Langchain’s PromptTemplate, we can properly format the Prompt based on user input which can further be used in querying the LLM.
  • Using Streamlit share, we can host the Python application in Live URL.

Frequently Asked Questions

Q1. What is the use of the Streamlit library in Python?

A. Streamlit is an Open source Python library that can be used to create interactive web applications with simple Python functions without extensive knowledge of web development.

Q2. How to create an app with OpenAI?

A. First, you need to choose the application development tech stack, and then, using OpenAI secret keys, you can leverage the benefits of OpenAI.

Q3. Can I use ChatGPT to write emails?

A. Yes, you can use ChatGPT for writing emails. You can generate email content by providing effective prompts with clear descriptions of email expectations to ChatGPT.

Q4. What is the default OpenAI model in LangChain?

A. The default OpenAI model used in LangChain is OpenAI GPT-3.5-turbo.

Q5. Can I use OpenAI for free?

A. OpenAI provides both free and paid services. You can get a limited API request, GPT-3 model for free service. You can get increased access to their models and more API requests using the paid version.

The media shown in this article is not owned by Analytics Vidhya and is used at the Author’s discretion. 

Frequently Asked Questions

Lorem ipsum dolor sit amet, consectetur adipiscing elit,

Responses From Readers

Related Courses