#!/usr/bin/env python3

import sys
import os
parent_dir = os.path.dirname(os.getcwd())
sys.path.insert(0, parent_dir)


import config

import sqlite3
from flask import Flask, request, jsonify


app = Flask(__name__)

os.chdir(parent_dir)
print(os.getcwd())
conn = sqlite3.connect(config.DB_URI_READ_ONLY, uri=True)


@app.route('/', methods=['GET'])
def hello_world():
    return 'Hello World!'


@app.route('/', methods=['POST'])
def sql_query():
    if 'query' not in request.form:
        err = {'error': 'No query provided. Post SQL queries as '
                        'form URL-encoded param "query".'}
        return jsonify(err), 400
    query = request.form['query']

    try:
        results = conn.execute(query)
    except sqlite3.OperationalError as e:
        err = {'error': repr(e)}
        return jsonify(err), 400

    column_names = [n[0] for n in results.description]
    named_results = []
    for row in results:
        named_row = {}
        for num, cell in enumerate(row):
            named_row[column_names[num]] = cell
        named_results.append(named_row)

    output = {'rows': named_results}
    return jsonify(output)


if __name__ == '__main__':
    app.run()

@@ -143,16 +143,113 @@
 sqlite3%0A
+from time import time%0Afrom traceback import print_exc%0Afrom multiprocessing import Process, Queue%0A
 from fla
@@ -351,64 +351,612 @@
 ())%0A
-conn = sqlite3.connect(config.DB_URI_READ_ONLY, uri=True
+%0A%0Adef query_processor(conn, query, result_queue):%0A    try:%0A        start_time = time()%0A        results = conn.execute(query)%0A        query_time = time() - start_time%0A    except sqlite3.OperationalError as e:%0A        result_queue.put(e)%0A        return%0A%0A    column_names = %5Bn%5B0%5D for n in results.description%5D%0A    named_results = %5B%5D%0A    for row in results:%0A        named_row = %7B%7D%0A        for num, cell in enumerate(row):%0A            named_row%5Bcolumn_names%5Bnum%5D%5D = cell%0A        named_results.append(named_row)%0A%0A    output = %7B'results': named_results, 'query_time_sec': query_time%7D%0A    result_queue.put(output
 )%0A%0A%0A
@@ -1082,24 +1082,37 @@
 ql_query():%0A
+    try:%0A    
     if 'quer
@@ -1135,32 +1135,36 @@
 t.form:%0A        
+   
+ 
 err = %7B'error': 
@@ -1229,16 +1229,20 @@
         
+    
 'form UR
@@ -1268,32 +1268,36 @@
 ery%22.'%7D%0A        
+    
 return jsonify(e
@@ -1305,24 +1305,28 @@
 r), 400%0A    
+   
+ 
 query = requ
@@ -1352,92 +1352,383 @@
     
-try:%0A        results = conn.execute(query)%0A    except sqlite3.OperationalError as e:
+    conn = sqlite3.connect(config.DB_URI_READ_ONLY, uri=True)%0A        result_queue = Queue()%0A%0A        query_process = Process(target=query_processor,%0A                                args=(conn, query, result_queue))%0A        query_process.start()%0A        query_process.join(config.QUERY_TIMEOUT_SECS)%0A%0A        if query_process.is_alive():%0A            query_process.terminate()
 %0A   
@@ -1724,32 +1724,36 @@
 inate()%0A        
+    
 err = %7B'error': 
@@ -1756,370 +1756,507 @@
 r': 
-repr(e)%7D%0A        return jsonify(err), 400%0A%0A    column_names = %5Bn%5B0%5D for n in results.description%5D%0A    named_results = %5B%5D%0A    for row in results:%0A        named_row = %7B%7D%0A        for num, cell in enumerate(row):%0A            named_row%5Bcolumn_names%5Bnum%5D%5D = cell%0A        named_results.append(named_row)%0A%0A    output = %7B'rows': named_results%7D%0A    return jsonify(output)%0A
+'Query took too long; max time %25s seconds' %25%0A                            config.QUERY_TIMEOUT_SECS%7D%0A            return jsonify(err), 400%0A%0A        output = result_queue.get()%0A%0A        if type(output) is sqlite3.OperationalError:%0A            err = %7B'error': repr(output)%7D%0A            return jsonify(err), 400%0A%0A        return jsonify(output)%0A%0A    except Exception:%0A        # It's a little hacky but it lets us get proper tracebacks from the%0A        # server, even without debug mode%0A        print_exc()
 %0A%0Aif

Add timeouts to queries; add console tracebacks outside debug mode