Skip to content

Commit eda372b

Browse files
authored
Merge pull request #53 from michaelthwan/ajax
ajax call and avoid full page refresh / config change
2 parents dc3cef2 + 6c9388d commit eda372b

File tree

7 files changed

+119
-48
lines changed

7 files changed

+119
-48
lines changed

src/config/config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ goose_ai_api:
3131
cache: # .cache result for efficiency and consistency
3232
is_enable_cache: false
3333
path: .cache
34-
max_number_of_cache: 10
34+
max_number_of_cache: 0
3535
semantic_search:
3636
# provider list:
3737
# faiss-openai (default): Use OpenAIEmbedding. fast, good accuracy but need openai key (cost)

src/website/static/index.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
$(document).ready(function () {
2+
$('form').submit(function(event) {
3+
event.preventDefault();
4+
let search_text = $('#form1').val();
5+
$('#search-btn')[0].disabled = true;
6+
$('#search-result-spinner').addClass('d-flex');
7+
$('#search-results').hide();
8+
$.ajax({
9+
url: '/search',
10+
type: 'POST',
11+
data: {
12+
q: search_text,
13+
bing_search_subscription_key: $('#bing_search_subscription_key').val(),
14+
openai_api_key: $('#openai_api_key').val(),
15+
is_use_source: $('input[name="is_use_source"]')[0].checked,
16+
llm_service_provider: $('#llm_service_provider').val(),
17+
llm_model: $('#llm_model').val(),
18+
semantic_search_provider: $('#semantic_search_provider').val()
19+
},
20+
success: function (response) {
21+
$('#' + response.id).html(response.html)
22+
$('#search-btn')[0].disabled = false;
23+
$('#search-result-spinner').removeClass('d-flex');
24+
$('#search-results').show();
25+
},
26+
error: function (error) {
27+
console.log(error)
28+
$('#search-btn')[0].disabled = false;
29+
$('#search-result-spinner').removeClass('d-flex');
30+
$('#search-results').show();
31+
}
32+
})
33+
})
34+
})

src/website/templates/alert_box.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{% if error %}
2+
<div class="alert alert-danger alert-dismissible fade show" role="alert">
3+
<strong>Encountered error</strong> {{ error }}
4+
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
5+
</div>
6+
{% endif %}

