From b4ea4046fa0fb8b437a9363b5d16501011de5347 Mon Sep 17 00:00:00 2001 From: Sebastian Steiner Date: Fri, 18 Jan 2019 16:29:56 +0100 Subject: [PATCH] issue #62 implemented --- service-analysis/Dockerfile | 2 ++ service-analysis/README.md | 32 +++++++++++++++++++++----- service-analysis/analysis.py | 2 +- service-analysis/offline_analysis.py | 26 +++++++++++++++++++++ service-analysis/requirements.txt | 1 + service-analysis/sentiment_analysis.py | 2 ++ 6 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 service-analysis/offline_analysis.py diff --git a/service-analysis/Dockerfile b/service-analysis/Dockerfile index ad239ec..be70c7c 100644 --- a/service-analysis/Dockerfile +++ b/service-analysis/Dockerfile @@ -6,6 +6,8 @@ COPY . /app/ RUN pip install -r requirements.txt +RUN python -m textblob.download_corpora + RUN chmod a+x *.py CMD ["python3.7", "./sentiment_analysis.py"] diff --git a/service-analysis/README.md b/service-analysis/README.md index 1572beb..57c6b0c 100644 --- a/service-analysis/README.md +++ b/service-analysis/README.md @@ -9,7 +9,7 @@ The service uses the the sentiment analysis service indico. `GET`: `/health` Returns HTTP Status 200 if service is running -`POST`: `/` Calculates the average sentiment for a given list of texts +`POST`: `/` Calculates the average sentiment for a given list of texts using the online sentiment analysis tool indico (https://www.indico.io). - param: Term[ ] as Content-Tye: `application/json` example body of request: ```json @@ -25,6 +25,22 @@ example body of request: } ] ``` +`POST`: `/offline_analysis` Calculates the average sentiment for a given list of texts using TextBlob (https://textblob.readthedocs.io) +- param: Term[ ] as Content-Tye: `application/json` +example body of request: +```json +[ + { + 'text': 'sample text 1', + }, + { + 'text': 'sample text 2', + }, + { + 'text': 'sample 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. For more examples see curl commands in local -> commands. @@ -33,8 +49,9 @@ For more examples see curl commands in local -> commands. - `503`: indico sentiment analysis not available ## external services -This sentiment analysis service uses and relies on the online sentiment analysis indico (https://www.indico.io). -The api key can be set in the file indico_api_key.txt. The current key does work, however excessive use of this service will require you to provide your own key, since the amount of requests for this key is limited. +This sentiment analysis service uses the online sentiment analysis indico (https://www.indico.io). +The indico api key can be set in the file indico_api_key.txt. The current key does work, however excessive use of this service will require you to provide your own key, since the amount of requests for this key is limited. +In case of an 503 error, you can use the `/offline_analysis`. ## run with docker - `docker build -t sentiment_analysis .` @@ -46,8 +63,11 @@ The api key can be set in the file indico_api_key.txt. The current key does work - pip: indicoio - pip: flask - pip: flask_restful +- pip: textblob ### commands -- `python3.7 sentiment_analysis.py` -- positive sentiment test example: `curl -v -H 'content-type: application/json' -X POST http://localhost:8081 -d '[{"text":"happy birthday, i love you"}]'` -- negative sentiment test example: `curl -v -H 'content-type: application/json' -X POST http://localhost:8081 -d '[{"text":"i hate you, please die"}]'` +- `python3.7 sentiment_analysis.py` to start the service +- positive online sentiment test example: `curl -v -H 'content-type: application/json' -X POST http://localhost:8081 -d '[{"text":"happy birthday, i love you"}]'` +- negative online sentiment test example: `curl -v -H 'content-type: application/json' -X POST http://localhost:8081 -d '[{"text":"i hate you, please die"}]'` +- positive offline sentiment test example: `curl -v -H 'content-type: application/json' -X POST http://localhost:8081/offline_analysis -d '[{"text":"happy birthday, i love you"}]'` +- negative offline sentiment test example: `curl -v -H 'content-type: application/json' -X POST http://localhost:8081/offline_analysis -d '[{"text":"i hate you, please die"}]'` - health check test example: `curl -v -X GET http://localhost:8081/health` diff --git a/service-analysis/analysis.py b/service-analysis/analysis.py index 291b8e0..b0c43b2 100644 --- a/service-analysis/analysis.py +++ b/service-analysis/analysis.py @@ -10,7 +10,7 @@ service_error_503 = 'The sentiment analysis service is currently unavailable.' class Analysis(Resource): def get(self): - return "POST a list of JSON objects as content-type: application/json. JSON objects must contain key 'text'.", 405, {'Allow': 'GET'} + return "POST a list of JSON objects as content-type: application/json. JSON objects must contain key 'text'.", 405 def post(self): if not request.json or not isinstance(request.json, (list,)): diff --git a/service-analysis/offline_analysis.py b/service-analysis/offline_analysis.py new file mode 100644 index 0000000..9c9da3a --- /dev/null +++ b/service-analysis/offline_analysis.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +import json + +from flask import request +from flask_restful import Resource, abort +from textblob import TextBlob + +input_error_409 = 'Input must be a list of JSON objects. JSON objects must contain contain key text.' + +class Offline_Analysis(Resource): + def get(self): + return "POST a list of JSON objects as content-type: application/json. JSON objects must contain key 'text'.", 405 + + def post(self): + if not request.json or not isinstance(request.json, (list,)): + return abort(409, message=input_error_409) + texts = request.json + value = 0 + for text in texts: + if 'text' not in text: + return abort(409, message=input_error_409) + analysis = TextBlob(text['text']) + value += (analysis.sentiment.polarity/2) + 0.5 + sentiment = value/len(texts) + data = {'sentiment': sentiment} + return data diff --git a/service-analysis/requirements.txt b/service-analysis/requirements.txt index 206be2f..65e5420 100644 --- a/service-analysis/requirements.txt +++ b/service-analysis/requirements.txt @@ -1,3 +1,4 @@ flask flask_restful indicoio +textblob diff --git a/service-analysis/sentiment_analysis.py b/service-analysis/sentiment_analysis.py index e27b0af..055a48d 100644 --- a/service-analysis/sentiment_analysis.py +++ b/service-analysis/sentiment_analysis.py @@ -3,6 +3,7 @@ import json import indicoio from analysis import Analysis +from offline_analysis import Offline_Analysis from health_check import Health_Check from flask import Flask @@ -15,6 +16,7 @@ with open('indico_api_key.txt', 'r') as key: indicoio.config.api_key = key.read().replace('\n','') api.add_resource(Analysis, '/') +api.add_resource(Offline_Analysis, '/offline_analysis') api.add_resource(Health_Check, '/health') if __name__ == '__main__': -- 2.43.0