This repository was archived by the owner on Dec 29, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmain.py
107 lines (87 loc) · 3.06 KB
/
main.py
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
95
96
97
98
99
100
101
102
103
104
105
106
107
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)
database = request.args.get('database', default="", type=str)
if not query:
return app.send_static_file('play.html')
if database:
query = f"USE {database}; {query}".encode()
result, errmsg = chdb_query_with_errmsg(query, format)
if len(errmsg) == 0:
return result, 200
return errmsg, 400
@app.route('/', methods=["POST"])
@auth.login_required
def play():
query = request.get_data() or None
query_param = request.args.get('query', default="", type=str)
format = request.args.get('default_format', default="TSV", type=str)
database = request.args.get('database', default="", type=str)
if not query and query_param:
query = f"{query_param}".encode()
elif query and query_param:
query_param = f"{query_param} ".encode()
query = query_param + query
if not query:
return "Error: no query parameter provided", 400
if database:
database = f"USE {database}; ".encode()
query = database + query
result, errmsg = chdb_query_with_errmsg(query, format)
if len(errmsg) == 0:
return result, 200
return errmsg, 400
@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', 8123)
path = os.getenv('DATA', '.chdb_data')
app.run(host=host, port=port)