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.43.0