From 55224e7692199fc5695f5965188ce77ce9a8c4c9 Mon Sep 17 00:00:00 2001
From: Sebastian Steiner <e1029038@student.tuwien.ac.at>
Date: Wed, 28 Nov 2018 15:33:26 +0100
Subject: [PATCH] Issue #20 fixed
---
service-analysis/Dockerfile | 10 +++----
service-analysis/README.md | 41 ++++++++++++++++++++++++--
service-analysis/requirements.txt | 3 ++
service-analysis/sentiment_analysis.py | 35 ++++++++++++++--------
4 files changed, 67 insertions(+), 22 deletions(-)
create mode 100644 service-analysis/requirements.txt
diff --git a/service-analysis/Dockerfile b/service-analysis/Dockerfile
index 976abd1..ad239ec 100644
--- a/service-analysis/Dockerfile
+++ b/service-analysis/Dockerfile
@@ -1,13 +1,11 @@
-FROM python:3
+FROM python:3.7-slim
LABEL maintainer="Sebastian Steiner"
-RUN pip install flask
-RUN pip install flask_restful
-RUN pip install indicoio
-
WORKDIR /app
COPY . /app/
+RUN pip install -r requirements.txt
+
RUN chmod a+x *.py
-CMD ["python3", "./sentiment_analysis.py"]
+CMD ["python3.7", "./sentiment_analysis.py"]
diff --git a/service-analysis/README.md b/service-analysis/README.md
index 59f472f..fb414fa 100644
--- a/service-analysis/README.md
+++ b/service-analysis/README.md
@@ -2,8 +2,43 @@
## API
+Provides a REST-API to get the average sentiment of a given list of texts
+The service uses the the sentiment analysis service indico.
-You can post a json string to the REST API on http://localhost:8081/.
-The json string needs to contain name-value key 'text'.
+`GET`: `/` Displays the expected input for a POST
-The service uses the online sentiment analysis tool indico to get the sentiment for each text, calculates the average sentiment value and returns it.
+`POST`: `/` Calculates the average sentiment for a given list of texts
+- param: Term[] as Content-Tye: `application/json`
+example body of request:
+```json
+[
+ {
+ 'text': 'text 1',
+ },
+ {
+ 'text': 'text 2',
+ },
+ {
+ 'text': 'text 3',
+ }
+]
+```
+JSON string may contain more value-key pairs than 'text', but 'text' is needed for the sentiment analysis. Everything else will be ignored.
+
+## API errors
+- `409`: input string does not meet specifications
+- `503`: indico sentiment analysis not available
+
+## run with docker
+- `docker build -t sentiment_analysis .`
+- `docker run -d -p YOUR_PORT:8081 sentiment_analysis`
+
+## run local
+### requirements
+- python 3.7
+- pip
+ -> indicoio
+ -> flask
+ -> flask_restfut
+### commands
+- `python3.7 sentiment_analysis.py`
diff --git a/service-analysis/requirements.txt b/service-analysis/requirements.txt
new file mode 100644
index 0000000..206be2f
--- /dev/null
+++ b/service-analysis/requirements.txt
@@ -0,0 +1,3 @@
+flask
+flask_restful
+indicoio
diff --git a/service-analysis/sentiment_analysis.py b/service-analysis/sentiment_analysis.py
index d9836af..933ce9c 100644
--- a/service-analysis/sentiment_analysis.py
+++ b/service-analysis/sentiment_analysis.py
@@ -2,30 +2,39 @@
import json
import indicoio
-from flask import Flask, request
-from flask_restful import Resource, Api
+from flask import Flask, request, jsonify
+from flask_restful import Resource, Api, output_json, abort
app = Flask(__name__)
api = Api(app)
indicoio.config.api_key = '525f16078717a430f9dac17cdc9dbaa3'
+input_error_409 = 'Input must be a JSON string. JSON objects must contain contain key text.'
+service_error_503 = 'The sentiment analysis service is currently unavailable.'
+
class Sentiment_Analysis(Resource):
def get(self):
- return "correct usage: curl -H 'content-type: application/json' -X POST http://localhost:8081 -d '$your JSON here$'"
+ return "POST a JSON string as content-type: application/json. JSON objects must contain key 'text'."
def post(self):
- tweets = request.json
+ if not request.json:
+ return abort(409, message=input_error_409)
+ texts = request.json
+ text_array = []
value = 0
- for tweet in tweets:
- #possible performance improvement: batch sentiment: indicoio.sentiment($list_of_texts$)
- sentiment_value = indicoio.sentiment(tweet['text'])
- value += sentiment_value
- #returns number between 0 and 1.
- #it is a probability representing the likelihood that the analyzed text is positive or negative
- #values > 0.5 indicate positive sentiment
- #values < 0.5 indicate negative sentiment
- return value/len(tweets)
+ for text in texts:
+ if 'text' not in text:
+ return abort(409, message=input_error_409)
+ text_array.append(text['text'])
+ try:
+ for sentiment_value in indicoio.sentiment(text_array):
+ value += sentiment_value
+ except:
+ return make_error(503, message=service_error_503)
+ sentiment = value/len(text_array)
+ data = {'sentiment': sentiment}
+ return output_json(json.dumps(data), 200)
api.add_resource(Sentiment_Analysis, '/')
--
2.47.3