content: # -*- coding: utf-8 -*-
  #
  # This file is part of semantic_query.
  # Copyright (C) 2016 CIAPPLE.
  #
  # This is a free software; you can redistribute it and/or modify it
  # under the terms of the Revised BSD License; see LICENSE file for
  # more details.
  
  # Semantic Query API
  
  # Author: Hussein AL-NATSHEH <h.natsheh@ciapple.com>
  # Affiliation: CIAPPLE, Jordan
  
  import os, argparse, pickle, json
  import numpy as np
  
  from sklearn.feature_extraction.text import TfidfVectorizer
  from sklearn.decomposition import TruncatedSVD
  from sklearn.metrics.pairwise import cosine_similarity
  from sklearn.pipeline import Pipeline
  
  from collections import OrderedDict
  from itertools import islice
  from bs4 import BeautifulSoup
  
  from flask import Flask, request, make_response
  from flask_httpauth import HTTPBasicAuth
  from flask_restful import Resource, Api, reqparse
  
  def top(n, sorted_results):
  	return list(islice(sorted_results.iteritems(), n))
  
  def query_by_text(transformer, transformed, documents, index, query_text, url, n_results=10):
  	query = transformer.transform(query_text)
  	sims = cosine_similarity(query.reshape(1,-1), transformed)
  	scores =  sims[0][:].reshape(-1,1)
  	results= dict()
  	for i in range(len(transformed)):
  		results[i] = scores[i]
  	sorted_results = OrderedDict(sorted(results.items(), key=lambda k: k[1], reverse=True))
  	topn = top(n_results, sorted_results)
  
  	results = np.array(range(n_results), dtype=np.object)
  	for rank, (answer, score) in enumerate(topn):
  		title = documents[answer].split('\n__')[0]
  		title_t = title.replace (" ", "_")
  		doc_id = str(index[answer])
  		reference = url + title_t
  		results[rank] = {'reference': reference, 'score': str(score), 'doc_id':  doc_id, 'title': title, 'answer': documents[answer]}
  
  	return results.tolist()
  
  class Query(Resource):
  	def post(self):
  		try:
  			parser = reqparse.RequestParser()
  			parser.add_argument('question', type=str, required=True, help='Query text')
  			parser.add_argument('userId', type=str, required=False, help='User ID')
  			parser.add_argument('questionId', type=str, required=False, help='Question ID')
  			parser.add_argument('limit', type=int, required=False, help='Size of the returned results')
  			args = parser.parse_args()
  			q = request.args.get('question')
  			question = BeautifulSoup(q, "lxml").p.contents
  			try:
  				size = request.args.get('limit')
  				n_results = int(size)
  				if n_results > 100:
  					n_results = 100
  			except:
  				n_results = 3
  			user_id = request.args.get('userId')
  			question_id = request.args.get('questionId')
  			response = {}
  			response['userId'] = user_id
  			response['questionId'] = question_id
  			response['limit'] = n_results
  			response['interesteId'] = 'future_feature'
  			response['results'] =  query_by_text(transformer, transformed, documents, index, question, url, n_results=n_results)
  			if str(type(question)) == "<type 'list'>":
  				question = question[0]
  			response['question'] = question
  			resp = make_response()
  			resp.headers['Access-Control-Allow-Origin'] = '*'
  			resp.headers['content-type'] = 'application/json'
  			resp.data = response
  			return response
  
  		except Exception as e:
  			return {'error': str(e)}
  
  	def get(self):
  		try:
  			q = request.args.get('question')
  			question = BeautifulSoup(q, "lxml").p.contents
  			try:
  				user_id = request.args.get('userId')
  			except:
  				user_id = 'uid1'
  			try:
  				question_id = request.args.get('questionId')
  			except:
  				question_id = 'qid1'
  			try:
  				size = request.args.get('limit')
  				n_results = int(size)
  				if n_results > 100:
  					n_results = 100
  			except:
  				n_results = 3
  			response = dict()
  			response['userId'] = user_id
  			response['questionId'] = question_id
  			response['limit'] = n_results
  			response['interesteId'] = 'future_feature'
  			results =  query_by_text(transformer, transformed, documents, index, question, url, n_results=n_results)
  			response['results'] = results
  			if str(type(question)) == "<type 'list'>":
  				question = question[0]
  			response['question'] = question
  			return response
  
  		except Exception as e:
  			return {'error': str(e)}
  
  app = Flask(__name__, static_url_path="")
  auth = HTTPBasicAuth()
  
  api = Api(app)
  api.add_resource(Query, '/Query/')
  
  if __name__ == '__main__':
  
  	transformed_file = 'transformed.pickle'
  	docs_file = 'documents.pickle'
  	index_file = 'index.pickle'
  	transformer_file = 'transformer.pickle'
  
  	transformed = np.load(transformed_file)
  
  	index = pickle.load(open(index_file,'rb'))
  
  	documents = pickle.load(open(docs_file,'rb'))
  	print 'number of documents :', len(index)
  
  	transformer = pickle.load(open(transformer_file,'rb'))
  
  	url_config = json.load(open('url_config.json', 'r'))
  	url = url_config['url']
  
  	print 'Ready to call!!'
  	app.run(host='0.0.0.0', threaded=True)
  