src/website/templates/base.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,17 @@
3030
<div class="container text-center">
3131
<div class="row">
3232
<div class="col-lg-12">
33-
<p class="text-muted small mb-0">SearchGPT 20230305 Version (
33+
<p class="text-muted small mb-0">SearchGPT 20230306 Version (
3434
<a href="https://github.com/michaelthwan/searchGPT">Github</a>
3535
). Your feedback will help us to improve</p>
3636
</div>
3737
</div>
3838
</div>
3939
</footer>
4040

41-
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
41+
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f" crossorigin="anonymous"></script>
4242
<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>
4343
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
44+
<script type="text/javascript" src="{{url_for('static', filename='index.js')}}"></script>
4445
</body>
4546
</html>

src/website/templates/index.html

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11
{% extends "base.html" %} {% block title %}SearchGPT{% endblock %}
22
{% block content %}
33
<div class="container mt-4">
4-
{% if error %}
5-
<div class="alert alert-danger alert-dismissible fade show" role="alert">
6-
<strong>Encountered error</strong> {{ error }}
7-
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
4+
<div id="alert-box">
5+
{% include 'alert_box.html' %}
86
</div>
9-
{% endif %}
107
<div>
11-
<form action="/index" method="get">
8+
<form action="/search" method="post">
129
<div class="input-group">
1310
<input type="search" id="form1" class="form-control"
1411
placeholder="Ask: e.g. What is ChatGPT"
1512
name="q" value="{{ request.args.get('q', '') }}"
16-
minlength="10" maxlength="200" required/>
17-
<button type="submit" class="btn btn-primary"><i class="fa fa-search"></i></button>
13+
minlength="5" maxlength="200" required/>
14+
<button type="submit" class="btn btn-primary" id="search-btn"><i class="fa fa-search"></i></button>
1815
</div>
1916
<div class="row mt-4">
2017
<div class="col-md-6">
2118
<div class="form-group">
2219
<label for="bing_search_subscription_key">Bing Search Subscription Key</label>
23-
<input type="text" class="form-control" id="bing_search_subscription_key" placeholder="Enter key"
24-
name="bing_search_subscription_key" value="{{ request.args.get('bing_search_subscription_key', '') }}">
20+
<input type="text" class="form-control" id="bing_search_subscription_key"
21+
placeholder="Enter key"
22+
name="bing_search_subscription_key"
23+
value="{{ request.args.get('bing_search_subscription_key', '') }}">
2524
</div>
2625
<div class="form-group">
2726
<label for="openai_api_key">OpenAI API Key</label>
@@ -67,7 +66,8 @@
6766
<div class="form-group">
6867
<label for="semantic_search_provider">Semantic Search Provider</label>
6968
<select class="form-control" id="semantic_search_provider" name="semantic_search_provider">
70-
<option value="faiss-openai">FAISS-OpenAI Embedding (fast, best accuracy, need OpenAI key)</option>
69+
<option value="faiss-openai">FAISS-OpenAI Embedding (fast, best accuracy, need OpenAI key)
70+
</option>
7171
<option value="faiss-huggingface"
7272
{% if request.args.get(
7373
'semantic_search_provider') == 'faiss-huggingface' %} selected {% endif %}
@@ -80,34 +80,14 @@
8080
</div>
8181
<hr>
8282
<div class="container mt-4">
83-
<div class="row">
84-
<div class="col-md-6">
85-
<h2>{{search_text}}</h2>
86-
<p>
87-
{% for item in response_json %}
88-
{% if item['type'] == 'footnote' %}
89-
<span style="font-weight: bold; font-size: 0.8rem; background-color: #88effc;">{{ item['text'] }}</span>
90-
{% else %}
91-
{{ item['text'] }}
92-
{% endif %}
93-
{% endfor %}
94-
</p>
95-
</div>
96-
<div class="col-md-6">
97-
<ul class="list-group">
98-
{% for item in source_json %}
99-
<li class="list-group-item">
100-
<h5 class="mb-1">
101-
<img src="https://www.google.com/s2/favicons?domain={{item['domain']}}" alt="Favicon">
102-
<a href="{{item['url']}}">{{item['footnote']}} {{item['domain']}}</a>
103-
</h5>
104-
<h4 class="mb-1" style="font-family: 'Playfair Display', Georgia">{{item['title']}}</h4>
105-
<p class="mb-1">{{item['text']}}</p>
106-
</li>
107-
{% endfor %}
108-
</ul>
83+
<div class="justify-content-center" id="search-result-spinner" hidden>
84+
<div class="spinner-border" role="status">
85+
<span class="sr-only">Loading...</span>
10986
</div>
11087
</div>
88+
<div id="search-results">
89+
{% include 'search_result.html' %}
90+
</div>
11191
</div>
11292
<hr>
11393
</div>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<div class="row">
2+
<div class="col-md-6">
3+
<h2>{{search_text}}</h2>
4+
<p>
5+
{% for item in response_json %}
6+
{% if item['type'] == 'footnote' %}
7+
<span style="font-weight: bold; font-size: 0.8rem; background-color: #88effc;">{{ item['text'] }}</span>
8+
{% else %}
9+
{{ item['text'] }}
10+
{% endif %}
11+
{% endfor %}
12+
</p>
13+
</div>
14+
<div class="col-md-6">
15+
<ul class="list-group">
16+
{% for item in source_json %}
17+
<li class="list-group-item">
18+
<h5 class="mb-1">
19+
<img src="https://www.google.com/s2/favicons?domain={{item['domain']}}" alt="Favicon">
20+
<a href="{{item['url']}}">{{item['footnote']}} {{item['domain']}}</a>
21+
</h5>
22+
<h4 class="mb-1" style="font-family: 'Playfair Display', Georgia">{{item['title']}}</h4>
23+
<p class="mb-1">{{item['text']}}</p>
24+
</li>
25+
{% endfor %}
26+
</ul>
27+
</div>
28+
</div>

src/website/views.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from flask import Blueprint, render_template, request
2+
23
from SearchGPTService import SearchGPTService
34
from Util import setup_logger
45

@@ -8,10 +9,22 @@
89

910
@views.route('/', methods=['GET'])
1011
@views.route('/index', methods=['GET'])
12+
def start_page():
13+
data_json = {'response_json': [], 'source_json': []}
14+
return render_template("index.html",
15+
search_text='' or "Please search for something.",
16+
response_json=data_json.get('response_json'),
17+
source_json=data_json.get('source_json'),
18+
error=None
19+
)
20+
21+
22+
@views.route('/search', methods=['POST'])
1123
def index_page():
1224
error = None
25+
data_json = {'response_json': [], 'source_json': []}
26+
search_text = request.values.get('q')
1327
try:
14-
search_text = request.values.get('q')
1528
ui_overriden_config = {
1629
'bing_search_subscription_key': request.values.get('bing_search_subscription_key'),
1730
'openai_api_key': request.values.get('openai_api_key'),
@@ -22,19 +35,28 @@ def index_page():
2235
}
2336
logger.info(f"GET ui_overriden_config: {ui_overriden_config}")
2437

25-
data_json = {'response_json': [], 'source_json': []}
2638
if search_text is not None:
2739
search_gpt_service = SearchGPTService(ui_overriden_config)
2840
response_text, response_text_with_footnote, source_text, data_json = search_gpt_service.query_and_get_answer(search_text)
2941
# response_text, response_text_with_footnote, source_text, data_json = "test", "test", "test", {'response_json': [], 'source_json': []}
3042
except Exception as e:
3143
error = str(e)
32-
return render_template("index.html",
33-
search_text=search_text or "Please search for something.",
34-
response_json=data_json.get('response_json'),
35-
source_json=data_json.get('source_json'),
36-
error=error
37-
)
44+
45+
if error is None:
46+
result_html = render_template('search_result.html',
47+
search_text=search_text,
48+
response_json=data_json.get('response_json'),
49+
source_json=data_json.get('source_json'))
50+
return {
51+
'id': 'search-results',
52+
'html': result_html
53+
}
54+
else:
55+
result_html = render_template('alert_box.html', error=error)
56+
return {
57+
'id': 'alert-box',
58+
'html': result_html
59+
}
3860

3961

4062
@views.route('/index_static', methods=['GET', 'POST'])

0 commit comments

Comments
 (0)