File size: 2,605 Bytes
5b065c1
482cd40
 
8f3ac58
482cd40
 
 
5b065c1
 
482cd40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5b065c1
 
482cd40
5b065c1
 
482cd40
5b065c1
482cd40
5b065c1
 
482cd40
 
 
 
 
5b065c1
 
482cd40
5b065c1
482cd40
 
5b065c1
482cd40
 
 
 
 
 
 
 
5b065c1
482cd40
 
 
 
 
 
 
5b065c1
 
 
 
 
482cd40
5b065c1
 
482cd40
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import os
import tempfile

import chdb
from chdb import session as chs
from flask import Flask, request
from flask_httpauth import HTTPBasicAuth

app = Flask(__name__, static_folder="public", static_url_path="")
auth = HTTPBasicAuth()
driver = chdb

# session support: basic username + password as unique datapath
@auth.verify_password
def verify(username, password):
    if not (username and password):
        print('stateless session')
        globals()["driver"] = chdb
    else:
        path = globals()["path"] + "/" + str(hash(username + password))
        print('stateful session ' + path)
        globals()["driver"] = chs.Session(path)
    return True

# run chdb.query(query, format), get result from return and collect stderr
def chdb_query_with_errmsg(query, format):
    # Redirect stdout and stderr to the buffers
    try:
        new_stderr = tempfile.TemporaryFile()
        old_stderr_fd = os.dup(2)
        os.dup2(new_stderr.fileno(), 2)
        # Call the function
        output = driver.query(query, format).bytes()
        
        new_stderr.flush()
        new_stderr.seek(0)
        errmsg = new_stderr.read()
        
        # cleanup and recover
        new_stderr.close()
        os.dup2(old_stderr_fd, 2)
    except Exception as e:
        # An error occurred, print it to stderr
        print(f"An error occurred: {e}")
    return output, errmsg
    

@app.route('/', methods=["GET"])
@auth.login_required
def clickhouse():
    query = request.args.get('query', default="", type=str)
    format = request.args.get('default_format', default="TSV", type=str)
    if not query:
#       return "Ok", 200
        return app.send_static_file('play.html')

    result, errmsg = chdb_query_with_errmsg(query, format)
    if len(errmsg) == 0:
        return result
    return errmsg


@app.route('/', methods=["POST"])
@auth.login_required
def play():
    query = request.data or None
    format = request.args.get('default_format', default="TSV", type=str)
    if not query:
        return "Ok", 200
#       return app.send_static_file('play.html')

    result, errmsg = chdb_query_with_errmsg(query, format)
    if len(errmsg) == 0:
        return result
    return errmsg


@app.route('/play', methods=["GET"])
def handle_play():
    return app.send_static_file('play.html')

@app.route('/ping', methods=["GET"])
def handle_ping():
    return "Ok", 200

@app.errorhandler(404)
def handle_404(e):
    return app.send_static_file('play.html')


host = os.getenv('HOST', '0.0.0.0')
port = os.getenv('PORT', 7860)
path = os.getenv('DATA', '.chdb_data')
app.run(host=host, port=port)