Use Python+AWS Create Sentiment Analysis Application
Tags: aws, python, lambda, apigateway
Published: 2022-01-10 14:02:31

## Hi,Today I will share my experience to you,It's about Use Python And Amazon Comprehend ,and I also use Lambda,Api Gateway togather build the tool

1. Python Stage(I will put my code in this stage)
#### Notice:I use Qtdesigner and PYUIC

```
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file '1.ui'
#
# Created by: PyQt5 UI code generator 5.15.6
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


import sys

import openpyxl
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog, QWidget
from PyQt5.QtWidgets import QApplication
import requests
import json
import datetime
import ctypes
import images

#Change Task manager icon
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid")

filename = '1'#Waiting analysis file name
flag = 1 #analysis flag

class About_page(QWidget):
    def __init__(self):
        super(About_page, self).__init__()
        self.resize(400,300)
        self.setWindowTitle("About")
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(':/Image-2.ico'), QtGui.QIcon.Normal)
        self.setWindowIcon(icon)
        self.label = QtWidgets.QLabel(self)
        self.label.setGeometry(QtCore.QRect(30, 40, 161, 21))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self)
        self.label_2.setGeometry(QtCore.QRect(30, 75, 161, 21))
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(self)
        self.label_3.setGeometry(QtCore.QRect(30, 110, 91, 21))
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(self)
        self.label_4.setGeometry(QtCore.QRect(130, 110, 221, 21))
        self.label_4.setObjectName("label_4")

        self.retranslateUi(self)
        QtCore.QMetaObject.connectSlotsByName(self)

    def retranslateUi(self,About_page):
        _translate = QtCore.QCoreApplication.translate
        self.setWindowTitle(_translate("Form", "About"))
        self.label.setText(_translate("Form", "Copyright ownership:T-UniStar"))
        self.label_2.setText(_translate("Form", "User:Lei Feng"))
        self.label_3.setText(_translate("Form", "Powered by"))
        self.label_4.setText(_translate("Form",
                                        u'<a href="https://aws.amazon.com/cn/" style="color:#0000ff;"><b>Amazon Web Services, Inc.</b></a>'))
        self.label_4.setOpenExternalLinks(True)

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(750, 548)
        Form.setFixedSize(QtCore.QSize(780, 548))
        Form.setMaximumSize(QtCore.QSize(750, 548))
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(':/Image-1.ico'), QtGui.QIcon.Normal)
        Form.setWindowIcon(icon)
        self.label = QtWidgets.QLabel(Form)
        self.label.setGeometry(QtCore.QRect(220, 10, 261, 61))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(26)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(Form)
        self.label_2.setGeometry(QtCore.QRect(250, 70, 211, 21))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")
        self.pushButton = QtWidgets.QPushButton(Form)
        self.pushButton.setGeometry(QtCore.QRect(20, 140, 111, 28))
        self.pushButton.setObjectName("pushButton")
        self.pushButton.clicked.connect(self.RealTime_analysis)
        self.textEdit = QtWidgets.QTextEdit(Form)
        self.textEdit.setGeometry(QtCore.QRect(160, 140, 291, 31))
        self.textEdit.setObjectName("textEdit")
        self.label_3 = QtWidgets.QLabel(Form)
        self.label_3.setGeometry(QtCore.QRect(20, 100, 201, 31))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(20)
        self.label_3.setFont(font)
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(Form)
        self.label_4.setGeometry(QtCore.QRect(20, 200, 481, 31))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(18)
        self.label_4.setFont(font)
        self.label_4.setObjectName("label_4")
        self.pushButton_2 = QtWidgets.QPushButton(Form)
        self.pushButton_2.setGeometry(QtCore.QRect(40, 420, 111, 28))
        self.pushButton_2.setObjectName("pushButton_2")
        self.pushButton_2.clicked.connect(self.multWordsAy)
        self.label_5 = QtWidgets.QLabel(Form)
        self.label_5.setGeometry(QtCore.QRect(20, 250, 171, 31))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.label_5.setFont(font)
        self.label_5.setObjectName("label_5")
        self.label_6 = QtWidgets.QLabel(Form)
        self.label_6.setGeometry(QtCore.QRect(20, 330, 171, 31))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.label_6.setFont(font)
        self.label_6.setObjectName("label_6")
        self.label_7 = QtWidgets.QLabel(Form)
        self.label_7.setGeometry(QtCore.QRect(80, 280, 31, 51))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(20)
        font.setBold(False)
        font.setWeight(50)
        self.label_7.setFont(font)
        self.label_7.setObjectName("label_7")
        self.label_8 = QtWidgets.QLabel(Form)
        self.label_8.setGeometry(QtCore.QRect(80, 360, 31, 51))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(20)
        font.setBold(False)
        font.setWeight(50)
        self.label_8.setFont(font)
        self.label_8.setObjectName("label_8")
        self.label_9 = QtWidgets.QLabel(Form)
        self.label_9.setGeometry(QtCore.QRect(200, 250, 561, 31))
        self.label_9.setObjectName("label_9")
        self.textBrowser = QtWidgets.QTextBrowser(Form)
        self.textBrowser.setGeometry(QtCore.QRect(190, 410, 351, 131))
        self.textBrowser.setObjectName("textBrowser")
        self.lineEdit = QtWidgets.QLineEdit(Form)
        self.lineEdit.setGeometry(QtCore.QRect(180, 330, 301, 31))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit.setEnabled(False)
        self.pushButton_3 = QtWidgets.QPushButton(Form)
        self.pushButton_3.setGeometry(QtCore.QRect(510, 330, 111, 31))
        self.pushButton_3.setObjectName("pushButton_3")
        self.pushButton_3.clicked.connect(self.openFile)
        self.label_10 = QtWidgets.QLabel(Form)
        self.label_10.setGeometry(QtCore.QRect(470, 110, 72, 21))
        self.label_10.setObjectName("label_10")
        self.label_11 = QtWidgets.QLabel(Form)
        self.label_11.setGeometry(QtCore.QRect(560, 110, 72, 21))
        self.label_11.setObjectName("label_11")
        self.label_12 = QtWidgets.QLabel(Form)
        self.label_12.setGeometry(QtCore.QRect(650, 110, 72, 21))
        self.label_12.setObjectName("label_12")
        self.textEdit_2 = QtWidgets.QTextEdit(Form)
        self.textEdit_2.setGeometry(QtCore.QRect(460, 140, 81, 31))
        self.textEdit_2.setObjectName("textEdit_2")
        self.textEdit_2.setEnabled(False)
        self.textEdit_3 = QtWidgets.QTextEdit(Form)
        self.textEdit_3.setGeometry(QtCore.QRect(550, 140, 81, 31))
        self.textEdit_3.setObjectName("textEdit_3")
        self.textEdit_3.setEnabled(False)
        self.textEdit_4 = QtWidgets.QTextEdit(Form)
        self.textEdit_4.setGeometry(QtCore.QRect(640, 140, 81, 31))
        self.textEdit_4.setObjectName("textEdit_4")
        self.textEdit_4.setEnabled(False)
        self.pushButton_4 = QtWidgets.QPushButton(Form)
        self.pushButton_4.setGeometry(QtCore.QRect(650, 500, 93, 28))
        self.pushButton_4.setObjectName("pushButton_4")
        self.pushButton_4.clicked.connect(self.open_About_page)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Sentiment Analysis System"))
        self.label.setText(_translate("Form", "Sentiment Analysis System"))
        self.label_2.setText(_translate("Form", "Please follow the stage work"))
        self.pushButton.setText(_translate("Form", "Start Single words Analysis"))
        self.textEdit.setHtml(_translate("Form", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-style:italic;\">Please Input Need Analysis words</span></p></body></html>"))
        self.label_3.setText(_translate("Form", "Single Words Analysis"))
        self.label_4.setText(_translate("Form", "More Words Analysis(Only support XLSX format)"))
        self.pushButton_2.setText(_translate("Form", "Start More Words Analysis"))
        self.label_5.setText(_translate("Form", "Stage 1、Format head"))
        self.label_6.setText(_translate("Form", "Stage 2、Choose File"))
        self.label_7.setText(_translate("Form", "↓"))
        self.label_8.setText(_translate("Form", "↓"))
        self.label_9.setText(_translate("Form", "The First head is：Text、Positive、Negative、Neutral、Emotion judgment、Language"))
        self.pushButton_3.setText(_translate("Form", "Choose File"))
        self.label_10.setText(_translate("Form", "Positive"))
        self.label_11.setText(_translate("Form", "Negative"))
        self.label_12.setText(_translate("Form", "Emotion Judgment"))
        self.pushButton_4.setText(_translate("Form", "About"))

    def RealTime_analysis(self):
        stat_words = self.textEdit.toPlainText()
        #print(stat_words)
        #print(data)
        url = "https://yuzcb6dtb3.execute-api.us-east-1.amazonaws.com/endpoint"
        payload = json.dumps({
            "Text": stat_words
        })
        headers = {
            'Content-Type':'application/json'
        }

        RTResponse = requests.request('POST',url,headers=headers,data=payload)
        RTRp_text = RTResponse.text

        RT_Positive = json.loads(RTRp_text)['body']['SentimentScore']['Positive']
        RT_Negative = json.loads(RTRp_text)['body']['SentimentScore']['Negative']
        RT_Neutral = json.loads(RTRp_text)['body']['SentimentScore']['Neutral']
        # print(float(str(json.loads(RTRp_text)['body']['SentimentScore']['Positive'])))
        # self.textEdit_2.setText(RT_Positive)
        # self.textEdit_3.setText(RT_Negative)
        if RT_Positive > RT_Negative and RT_Positive > RT_Neutral:
            self.textEdit_2.setText(str(float(RT_Positive) * 100)[:8])
            self.textEdit_3.setText(str(float(RT_Negative)*10)[:8])
            self.textEdit_4.setText('Postive')
        elif RT_Positive < RT_Negative and RT_Neutral < RT_Negative:
            self.textEdit_2.setText(str(float(RT_Positive)*10)[:8])
            self.textEdit_3.setText(str(float(RT_Negative)*100)[:8])
            self.textEdit_4.setText('Negative')
        else:
            self.textEdit_2.setText(str(float(RT_Positive) * 10)[:8])
            self.textEdit_3.setText(str(RT_Negative)[:8])

            self.textEdit_4.setText('Neutral')

        print(RTRp_text)


    def openFile(self):
        openFileName = QFileDialog.getOpenFileName(None,'Choose File', '', 'Excel files(*.xlsx)')
        print(openFileName)
        openF = openFileName[0].split('/')
        global filename;
        filename = openFileName[0];
        name = openF[len(openF) - 1];
        self.lineEdit.setText(str(name))


    def stopAnalysis(self):
        self.pushButton_2.setText("Start More Words Analysis")
        self.pushButton_2.clicked.disconnect(self.stopAnalysis)
        self.pushButton_2.clicked.connect(self.multWordsAy)
        self.textBrowser.append("Stopped by user：" + datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
        global flag;
        flag = -1;
        return

    def multWordsAy(self):
        #Check file exist
        global flag;
        flag = 1
        import os
        if (not os.path.exists(filename)):
            self.textBrowser.append('This file not exist！')
            return;
        self.pushButton_2.setText("Stop Analysis")
        self.textBrowser.append("Start Analysis：" + datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
        self.pushButton_2.clicked.disconnect(self.multWordsAy)
        self.pushButton_2.clicked.connect(self.stopAnalysis)

        def getMultResult(text):
            senment_words = text
            # print(stat_words)
            # print(data)
            url = "https://yuzcb6dtb3.execute-api.us-east-1.amazonaws.com/endpoint"
            mult_payload = json.dumps({
                "Text": senment_words
            })
            headers = {
                'Content-Type': 'application/json'
            }

            multResponse = requests.request('POST', url, headers=headers, data=mult_payload)
            mult_resp_text = multResponse.text
            mu_Positive = json.loads(mult_resp_text)['body']['SentimentScore']['Positive']
            mu_Negative = json.loads(mult_resp_text)['body']['SentimentScore']['Negative']
            mu_Neutral = json.loads(mult_resp_text)['body']['SentimentScore']['Neutral']
            LanguageCode = json.loads(mult_resp_text)['LanguageCode']
            return [mu_Positive,mu_Negative,mu_Neutral,LanguageCode]



        book = openpyxl.load_workbook(filename)
        sheet = book.get_sheet_by_name(book.get_sheet_names()[0])
        rows = sheet.max_row
        showText = "Read file successful，amount"+str(rows-1)+"records waiting analysis。。。\nCurrent Time："+datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        self.textBrowser.append(showText)
        if (sheet.cell(1, 1).value != 'Text' or sheet.cell(1, 2).value != 'Positive' or sheet.cell(1,3).value != 'Negative' or sheet.cell(1, 4).value != 'Negative' or sheet.cell(1, 5).value != 'Emotion judgment' or sheet.cell(1,6).value != 'Language'):
            self.textBrowser.append('The execl not stand format！')
            return;
        for i in range(2,rows+1):
            detectWords = sheet.cell(i,1).value
            detectResult = getMultResult(detectWords)
            self.textBrowser.append(f'Analysising {i-1}Record,Current Time:{datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}')
            print(f'Analysising{i-1}Record,Current Time:{datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}')
            sheet.cell(i,2,detectResult[0])
            sheet.cell(i,3,detectResult[1])
            sheet.cell(i,4,detectResult[2])
            sheet.cell(i,6,detectResult[3])
            if detectResult[0] > detectResult[1] and detectResult[0] > detectResult[2]:
                sheet.cell(i,5,"Positive")
            elif detectResult[1] > detectResult[0] and detectResult[1] > detectResult[2]:
                sheet.cell(i,5,"Negative")
            else:
                sheet.cell(i,5,"Neutral")
            QApplication.processEvents()
        book.save(filename)
        self.textBrowser.append('Analysis ended')

        self.textBrowser.append(str(rows - 1) + "Records analysis done！")
        self.pushButton_2.setText("Strat Analysis")
        self.pushButton_2.clicked.disconnect(self.stopAnalysis)
        self.pushButton_2.clicked.connect(self.multWordsAy)

    def open_About_page(self):
        self.about_form = About_page()
        self.about_form.show()




if __name__=="__main__":
    app=QtWidgets.QApplication(sys.argv)
    widget=QtWidgets.QMainWindow()
    # widget.setFixedSize(widget.width(), widget.height()-80) #ban max
    ui=Ui_Form()
    ui.setupUi(widget)
    widget.showMaximized()
    sys.exit(app.exec_())
```

2. Lambda And Api Gateway Stage
#### Notice You need give right IAM
![Lambda Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xk2smazy6o4rilbe4v3v.png)

Here is the Lambda Code

```
import json
import boto3

comprehend = boto3.client(service_name='comprehend', region_name='ap')

def lambda_handler(event, context):
    # TODO implement
    LanguageCode = comprehend.detect_dominant_language(Text=event['Text'])
    comprehend_sentiment = comprehend.detect_sentiment(Text = event['Text'],LanguageCode=LanguageCode['Languages'][0]['LanguageCode'])
    print(LanguageCode)
    return {
        'statusCode': 200,
        'body': comprehend_sentiment,
        'LanguageCode':LanguageCode['Languages'][0]['LanguageCode']
    }
```

#### This is Apigateway(When you finished,You need deploy it and use postman to test)
![Apigateway](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/te7g9jlpdaa8pzwtol80.png)
 

3. The Final display
![Build Done display](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/odjjvuh3la2cnlxz7ire.png)