From c852fdb802d9f37aac67eb075439da18a592591b Mon Sep 17 00:00:00 2001 From: Sebastian Steiner Date: Fri, 18 Jan 2019 15:40:53 +0100 Subject: [PATCH] #57 #54 and refactoring --- service-analysis/README.md | 23 +++++++++++---- service-analysis/analysis.py | 32 +++++++++++++++++++++ service-analysis/health_check.py | 6 ++++ service-analysis/indico_api_key.txt | 1 + service-analysis/sentiment_analysis.py | 39 ++++++-------------------- 5 files changed, 65 insertions(+), 36 deletions(-) create mode 100644 service-analysis/analysis.py create mode 100644 service-analysis/health_check.py create mode 100644 service-analysis/indico_api_key.txt diff --git a/service-analysis/README.md b/service-analysis/README.md index aa0e4c0..802b4eb 100644 --- a/service-analysis/README.md +++ b/service-analysis/README.md @@ -13,22 +13,27 @@ example body of request: ```json [ { - 'text': 'text 1', + 'text': 'sample text 1', }, { - 'text': 'text 2', + 'text': 'sample text 2', }, { - 'text': 'text 3', + '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. ## API errors - `409`: input string does not meet specifications - `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. + ## run with docker - `docker build -t sentiment_analysis .` - `docker container run -d -p YOUR_PORT:8081 sentiment_analysis` @@ -40,8 +45,14 @@ JSON string may contain more value-key pairs than 'text', but 'text' is needed f -> indicoio -> flask -> flask_restful - ### commands - `python3.7 sentiment_analysis.py` -- positive sentiment test example: `curl -vs -H 'content-type: application/json' -X POST http://localhost:8081 -d '[{"text":"happy birthday, i love you"}]'` -- negative sentiment test example: `curl -vs -H 'content-type: application/json' -X POST http://localhost:8081 -d '[{"text":"i hate you, please die"}]'` +- 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"}]'` + +## health check +Under http://localhost:8081/health the service returns HTTP Status 200 if it is running OK. +### commans +curl -v -X GET http://localhost:8081/health diff --git a/service-analysis/analysis.py b/service-analysis/analysis.py new file mode 100644 index 0000000..291b8e0 --- /dev/null +++ b/service-analysis/analysis.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +import json +import indicoio + +from flask import request +from flask_restful import Resource, abort + +input_error_409 = 'Input must be a list of JSON objects. JSON objects must contain contain key text.' +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'} + + def post(self): + if not request.json or not isinstance(request.json, (list,)): + return abort(409, message=input_error_409) + texts = request.json + text_array = [] + value = 0 + 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 abort(503, message=service_error_503) + sentiment = value/len(text_array) + data = {'sentiment': sentiment} + return data diff --git a/service-analysis/health_check.py b/service-analysis/health_check.py new file mode 100644 index 0000000..500b923 --- /dev/null +++ b/service-analysis/health_check.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from flask_restful import Resource + +class Health_Check(Resource): + def get(self): + return "System up and running :)", 200 diff --git a/service-analysis/indico_api_key.txt b/service-analysis/indico_api_key.txt new file mode 100644 index 0000000..339d02b --- /dev/null +++ b/service-analysis/indico_api_key.txt @@ -0,0 +1 @@ +525f16078717a430f9dac17cdc9dbaa3 diff --git a/service-analysis/sentiment_analysis.py b/service-analysis/sentiment_analysis.py index 2a013e9..e27b0af 100644 --- a/service-analysis/sentiment_analysis.py +++ b/service-analysis/sentiment_analysis.py @@ -2,41 +2,20 @@ import json import indicoio -from flask import Flask, request, jsonify, Response -from flask_restful import Resource, Api, output_json, abort +from analysis import Analysis +from health_check import Health_Check + +from flask import Flask +from flask_restful import Api app = Flask(__name__) api = Api(app) -indicoio.config.api_key = '525f16078717a430f9dac17cdc9dbaa3' - -input_error_409 = 'Input must be a list of JSON objects. JSON objects must contain contain key text.' -service_error_503 = 'The sentiment analysis service is currently unavailable.' +with open('indico_api_key.txt', 'r') as key: + indicoio.config.api_key = key.read().replace('\n','') -class Sentiment_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'} - - def post(self): - if not request.json or not isinstance(request.json, (list,)): - return abort(409, message=input_error_409) - texts = request.json - text_array = [] - value = 0 - 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 data - -api.add_resource(Sentiment_Analysis, '/') +api.add_resource(Analysis, '/') +api.add_resource(Health_Check, '/health') if __name__ == '__main__': app.run(host="0.0.0.0", port=8081, debug=False) -- 2.43.0