mirror of https://github.com/kubeflow/examples.git
				
				
				
			Polish the github issue summarization UI (#69)
* Polish the github issue summarization UI * Add kubeflow footer
This commit is contained in:
		
							parent
							
								
									e3b826a5af
								
							
						
					
					
						commit
						9f6ccde03f
					
				| 
						 | 
				
			
			@ -1,15 +1,13 @@
 | 
			
		|||
FROM python:alpine
 | 
			
		||||
FROM python:3.6
 | 
			
		||||
 | 
			
		||||
COPY ./flask_web/requirements.txt /app/
 | 
			
		||||
 | 
			
		||||
WORKDIR /app
 | 
			
		||||
 | 
			
		||||
RUN pip install -r requirements.txt
 | 
			
		||||
RUN pip install requests
 | 
			
		||||
 | 
			
		||||
COPY ./flask_web /app
 | 
			
		||||
 | 
			
		||||
ENTRYPOINT [ "python" ]
 | 
			
		||||
 | 
			
		||||
CMD [ "app.py" ]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,9 +2,28 @@
 | 
			
		|||
Simple app that parses predictions from a trained model and displays them.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import re
 | 
			
		||||
import random
 | 
			
		||||
 | 
			
		||||
import requests
 | 
			
		||||
from flask import Flask, json, render_template, request
 | 
			
		||||
import pandas as pd
 | 
			
		||||
from flask import Flask, json, render_template, request, g, jsonify
 | 
			
		||||
 | 
			
		||||
APP = Flask(__name__)
 | 
			
		||||
GITHUB_TOKEN = os.environ['GITHUB_TOKEN']
 | 
			
		||||
SAMPLE_DATA_URL = ('https://storage.googleapis.com/kubeflow-examples/'
 | 
			
		||||
                   'github-issue-summarization-data/github_issues_sample.csv')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_issue_body(issue_url):
 | 
			
		||||
  issue_url = re.sub('.*github.com/', 'https://api.github.com/repos/',
 | 
			
		||||
                     issue_url)
 | 
			
		||||
  return requests.get(
 | 
			
		||||
    issue_url, headers={
 | 
			
		||||
      'Authorization': 'token {}'.format(GITHUB_TOKEN)
 | 
			
		||||
    }).json()['body']
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@APP.route("/")
 | 
			
		||||
def index():
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +33,8 @@ def index():
 | 
			
		|||
  """
 | 
			
		||||
  return render_template("index.html")
 | 
			
		||||
 | 
			
		||||
@APP.route("/summary", methods=['GET', 'POST'])
 | 
			
		||||
 | 
			
		||||
@APP.route("/summary", methods=['POST'])
 | 
			
		||||
def summary():
 | 
			
		||||
  """Main prediction route.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -23,26 +43,33 @@ def summary():
 | 
			
		|||
  """
 | 
			
		||||
  if request.method == 'POST':
 | 
			
		||||
    issue_text = request.form["issue_text"]
 | 
			
		||||
 | 
			
		||||
    url = "http://ambassador:80/seldon/issue-summarization/api/v0.1/predictions"
 | 
			
		||||
    issue_url = request.form["issue_url"]
 | 
			
		||||
    if issue_url:
 | 
			
		||||
      issue_text = get_issue_body(issue_url)
 | 
			
		||||
    url = "http://ambassador/seldon/issue-summarization/api/v0.1/predictions"
 | 
			
		||||
    headers = {'content-type': 'application/json'}
 | 
			
		||||
    json_data = {
 | 
			
		||||
      "data" : {
 | 
			
		||||
        "ndarray" : [[issue_text]]
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    response = requests.post(url=url,
 | 
			
		||||
                             headers=headers,
 | 
			
		||||
                             data=json.dumps(json_data))
 | 
			
		||||
 | 
			
		||||
    json_data = {"data": {"ndarray": [[issue_text]]}}
 | 
			
		||||
    response = requests.post(
 | 
			
		||||
      url=url, headers=headers, data=json.dumps(json_data))
 | 
			
		||||
    response_json = json.loads(response.text)
 | 
			
		||||
    issue_summary = response_json["data"]["ndarray"][0][0]
 | 
			
		||||
    return jsonify({'summary': issue_summary, 'body': issue_text})
 | 
			
		||||
 | 
			
		||||
    return render_template("issue_summary.html",
 | 
			
		||||
                           issue_text=issue_text,
 | 
			
		||||
                           issue_summary=issue_summary)
 | 
			
		||||
  return ('', 204)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@APP.route("/random_github_issue", methods=['GET'])
 | 
			
		||||
def random_github_issue():
 | 
			
		||||
  github_issues = getattr(g, '_github_issues', None)
 | 
			
		||||
  if github_issues is None:
 | 
			
		||||
    github_issues = g._github_issues = pd.read_csv(
 | 
			
		||||
      SAMPLE_DATA_URL).body.tolist()
 | 
			
		||||
  return jsonify({
 | 
			
		||||
    'body':
 | 
			
		||||
    github_issues[random.randint(0,
 | 
			
		||||
                                 len(github_issues) - 1)]
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
  APP.run(debug=True, host='0.0.0.0', port=80)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,2 +1,3 @@
 | 
			
		|||
Flask==0.12.2
 | 
			
		||||
 | 
			
		||||
pandas
 | 
			
		||||
requests
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,55 @@
 | 
			
		|||
<h1>Issue text</h1>
 | 
			
		||||
<!doctype html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
  <head>
 | 
			
		||||
    <!-- Required meta tags -->
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
 | 
			
		||||
 | 
			
		||||
<form action="summary" method="post">
 | 
			
		||||
  <p>Enter GitHub issue text:</p>
 | 
			
		||||
  <p><textarea class="scrollabletextbox" name="issue_text" rows=5 cols=100></textarea></p>
 | 
			
		||||
  <p><input type="submit" value="Submit"/></p>
 | 
			
		||||
</form>
 | 
			
		||||
    <!-- Bootstrap CSS -->
 | 
			
		||||
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
 | 
			
		||||
 | 
			
		||||
    <title>Github Issue Summarization</title>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body class="text-center">
 | 
			
		||||
    <form class="form-signin" action="summary" method="post">
 | 
			
		||||
      <img class="mb-4" src="https://assets-cdn.github.com/images/modules/logos_page/GitHub-Mark.png" alt="" width="72" height="72">
 | 
			
		||||
      <h1 style="margin-top: -20px;">Github Issue Summarization</h1>
 | 
			
		||||
      <p style="margin-left: 20%; margin-right: 20%;">Instructions: This is a demo of the github issue summarization <a href="https://github.com/hamelsmu/Seq2Seq_Tutorial" target="_blank">model</a> by <a href="https://github.com/hamelsmu" target="_blank">Hamel Husain.</a> Enter the body of a github issue or the url of a github issue and click on Submit. The model then tries to generate a title or summary of the issue.</p>
 | 
			
		||||
      <h3 class="h3 mb-3 font-weight-normal">Enter Github Issue Body</h3>
 | 
			
		||||
      <p><button id="generate_random_issue_button" type="button">Populate Random Issue</button></p>
 | 
			
		||||
      <p><textarea id="issue_body_textarea" class="scrollabletextbox" name="issue_text" rows=8 cols=100></textarea></p>
 | 
			
		||||
      <h3 class="h3 mb-3 font-weight-normal">OR Enter Github Issue URL</h3>
 | 
			
		||||
      <p><input id="issue_url_textarea" name="issue_url" type="text" size="100" placeholder="https://github.com/kubeflow/kubeflow/issues/157"></input></p>
 | 
			
		||||
      <p><button id="submit" type="button">Generate Title</button></p>
 | 
			
		||||
    </form>
 | 
			
		||||
    <div id="generated_title_div" style="display: none;">
 | 
			
		||||
      <h2>Machine Generated Title</h2>
 | 
			
		||||
      <p style="margin-right: 20%; margin-left: 20%;" id="generated_title"></p>
 | 
			
		||||
    </div>
 | 
			
		||||
    <p style="font-style: italic; margin-right: 20%; margin-left: 20%; margin-top: 40px;" id="generated_title">This demo is run using <a target="_blank" href="https://github.com/kubeflow/kubeflow/">Kubeflow</a> - a machine learning toolkit for Kubernetes. Kubeflow is dedicated to making deployment of machine learning on Kubernetes simple, portable and scalable.</p>
 | 
			
		||||
 | 
			
		||||
    <!-- Optional JavaScript -->
 | 
			
		||||
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
 | 
			
		||||
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
 | 
			
		||||
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
 | 
			
		||||
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
 | 
			
		||||
    <script type="text/javascript">
 | 
			
		||||
      $("#generate_random_issue_button").click(function(){
 | 
			
		||||
          $.ajax({url: window.location.pathname + "random_github_issue", success: function(result){
 | 
			
		||||
              $("#issue_body_textarea").html(result.body);
 | 
			
		||||
          }});
 | 
			
		||||
      });
 | 
			
		||||
      $("#submit").click(function(){
 | 
			
		||||
          $("#generated_title").html("");
 | 
			
		||||
          var issue_body_textarea = $("#issue_body_textarea").val();
 | 
			
		||||
          var issue_url_textarea = $("#issue_url_textarea").val();
 | 
			
		||||
          $.post(window.location.pathname + "summary", {issue_text: issue_body_textarea, issue_url: issue_url_textarea}, function(result){
 | 
			
		||||
              $("#generated_title").html("“" + result.summary + "”");
 | 
			
		||||
              $("#issue_body_textarea").html(result.body);
 | 
			
		||||
              $("#generated_title_div").show();
 | 
			
		||||
 | 
			
		||||
          });
 | 
			
		||||
      });
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +0,0 @@
 | 
			
		|||
<h1>Issue Summary</h1>
 | 
			
		||||
<p>{{issue_summary}}</p>
 | 
			
		||||
 | 
			
		||||
<h2>Issue text</h1>
 | 
			
		||||
<p>{{issue_text}}</p>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue