-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"]
## 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`
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, '/')