From 55224e7692199fc5695f5965188ce77ce9a8c4c9 Mon Sep 17 00:00:00 2001 From: Sebastian Steiner 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